Nome básico de caractere latino para caractere

23

Vamos voltar ao básico!

  • Seu código, um programa ou função completo, deve converter o nome Unicode oficial de um caractere latino básico imprimível no caractere correspondente. Por exemplo, para a entrada LOW LINEseu código deve gerar _.
  • Você só precisa usar um único nome de caractere como entrada.
  • Você não pode usar nenhuma função ou biblioteca preexistente, embutida ou não, que ofereça qualquer lógica relacionada especificamente aos nomes de caracteres Unicode (por exemplo, Python unicodedata, Java Character.getNamee assim por diante).
  • Para entrada diferente de um desses nomes, qualquer comportamento é aceitável.

Este é o código golf: o código mais curto em bytes vence.

Para evitar qualquer ambiguidade, este é o conjunto completo de nomes de personagens oficiais que usaremos (emprestados desta pergunta ):

     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
fonte
2
O programa precisa apenas lidar com o nome de um caractere? Por exemplo, COLON COLONsaída ::ou comportamento indefinido?
Kevin W.
Editado para esclarecer.
Lucas
Por que é String.fromCharCodeproibido?
precisa saber é o seguinte
Opa, eu não entendi o que essa função faz.
Lucas
Como devemos lidar com entradas inválidas, como CLON?
edc65

Respostas:

25

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

Hexdump do 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 algum hash. Por alguma pesquisa de força bruta, descobri que a seguinte função hash pode ser aplicada aos bytes da string de entrada:

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

Ele multiplica xpor 89, adiciona o próximo byte (código ASCII) e adota o módulo 113 restante. Ele faz isso em todos os bytes da string de entrada, exceto o último, por exemplo, LATIN CAPITAL LETTER Ae LATIN CAPITAL LETTER Xfornece o mesmo código de hash.

Essa função hash não tem colisões e a saída está no intervalo de 0 a 113 (na verdade, por sorte, o intervalo é ainda mais estreito: 3 a 108).

Os valores de hash de todas as strings relevantes não preenchem completamente esse espaço, então decidi usá-lo para compactar a tabela de hash. Adicionei uma tabela "ignorar" (112 bits), que contém 0 se o local correspondente na tabela de hash estiver vazio e 1 caso contrário. Esta tabela converte um valor de hash em um índice "compactado", que pode ser usado para endereçar uma LUT densa.

As strings LATIN CAPITAL LETTERe LATIN SMALL LETTERfornecem códigos de hash 52 e 26; eles são tratados separadamente. Aqui está um código C para isso:

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];
}

O código da linguagem de montagem correspondente (sintaxe de montagem em linha do 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;
    }
}

Alguns detalhes de implementação dignos de nota:

  • Ele usa uma CALLinstrução para obter um ponteiro para o código, onde reside a tabela codificada. No modo de 64 bits, ele poderia usar o registro rip.
  • Ele usa a BTinstrução para acessar a tabela de pular
  • Ele consegue fazer o trabalho usando apenas 3 registros eax, ecx, edx, que pode ser derrotado - por isso não há necessidade de salvar e restaurar registradores
  • Quando a descodificação tabela hash, que utiliza ale ahcuidadosamente, de modo que no lugar certo, ahé diminuída a 0, e todo o eaxregisto pode ser usado como um índice LUT
anatolyg
fonte
18

JavaScript ES6, 228 236 247 257 267 274 287

Nota: 7 caracteres salvos thx @ ev3commander

Nota 2: melhor que o JAPT após 7 edições principais,

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()

Execute o trecho para testar

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
fonte
5
Quão? Bem feito.
SuperJedi224
Na verdade, além do alfabeto, não há caracteres começando com "LA"
ev3commander 08/12/15
@ ev3commander sim, mas aqui eu consigo LAT, RIG e LEF e 2 caracteres parece muito poucos, tendo deixado e menos
edc65
Ohh Eu apenas deslizei e não vi a parte RIG / LEF.
Ev3commander
@ ev3commander pensando bem que você tem razão! Eu posso mesclar manipulação menos e esquerda e salvar 4 bytes. Thx
edc65
10

Japonês , 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 ¿um representa um caractere Unicode não imprimível. Experimente online!

Ungolfed:

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

Isso foi muito divertido. Dividi os nomes dos personagens em vários pedaços grandes:

0. Pegue as duas primeiras letras

V=Us0,2;define variável Vpara as duas primeiras letras de U, a sequência de entrada. Isso será útil mais tarde.

1. Letras maiúsculas

Isso é o mais fácil: as letras maiúsculas são as únicas que possuem um caractere na posição 21, que são a letra e o caso corretos. Assim, Ug21é suficiente.

2. Letras minúsculas

Outro bastante fácil; o único outro nome que tem um caractere na posição 19 é RIGHT SQUARE BRACKET, portanto, verificamos se o nome vem Rcom antes U<'R; se for ( &&), pegamos o 19º caractere Ug19e o colocamos em minúscula v.

3. Dígitos

Todos esses nomes começam com DI(e, felizmente, nenhum dos outros), portanto V=="DI", se podemos transformá-lo em um dígito. As primeiras letras de alguns dos nomes dos dígitos são as mesmas, mas as duas primeiras são suficientes. Combinando-os em uma sequência, obtemos ZEONTWTHFOFISISEEINI. Agora podemos pegar o índice bdos dois primeiros caracteres no nome do dígito Us6,8)e dividir por dois.

4) SIGN

Existem sete nomes que contêm SIGN:

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

Primeiro, verificamos se o nome contém a palavra SIGN. Acontece que GNé suficiente; Uf"GN"retorna todas as instâncias de GNno nome, ou seja, nullse ele contém 0 instâncias e, portanto, é ignorado.

Agora, usando a mesma técnica dos dígitos, combinamos as duas primeiras letras em uma sequência LEGRPLEQDONUPE, depois pegamos o índice e dividimos por duas. Isso resulta em um número 0-6, do qual podemos usar para obter o caractere correspondente da string <>+=$#%.

5) MARK

Existem três caracteres que contêm MARK:

!    EXCLAMATION MARK
"    QUOTATION MARK
?    QUESTION MARK

Aqui usamos a mesma técnica que com SIGN.  Mé suficiente para diferenciar esses três dos outros. Para traduzir para um símbolo, desta vez, basta marcar uma letra: o caractere na posição 2 é diferente para os três caracteres. Isso significa que não precisamos dividir por dois ao escolher o caractere correto.

6 LEFT/RIGHT

Este grupo contém colchetes e parênteses []{}(). Seria realmente complicado capturar os dois LEFTe RIGHT, felizmente, todos eles contêm a string . Verificamos isso com a mesma técnica que fizemos SIGN. Para traduzir para um símbolo, MARKbasta verificar uma letra; o personagem na posição 6 é único para todos os seis.

7) CO

O resto dos caracteres são bastante únicos, mas não são únicos o suficiente. Três deles começar com CO: COMMA, COLON, e COMMERCIAL AT. Usamos exatamente a mesma técnica como fizemos com os suportes, escolhendo o símbolo correto baseado no personagem na posição 4 ( A, Nou E).

8. Tudo o resto

Até agora, os dois primeiros caracteres são diferentes para cada nome. Combinamos todos eles em uma sequência grande SPAMAPASHYFUSORESETICIGRLOVEe mapeamos cada par para o caractere correspondente  &'*-./\;~^`_|.

9. Etapas finais

Cada uma das partes retorna uma string vazia ou, nullse não for a correta, para que possamos vinculá-las da esquerda para a direita ||. O ||operador retorna o argumento da esquerda, se for verdade, e o argumento da direita, caso contrário. O Japt também possui saída implícita; portanto, seja qual for o resultado, ele é automaticamente enviado para a caixa de saída.

Perguntas, comentários e sugestões são bem-vindos!

ETHproductions
fonte
Ótima resposta e ótima explicação. Mas você esqueceu de mencionar a manipulação ou MARK na explicação ( "!?)
edc65
@ edc65 Opa, obrigado! Eu adicionei em uma seção sobre MARKcaracteres.
ETHproductions
7
spamapashyfusoreseticigrlove= Spam um pashy por tanto redefinição amor gelada menina ... +1
AdmBorkBork
Não, isso ainda é muito jogado.
Blacklight Shining
3

Python 2, 237 bytes

Obtenha o hash da string e o módulo divida-o por 535. Posteriormente, converta-o em um caractere unicode com esse número. A posição do caractere unicode em uma lista pré-compilada de caracteres unicode é posteriormente convertida no caractere ascii.

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

Explicação:

Essa cadeia longa é uma lista compactada. a.length.toString(36)+a[0]+a.slice(-3)determina como, se houver, a sequência será representada na lista. Além disso, lógica especial para letras. (com strings, a[0]é uma abreviação interna para a.charAt(0), a propósito)

SuperJedi224
fonte
Se você substituiu _por +, poderia Base64-comprimir a lista.
ETHproductions
O @ETHproductions base64 torna as coisas mais longas , não mais curtas.
Blacklight Shining
@ETHproductions O Javascript possui Base64?
precisa saber é o seguinte
@ SuperJedi224 Sim, mas o Blacklight está correto, a menos que a base 64 esteja substituindo um número que poderia ter sido expresso em uma base inferior, especialmente binária.
wedstrom 08/12/2015
Você pode usar btoa("abc")ao texto compressa por 25% (desde que ele é válido texto base-64, que seria depois de substituir _com -), então atob("compressed stuff")em seu 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]

( LineFeedconta o mesmo byte que ;, então deixarei as quebras para facilitar a leitura)

Editar 1 - Retirou muitos elementos da instrução switch e preencheu uma hashtable para pesquisas.

Edit 2 - Oh yeah ... indexando em uma string, esse é o caminho a seguir ...

Essencialmente, pega a entrada, divide-a em espaços e faz um curinga switchna primeira palavra para filtrar as mais engraçadas. Define o resultado disso para $b. Se $bnão existir, a cadeia de caracteres $cé avaliada nas três primeiras letras da primeira palavra e gera o caractere imediatamente a seguir, caso contrário, produzimos $b.

Alguns truques incluem o LATIN CAPITAL LETTER Rque indexa em uma matriz com base na segunda palavra CAPITAL, e gera a letra maiúscula / minúscula correspondente. O outro "truque" é para os DIGIT, indexando em uma hashtable. Observe que não é mais curto fazer o mesmo truque de indexar em uma string aqui (na verdade, é mais longo em um byte).

AdmBorkBork
fonte
Estou batendo em você de novo.
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 é um formato mais legível (explicação a seguir):

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 da combinação de cadeias de chave e valor.

Explicação: As expressões regulares na primeira linha reduzem as entradas em chaves exclusivas de 4 caracteres. Observe que a exclusividade é garantida apenas para o conjunto específico de nomes especificado no desafio, e duplicatas seriam muito comuns no inglês normal! Mesmo para esse desafio, tive que remover palavras comuns como colchete e sinal para obter um conjunto exclusivo.

Para retornar o caractere, verifico se é um caractere latino, verificando as cadeias "SER" e "cer", e retorno o último caractere da entrada, em minúsculas para ser.

Para todo o resto, refiro-me a uma sequência que contém todas as chaves de 4 caracteres, seguidas pelo caractere correto. Depois, uso índices de caracteres indexof e substring para puxar e retornar o caractere.

Edit: Utilizou mais curingas para reduzir o tamanho de regex, substituiu substr por índices de caracteres e raspou mais vinte caracteres. Os defensores das regras observarão que esta atualização final será publicada após o término do desafio, no entanto, não acho que isso tenha mudado minha classificação. Isso é apenas prática para um iniciante.

wedstrom
fonte
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 sua conveniência de visualização, substituí dois bytes não imprimíveis pelos códigos de escape octais \32e \34; desfazer isso para obter a função de 148 bytes.

Eu calculei partes dessa função de hash com o GPerf .

Anders Kaseorg
fonte
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
fonte