Nombre latino básico del carácter a carácter

23

¡Volvamos a lo básico!

  • Su código, un programa o función completa, debe convertir el nombre oficial Unicode de un carácter latino básico imprimible en el carácter correspondiente. Por ejemplo, para la entrada LOW LINEsu código debe salir _.
  • Solo necesita tomar un solo nombre de carácter como entrada.
  • No puede utilizar ninguna función o biblioteca preexistente, integrada o de otro tipo, que ofrezca ninguna lógica relacionada específicamente con los nombres de caracteres Unicode (por ejemplo, Python unicodedata, Java Character.getName, etc.)
  • Para entradas que no sean uno de estos nombres, cualquier comportamiento es aceptable.

Este es el código de golf: el código más corto en bytes gana.

Para evitar cualquier ambigüedad, este es el conjunto completo de nombres de personajes oficiales que usaremos (tomado de esta pregunta ):

     SPACE
!    EXCLAMATION MARK
"    QUOTATION MARK
#    NUMBER SIGN
$    DOLLAR SIGN
%    PERCENT SIGN
&    AMPERSAND
'    APOSTROPHE
(    LEFT PARENTHESIS
)    RIGHT PARENTHESIS
*    ASTERISK
+    PLUS SIGN
,    COMMA
-    HYPHEN-MINUS
.    FULL STOP
/    SOLIDUS
0    DIGIT ZERO
1    DIGIT ONE
2    DIGIT TWO
3    DIGIT THREE
4    DIGIT FOUR
5    DIGIT FIVE
6    DIGIT SIX
7    DIGIT SEVEN
8    DIGIT EIGHT
9    DIGIT NINE
:    COLON
;    SEMICOLON
<    LESS-THAN SIGN
=    EQUALS SIGN
>    GREATER-THAN SIGN
?    QUESTION MARK
@    COMMERCIAL AT
A    LATIN CAPITAL LETTER A
B    LATIN CAPITAL LETTER B
C    LATIN CAPITAL LETTER C
D    LATIN CAPITAL LETTER D
E    LATIN CAPITAL LETTER E
F    LATIN CAPITAL LETTER F
G    LATIN CAPITAL LETTER G
H    LATIN CAPITAL LETTER H
I    LATIN CAPITAL LETTER I
J    LATIN CAPITAL LETTER J
K    LATIN CAPITAL LETTER K
L    LATIN CAPITAL LETTER L
M    LATIN CAPITAL LETTER M
N    LATIN CAPITAL LETTER N
O    LATIN CAPITAL LETTER O
P    LATIN CAPITAL LETTER P
Q    LATIN CAPITAL LETTER Q
R    LATIN CAPITAL LETTER R
S    LATIN CAPITAL LETTER S
T    LATIN CAPITAL LETTER T
U    LATIN CAPITAL LETTER U
V    LATIN CAPITAL LETTER V
W    LATIN CAPITAL LETTER W
X    LATIN CAPITAL LETTER X
Y    LATIN CAPITAL LETTER Y
Z    LATIN CAPITAL LETTER Z
[    LEFT SQUARE BRACKET
\    REVERSE SOLIDUS
]    RIGHT SQUARE BRACKET
^    CIRCUMFLEX ACCENT
_    LOW LINE
`    GRAVE ACCENT
a    LATIN SMALL LETTER A
b    LATIN SMALL LETTER B
c    LATIN SMALL LETTER C
d    LATIN SMALL LETTER D
e    LATIN SMALL LETTER E
f    LATIN SMALL LETTER F
g    LATIN SMALL LETTER G
h    LATIN SMALL LETTER H
i    LATIN SMALL LETTER I
j    LATIN SMALL LETTER J
k    LATIN SMALL LETTER K
l    LATIN SMALL LETTER L
m    LATIN SMALL LETTER M
n    LATIN SMALL LETTER N
o    LATIN SMALL LETTER O
p    LATIN SMALL LETTER P
q    LATIN SMALL LETTER Q
r    LATIN SMALL LETTER R
s    LATIN SMALL LETTER S
t    LATIN SMALL LETTER T
u    LATIN SMALL LETTER U
v    LATIN SMALL LETTER V
w    LATIN SMALL LETTER W
x    LATIN SMALL LETTER X
y    LATIN SMALL LETTER Y
z    LATIN SMALL LETTER Z
{    LEFT CURLY BRACKET
|    VERTICAL LINE
}    RIGHT CURLY BRACKET
~    TILDE
Luke
fuente
2
¿El programa solo necesita manejar un nombre de personaje? Por ejemplo, ¿debería un comportamiento de COLON COLONsalida ::o indefinido?
Kevin W.
Editado para aclarar.
Lucas
¿Por qué está String.fromCharCodeprohibido?
SuperJedi224
Vaya, no entendí lo que hace esa función.
Lucas
¿Cómo debemos manejar la entrada no válida, como CLON?
edc65

Respuestas:

25

Código de máquina IA-32, 161 160 122 bytes

Hexdump del código:

33 c0 6b c0 59 0f b6 11 03 c2 b2 71 f6 f2 c1 e8
08 41 80 79 01 00 75 ea e8 39 00 00 00 08 2c 5e
4a bd a3 cd c5 90 09 46 04 06 14 40 3e 3d 5b 23
60 5e 3f 2d 31 32 29 25 2e 3c 7e 36 39 34 33 30
21 2f 26 7d 7c 2c 3b 7b 2a 37 5d 22 35 20 3a 28
5c 27 2b 38 5f 24 5a 3c 34 74 17 3c 1a 74 16 33
c9 86 c4 0f a3 0a 14 00 41 fe cc 75 f6 8a 44 02
0e c3 8a 01 c3 8a 01 04 20 c3

Este código usa algo de hashing. Mediante una búsqueda de fuerza bruta, descubrí que la siguiente función hash se puede aplicar a los bytes de la cadena de entrada:

int x = 0;
while (s[1])
{
    x = (x * 89 + *s) % 113;
    ++s;
}

Se multiplica xpor 89, agrega el siguiente byte (código ASCII) y toma el resto del módulo 113. Lo hace en todos los bytes de la cadena de entrada, excepto en el último, por ejemplo, LATIN CAPITAL LETTER Ay LATIN CAPITAL LETTER Xproporciona el mismo código hash.

Esta función hash no tiene colisiones, y la salida está en el rango 0 ... 113 (en realidad, por suerte, el rango es aún más estrecho: 3 ... 108).

Los valores hash de todas las cadenas relevantes no llenan ese espacio por completo, así que decidí usar esto para comprimir la tabla hash. Agregué una tabla de "omisión" (112 bits), que contiene 0 si el lugar correspondiente en la tabla hash está vacío, y 1 en caso contrario. Esta tabla convierte un valor hash en un índice "comprimido", que se puede usar para abordar una LUT densa.

Las cadenas LATIN CAPITAL LETTERy LATIN SMALL LETTERdan los códigos hash 52 y 26; Se manejan por separado. Aquí hay un código C para eso:

char find(const char* s)
{
    int hash = 0;
    while (s[1])
    {
        hash = (hash * 89 + *s) % 113;
        ++s;
    }

    if (hash == 52)
        return *s;
    if (hash == 26)
        return *s + 32;

    int result_idx = 0;
    int bit = 0;
    uint32_t skip[] = {0x4a5e2c08, 0xc5cda3bd, 0x04460990, 0x1406};
    do {
        if (skip[bit / 32] & (1 << bit % 32))
            ++result_idx;
        ++bit;
    } while (--hash);

    return "@>=[#`^?-12)%.<~69430!/&}|,;{*7]\"5 :(\\'+8_$"[result_idx];
}

El código del lenguaje ensamblador correspondiente (sintaxis de ensamblaje en línea de MS Visual Studio):

_declspec(naked) char _fastcall find(char* s)
{
    _asm {
        xor eax, eax;
    mycalc:
        imul eax, eax, 89;
        movzx edx, [ecx];
        add eax, edx;
        mov dl, 113;
        div dl;
        shr eax, 8;
        inc ecx;
        cmp byte ptr [ecx + 1], 0;
        jne mycalc;

        call mycont;
        // skip table
        _asm _emit 0x08 _asm _emit 0x2c _asm _emit 0x5e _asm _emit 0x4a;
        _asm _emit 0xbd _asm _emit 0xa3 _asm _emit 0xcd _asm _emit 0xc5;
        _asm _emit 0x90 _asm _emit 0x09 _asm _emit 0x46 _asm _emit 0x04;
        _asm _emit 0x06 _asm _emit 0x14;
        // char table
        _asm _emit '@' _asm _emit '>' _asm _emit '=' _asm _emit '[';
        _asm _emit '#' _asm _emit '`' _asm _emit '^' _asm _emit '?';
        _asm _emit '-' _asm _emit '1' _asm _emit '2' _asm _emit ')';
        _asm _emit '%' _asm _emit '.' _asm _emit '<' _asm _emit '~';
        _asm _emit '6' _asm _emit '9' _asm _emit '4' _asm _emit '3';
        _asm _emit '0' _asm _emit '!' _asm _emit '/' _asm _emit '&';
        _asm _emit '}' _asm _emit '|' _asm _emit ',' _asm _emit ';';
        _asm _emit '{' _asm _emit '*' _asm _emit '7' _asm _emit ']';
        _asm _emit '"' _asm _emit '5' _asm _emit ' ' _asm _emit ':';
        _asm _emit '(' _asm _emit '\\' _asm _emit '\'' _asm _emit '+';
        _asm _emit '8' _asm _emit '_' _asm _emit '$';

    mycont:
        pop edx;
        cmp al, 52;
        je capital_letter;
        cmp al, 26;
        je small_letter;

        xor ecx, ecx;
        xchg al, ah;
    decode_hash_table:
        bt [edx], ecx;
        adc al, 0;
        inc ecx;
        dec ah;
        jnz decode_hash_table;

        mov al, [edx + eax + 14];
        ret;

    capital_letter:
        mov al, [ecx];
        ret;

    small_letter:
        mov al, [ecx];
        add al, 32;
        ret;
    }
}

Algunos detalles de implementación notables:

  • Utiliza una CALLinstrucción para obtener un puntero al código, donde reside la tabla codificada. En el modo de 64 bits, podría usar el registro en su riplugar.
  • Utiliza las BTinstrucciones para acceder a la tabla de omisión
  • Se las arregla para hacer el trabajo usando sólo 3 registros eax, ecx, edx, que se puede clobbered - lo que no hay necesidad de guardar y restaurar los registros
  • Al decodificar la tabla hash, se usa aly con ahcuidado, de modo que en el lugar correcto ahse reduce a 0, y todo el eaxregistro se puede usar como un índice LUT
anatolyg
fuente
18

JavaScript ES6, 228, 236, 247, 257, 267, 274, 287

Nota: 7 caracteres guardados thx @ ev3commander

Nota 2: mejor que JAPT después de 7 ediciones principales,

n=>n<'L'?"XC!DO$MP&OS'SK*N--FU.ZE0TW2HR3OU4FI5IX6EI8NI9EM;LS=R->IA@MF^AV`MM,NE1EN7LO:".replace(/(..)./g,(c,s)=>~n.search(s)?n=c[2]:0)&&n:'~  / ;  |?"\\ ) }]_+ #% < ( {['[(n<'Q')*13+n.length-(n>'T')-4]||n[21]||n[19].toLowerCase()

Ejecute el fragmento para probar

F=n=>
  n<'L'?"XC!DO$MP&OS'SK*N--FU.ZE0TW2HR3OU4FI5IX6EI8NI9EM;LS=R->IA@MF^AV`MM,NE1EN7LO:"
  .replace(/(..)./g,(c,s)=>~n.search(s)?n=c[2]:0)&&n:
  '~  / ;  |?"\\ ) }]_+ #% < ( {['[(n<'Q')*13+n.length-(n>'T')-4]
  ||n[21]||n[19].toLowerCase()

//TEST
console.log=x=>O.innerHTML+=x+'\n'
;[
['&','AMPERSAND'],
['\'','APOSTROPHE'],
['*','ASTERISK'],
['^','CIRCUMFLEX ACCENT'],
[':','COLON'],
[',','COMMA'],
['@','COMMERCIAL AT'],
['8','DIGIT EIGHT'],
['5','DIGIT FIVE'],
['4','DIGIT FOUR'],
['9','DIGIT NINE'],
['1','DIGIT ONE'],
['7','DIGIT SEVEN'],
['6','DIGIT SIX'],
['3','DIGIT THREE'],
['2','DIGIT TWO'],
['0','DIGIT ZERO'],
['$','DOLLAR SIGN'],
['=','EQUALS SIGN'],
['!','EXCLAMATION MARK'],
['.','FULL STOP'],
['`','GRAVE ACCENT'],
['>','GREATER-THAN SIGN'],
['-','HYPHEN-MINUS'],
['A','LATIN CAPITAL LETTER A'],
['B','LATIN CAPITAL LETTER B'],
['C','LATIN CAPITAL LETTER C'],
['D','LATIN CAPITAL LETTER D'],
['E','LATIN CAPITAL LETTER E'],
['F','LATIN CAPITAL LETTER F'],
['G','LATIN CAPITAL LETTER G'],
['H','LATIN CAPITAL LETTER H'],
['I','LATIN CAPITAL LETTER I'],
['J','LATIN CAPITAL LETTER J'],
['K','LATIN CAPITAL LETTER K'],
['L','LATIN CAPITAL LETTER L'],
['M','LATIN CAPITAL LETTER M'],
['N','LATIN CAPITAL LETTER N'],
['O','LATIN CAPITAL LETTER O'],
['P','LATIN CAPITAL LETTER P'],
['Q','LATIN CAPITAL LETTER Q'],
['R','LATIN CAPITAL LETTER R'],
['S','LATIN CAPITAL LETTER S'],
['T','LATIN CAPITAL LETTER T'],
['U','LATIN CAPITAL LETTER U'],
['V','LATIN CAPITAL LETTER V'],
['W','LATIN CAPITAL LETTER W'],
['X','LATIN CAPITAL LETTER X'],
['Y','LATIN CAPITAL LETTER Y'],
['Z','LATIN CAPITAL LETTER Z'],
['a','LATIN SMALL LETTER A'],
['b','LATIN SMALL LETTER B'],
['c','LATIN SMALL LETTER C'],
['d','LATIN SMALL LETTER D'],
['e','LATIN SMALL LETTER E'],
['f','LATIN SMALL LETTER F'],
['g','LATIN SMALL LETTER G'],
['h','LATIN SMALL LETTER H'],
['i','LATIN SMALL LETTER I'],
['j','LATIN SMALL LETTER J'],
['k','LATIN SMALL LETTER K'],
['l','LATIN SMALL LETTER L'],
['m','LATIN SMALL LETTER M'],
['n','LATIN SMALL LETTER N'],
['o','LATIN SMALL LETTER O'],
['p','LATIN SMALL LETTER P'],
['q','LATIN SMALL LETTER Q'],
['r','LATIN SMALL LETTER R'],
['s','LATIN SMALL LETTER S'],
['t','LATIN SMALL LETTER T'],
['u','LATIN SMALL LETTER U'],
['v','LATIN SMALL LETTER V'],
['w','LATIN SMALL LETTER W'],
['x','LATIN SMALL LETTER X'],
['y','LATIN SMALL LETTER Y'],
['z','LATIN SMALL LETTER Z'],
['{','LEFT CURLY BRACKET'],
['(','LEFT PARENTHESIS'],
['[','LEFT SQUARE BRACKET'],
['<','LESS-THAN SIGN'],
['_','LOW LINE'],
['#','NUMBER SIGN'],
['%','PERCENT SIGN'],
['+','PLUS SIGN'],
['?','QUESTION MARK'],
['"','QUOTATION MARK'],
['\\','REVERSE SOLIDUS'],
['}','RIGHT CURLY BRACKET'],
[')','RIGHT PARENTHESIS'],
[']','RIGHT SQUARE BRACKET'],
[';','SEMICOLON'],
['/','SOLIDUS'],
[' ','SPACE'],
['~','TILDE'],
['|','VERTICAL LINE'],
].forEach(t=>{
  var r=F(t[1]),ok=r==t[0]
  //if (!ok) // uncomment to see just errors
  console.log(r+' ('+t[0]+') '+t[1]+(ok?' OK':' ERROR'))
})
console.log('DONE')
<pre id=O></pre>

edc65
fuente
55
¿Así cómo? Bien hecho.
SuperJedi224
En realidad, además del alfabeto, no hay caracteres que comiencen con "LA"
ev3commander
@ ev3commander sí, pero aquí administro LAT, RIG y LEF y 2 caracteres parecen muy pocos, teniendo IZQUIERDA y MENOS
edc65
Ohh Simplemente hojeé y no vi la parte RIG / LEF.
ev3commander
@ ev3commander pensándolo bien, ¡tienes razón! Puedo fusionar el manejo MENOS e IZQUIERDO y guardar 4 bytes. Thx
edc65
10

Japt , 230 bytes

V=U¯2;Ug21 ªU<'R©Ug19 v ªV¥"DI"©`ze¿twâ¿¿¿¿e¿i`u bUs6,8)/2ªUf"GN" ©"<>+=$#%"g`¤grp¤qºnupe`u bV /2 ªUf"T " ©"[]\{}()"g"QSUCAP"bUg6) ªUf" M" ©"!\"?"g"COE"bUg2) ªV¥"CO"©",:@"g"ANE"bUg4) ª" &'*-./\\;~^`_|"g`spaµp¿豢¿Èögrlove`u bV /2

Cada uno ¿representa un carácter Unicode no imprimible. Pruébalo en línea!

Sin golf:

V=Us0,2;Ug21 ||U<'R&&Ug19 v ||V=="DI"&&"zeontwthfofisiseeini"u bUs6,8)/2||Uf"GN" &&"<>+=$#%"g"legrpleqdonupe"u bV /2 ||Uf"T " &&"[]\{}()"g"QSUCAP"bUg6) ||Uf" M" &&"!\"?"g"COE"bUg2) ||V=="CO"&&",:@"g"ANE"bUg4) ||" &'*-./\\;~^`_|"g"spamapashyfusoreseticigrlove"u bV /2

Esto fue muy divertido. He dividido los nombres de los personajes en varios fragmentos grandes:

0. Toma las dos primeras letras

V=Us0,2;establece variable Va las dos primeras letras de U, la cadena de entrada. Esto será útil más tarde.

1. Mayúsculas

Esta es la más fácil: las letras mayúsculas son las únicas que tienen un carácter en la posición 21, que resultan ser la letra y el caso correctos. Por lo tanto, Ug21es suficiente.

2. letras minúsculas

Otro bastante fácil; el único otro nombre que tiene un carácter en la posición 19 es RIGHT SQUARE BRACKET, por lo que verificamos si el nombre viene antes Rcon U<'R, luego si es ( &&), tomamos el carácter 19 con Ug19y lo ponemos en minúscula con v.

3. Dígitos

Todos estos nombres comienzan con DI(y afortunadamente, ninguno de los otros), por lo que si V=="DI"podemos convertirlo en un dígito. Las primeras letras de algunos de los nombres de los dígitos son iguales, pero las dos primeras letras son suficientes. Combinando estos en una sola cadena, obtenemos ZEONTWTHFOFISISEEINI. Ahora podemos tomar el índice bde los dos primeros caracteres en el nombre del dígito Us6,8)y dividirlo por dos.

4) SIGN

Hay siete nombres que contienen SIGN:

<    LESS-THAN SIGN
>    GREATER-THAN SIGN
+    PLUS SIGN
=    EQUALS SIGN
$    DOLLAR SIGN
#    NUMBER SIGN
%    PERCENT SIGN

Primero comprobamos que el nombre contiene la palabra SIGN. Resulta que GNes suficiente; Uf"GN"devuelve todas las instancias del GNnombre, que es nullsi contiene 0 instancias, y por lo tanto se omite.

Ahora, usando la misma técnica que con los dígitos, combinamos las dos primeras letras en una cadena LEGRPLEQDONUPE, luego tomamos el índice y lo dividimos por dos. Esto da como resultado un número de 0-6, que podemos usar para tomar el carácter correspondiente de la cadena <>+=$#%.

5) MARK

Hay tres caracteres que contienen MARK:

!    EXCLAMATION MARK
"    QUOTATION MARK
?    QUESTION MARK

Aquí usamos la misma técnica que con SIGN.  Mes suficiente para diferenciar estos tres de los demás. Para traducir a un símbolo, esta vez verificar una letra es suficiente: el carácter en la posición 2 es diferente para los tres caracteres. Esto significa que no tenemos que dividir entre dos al elegir el personaje correcto.

6) LEFT/RIGHT

Este grupo contiene los corchetes y paréntesis, []{}(). Sería realmente complicado capturar ambos LEFTy RIGHT, afortunadamente, todos contienen la cadena . Verificamos esto con la misma técnica que hicimos con SIGN. Para traducir a un símbolo, como con MARK, verificar una letra es suficiente; El personaje en la posición 6 es único para los seis.

7) CO

El resto de los caracteres son bastante únicos, pero no lo suficientemente únicos. Tres de ellos comienzan con CO: COMMA, COLON, y COMMERCIAL AT. Utilizamos exactamente la misma técnica como lo hicimos con los soportes, elegir el símbolo apropiado basado en el carácter en la posición 4 ( A, No E).

8. Todo lo demás

Por ahora, los dos primeros caracteres son diferentes para cada nombre. Los combinamos todos en una gran cadena SPAMAPASHYFUSORESETICIGRLOVEy asignamos cada par a su correspondiente carácter  &'*-./\;~^`_|.

9. Pasos finales

Cada una de las partes devuelve una cadena vacía o, nullsi no es la correcta, podemos vincularlas todas de izquierda a derecha ||. El ||operador devuelve el argumento izquierdo si es verdadero, y el argumento derecho de lo contrario. Japt también tiene salida implícita, por lo que sea cual sea el resultado, se envía automáticamente al cuadro de salida.

Preguntas, comentarios y sugerencias bienvenidos!

ETHproducciones
fuente
Gran respuesta y gran explicación. Pero olvidó mencionar el manejo o MARK (!? ") En la explicación
edc65
@ edc65 ¡Vaya, gracias! He agregado en una sección sobre MARKcaracteres.
ETHproductions
77
spamapashyfusoreseticigrlove= Spam un pashy para reiniciar el amor de la chica helada ... +1
AdmBorkBork
No, eso es mucho golf.
Blacklight Shining
3

Python 2, 237 bytes

Obtenga el hash de la cadena y el módulo divídalo por 535. Posteriormente conviértalo a un carácter unicode con ese número. La posición del carácter unicode en una lista precompilada de caracteres unicode se convierte posteriormente al carácter ascii.

print chr(u"""ǶŀȎdȊÏöǖIhȏƜǓDZǠƣƚdžƩC+ĶÅĠěóƋŎªƱijůŰűŪūŬŭŶŷŸŹŲųŴŵžſƀƁźŻżŽƆƇƈŖÐŗǀǼǿǾǹǸǻǺȅȄȇȆȁȀȃȂǭǬǯǮǩǨǫǪǵǴǷNȌ~B""".index(unichr(hash(raw_input())%535))+32)
Willem
fuente
3

Javascript, 501 499 469 465 451 430 bytes

a=prompt();c="5SACEgEARKeQARKbNIGNbDIGNcPIGN9AANDaAPHEgLSIShRSIS8AISK9PIGN5CMMAcHNUS9FTOP7SDUSaDERO9DONE9DTWObDREEaDOURaDIVE9DSIXbDVENbDGHTaDINE5CLON9SLONeLIGNbEIGNhGIGNdQARKdC ATjLKETfRDUSkRKEThCENT8LINEcGENTiLKETdVINEjRKET5TLDE".match(/.{5}/g).indexOf(a.length.toString(36)+a[0]+a.slice(-3));if(c>=33)c+=26;if(c>=65)c+=26;alert(a.length==20&&a[0]=="L"?a.slice(-1).toLowerCase():a.length>21?a.slice(-1):String.fromCharCode(32+c))

Explicación:

Esa larga cadena es una lista comprimida. a.length.toString(36)+a[0]+a.slice(-3)determina cómo, en todo caso, la cadena se representará en la lista. Además, lógica especial para letras. (por a[0]cierto , es una abreviatura integrada para a.charAt(0), por cierto)

SuperJedi224
fuente
Si lo reemplaza _con +, podría Base64-comprimir la lista.
ETHproductions
@ETHproductions base64 hace las cosas más largas , no más cortas.
Blacklight Shining
@ETHproductions ¿El Javascript tiene base 64?
SuperJedi224
@ SuperJedi224 Sí, pero Blacklight es correcto a menos que la base 64 esté reemplazando un número que podría haberse expresado en una base más baja, especialmente binaria.
wedstrom
Se puede utilizar btoa("abc")para comprimir el texto en un 25% (con tal de que es válido el texto base 64, que sería después de reemplazar _con -), a continuación, atob("compressed stuff")en su código real.
ETHproductions
1

PowerShell, 603 547 464 bytes

$a=-split$args
$b=switch -W($a[0]){
"LEFT"{switch -w($a[1]){"C*"{"{"}"P*"{"("}"S*"{"["}}}
"RI*"{switch -w($a[1]){"C*"{"}"}"P*"{")"}"S*"{"]"}}}
"LA*"{("$($a[3])".ToLower(),$a[3])[$a[1]-like"C*"]}
"DI*"{@{ONE=1;TWO=2;THREE=3;FOUR=4;FIVE=5;SIX=6;SEVEN=7;EIGHT=8;NINE=9;ZERO="0"}[$a[1]]}
"COMME*"{"@"}
"APO*"{"'"}
}
$c='COM,LES<GRA`GRE>QUE?QUO"COL:REV\LOW_EXC!EQU=DOL$AMP&AST*PER%PLU+SEM;SOL/SPA CIR^HYP-FUL.NUM#TIL~VER|'
($b,$c[$c.IndexOf($a[0][0..2]-join'')+3])[!$b]

( LineFeedcuenta el mismo byte ;, así que dejaré los descansos para facilitar la lectura)

Edición 1: eliminó muchos elementos de la instrucción de cambio y, en su lugar, completó una tabla hash para las búsquedas.

Edición 2 - Oh sí ... indexar en una cadena, ese es el camino a seguir ...

Esencialmente toma la entrada, la divide en espacios y hace un comodín switchen la primera palabra para filtrar los tontos. Establece el resultado de eso en $b. Si $bno existe, la cadena $cse evalúa en las primeras tres letras de la primera palabra y genera el carácter que sigue inmediatamente; de ​​lo contrario, se genera $b.

Algunos trucos incluyen el LATIN CAPITAL LETTER Rque indexa en una matriz en función de si la segunda palabra es CAPITAL, y genera la letra mayúscula / minúscula correspondiente. El otro "truco" es para la DIGITs, indexando en una tabla hash. Tenga en cuenta que no es más corto hacer el mismo truco de índice en una cadena aquí (en realidad es más largo por un byte).

AdmBorkBork
fuente
Te estoy golpeando de nuevo.
SuperJedi224
1

Javascript, 416 411 389 bytes

l=(E)=>{return E=E.replace(/LA.*N|BR.*T|SIGN|MARK| |TION/g,"").replace(/(.).*(.{3})/,"$1$2"),E.match("CER")?E[3]:E.match("SER")?E[3].toLowerCase():(a="SACE EAMA!QOTA\"NBER#DLAR$PENT%AAND&APHE'AISK*PLUS+CMMA,HNUS-FTOP.SDUS/CLON:SLON;LHAN<EALS=GHAN>QUES?CLAT@RDUS\\CENT^LINE_GENT`VINE|LSIS(RSIS)LARE[RARE]LRLY{RRLY}TLDE~DERO0DONE1DTWO2DREE3DOUR4DIVE5DSIX6DVEN7DGHT8DINE9",a[a.indexOf(E)+4])}

Este es un formato más legible (la explicación vendrá más adelante):

function l(k){
    k=k.replace(/LA.*N|BR.*T|SIGN|MARK| |TION/g,'').replace(/(.).*(.{3})/,'$1$2')
    if(k.match('CER')) return k[3];
    if(k.match('SER')) return k[3].toLowerCase();
    a="SACE EAMA!QOTA\"NBER#DLAR$PENT%AAND&APHE'AISK*PLUS+CMMA,HNUS-FTOP.SDUS/CLON:SLON;LHAN<EALS=GHAN>QUES?CLAT@RDUS\\CENT^LINE_GENT`VINE|LSIS(RSIS)LARE[RARE]LRLY{RRLY}TLDE~DERO0DONE1DTWO2DREE3DOUR4DIVE5DSIX6DVEN7DGHT8DINE9"
    return a[a.indexOf(k)+4];
}

Menos 5 bytes de la combinación de cadenas de clave y valor.

Explicación: Las expresiones regulares en la primera línea reducen las entradas en claves únicas de 4 caracteres. Tenga en cuenta que la unicidad solo está garantizada para el conjunto específico de nombres especificados en el desafío, ¡y los duplicados serían muy comunes para el inglés normal! Incluso para este desafío, tuve que eliminar palabras comunes como corchetes y signos para obtener un conjunto único.

Para devolver el carácter, verifico si es un carácter latino comprobando las cadenas "SER" y "cer", y devuelvo el último carácter de la entrada, en minúsculas para ser.

Para todo lo demás, me refiero a una cadena que contiene todas las 4 teclas de caracteres, seguidas del carácter correcto. Luego uso indexof y los índices de caracteres de subcadena para extraer y devolver el carácter.

Editar: se usaron más comodines para reducir el tamaño de expresiones regulares, se reemplazó substr con índices de caracteres y se recortó en veinte caracteres. Los expertos en reglas notarán que esta actualización final se publica después de que el desafío ha finalizado, sin embargo, no creo que haya cambiado mi clasificación. Esto es solo práctica para un novato.

Wedstrom
fuente
1

Python 3, 148 bytes

lambda s:chr(83-b'gfhtg\32}urgx_}3qeo|e~cwu~S~q~I,vqG\34jc}d*9~~_L|p~~~~~JJy'[sum(b'  !" *1! "2;D$# ! # !!( '[ord(c)%25]-32for c in s[:-1])]+ord(s[-1]))

Para su comodidad de visualización, he reemplazado dos bytes no imprimibles con los códigos de escape octal \32y \34; deshaga esto para obtener la función de 148 bytes.

Calculé partes de esta función hash con GPerf .

Anders Kaseorg
fuente
0

Perl 6 ,  348   242 bytes

{
  /NI/??9!!chr 32+
  '0A40W00SV0M20LR0O20IJ0LH0WH0YS0H20ID0A50P10IH0F70K10HF0I30LL0JX0JF0HX0LU0LE0JF0AJ0IX0RK0M40XF0QR0PD15Z16016116216316416516616716816916A16B16C16D16E16F16G16H16I16J16K16L16M16N16O1140V313F0XS0FU0N712A12B12C12D12E12F12G12H12I12J12K12L12M12N12O12P12Q12R12S12T12U12V12W12X12Y12Z0ZA0PU11L0AA'
  .comb(3).map({:36($_)}).first(:k,[+] .ords)
} # 348

{chr 32+"\x95ǐǠŬšƉĘŗȌȴĎĽ\x96ŖŁöģěĈśŊčĂĹŔĸ¤ĦƱŮȃƿƍʶʷʸʹʺʻʼʽʾʿˀˁ˂˃˄˅ˆˇˈˉˊʠʡʢʣʤɝǚʅǥâĿʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛɱɲɳɴɵțųɃ\x9b".ords.first: :k,[+] .ords.map(*%43)}
{
  chr 32+
  "\x95ǐǠŬšƉĘŗȌȴĎĽ\x96ŖŁöģěĈśŊčĂĹŔĸ¤ĦƱŮȃƿƍʶʷʸʹʺʻʼʽʾʿˀˁ˂˃˄˅ˆˇˈˉˊʠʡʢʣʤɝǚʅǥâĿʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛɱɲɳɴɵțųɃ\x9b"
  .ords.first: :k,[+] .ords.map(*%43)
}

uso:

my &code = {...}

# testing
my $test = [~] (' '..'~')».uniname».&code;
my $comparison = [~] ' '..'~';
say $test eq $comparison; # True

say code 'HYPHEN-MINUS'; # -
Brad Gilbert b2gills
fuente