Nom de caractère latin de base en caractère

23

Revenons à l'essentiel!

  • Votre code, un programme ou une fonction complète, doit convertir le nom Unicode officiel d'un caractère latin de base imprimable en le caractère correspondant. Par exemple, pour l'entrée, LOW LINEvotre code doit sortir _.
  • Il vous suffit de prendre un seul nom de caractère en entrée.
  • Vous ne pouvez pas utiliser une fonction ou une bibliothèque préexistante, intégrée ou non, qui offre une logique spécifiquement liée aux noms de caractères Unicode (par exemple, Python unicodedata, Java Character.getName, etc.).
  • Pour une entrée autre que l'un de ces noms, tout comportement est acceptable.

C'est le golf de code: le code le plus court en octets gagne.

Pour éviter toute ambiguïté, voici l'ensemble complet des noms de personnages officiels que nous utiliserons (emprunté à cette question ):

     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
Luc
la source
2
Le programme a-t-il seulement besoin de gérer un nom de caractère? Par exemple, la COLON COLONsortie devrait ::-elle ou un comportement non défini?
Kevin W.
Modifié pour clarifier.
Luke
Pourquoi est-il String.fromCharCodeinterdit?
SuperJedi224
Oups, j'ai mal compris ce que fait cette fonction.
Luke
Comment devons-nous gérer les entrées invalides, comme CLON?
edc65

Réponses:

25

Code machine IA-32, 161 160 122 octets

Hexdump du code:

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

Ce code utilise un hachage. Par une recherche par force brute, j'ai trouvé que la fonction de hachage suivante peut être appliquée aux octets de la chaîne d'entrée:

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

Il multiplie xpar 89, ajoute l'octet suivant (code ASCII) et prend un reste modulo 113. Il le fait sur tous les octets de la chaîne d'entrée sauf la dernière, donc par exemple LATIN CAPITAL LETTER Aet LATIN CAPITAL LETTER Xdonne le même code de hachage.

Cette fonction de hachage n'a pas de collisions et la sortie est dans la plage 0 ... 113 (en fait, par chance, la plage est encore plus étroite: 3 ... 108).

Les valeurs de hachage de toutes les chaînes pertinentes ne remplissent pas complètement cet espace, j'ai donc décidé de l'utiliser pour compresser la table de hachage. J'ai ajouté une table "skip" (112 bits), qui contient 0 si la place correspondante dans la table de hachage est vide, et 1 sinon. Ce tableau convertit une valeur de hachage en un index "compressé", qui peut être utilisé pour adresser une LUT dense.

Les chaînes LATIN CAPITAL LETTERet LATIN SMALL LETTERdonnent les codes de hachage 52 et 26; ils sont traités séparément. Voici un code C pour cela:

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

Le code du langage d'assemblage correspondant (syntaxe d'assemblage en ligne 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;
    }
}

Quelques détails de mise en œuvre remarquables:

  • Il utilise une CALLinstruction pour obtenir un pointeur sur le code, où réside la table codée en dur. En mode 64 bits, il pourrait utiliser le registre à la ripplace.
  • Il utilise l' BTinstruction pour accéder à la table de saut
  • Il parvient à faire le travail en utilisant seulement trois registres eax, ecx, edxqui peut être mis à mal - il n'y a donc pas besoin de sauvegarder et de restaurer les registres
  • Lors du décodage de la table de hachage, il utilise alet ahsoigneusement, de sorte qu'au bon endroit ahest réduit à 0, et le eaxregistre entier peut être utilisé comme un index LUT
anatolyg
la source
18

JavaScript ES6, 228 236 247 257 267 274 287

Remarque: 7 caractères ont enregistré thx @ ev3commander

Note 2: mieux que JAPT après 7 modifications majeures,

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

Exécutez l'extrait de code pour tester

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
la source
5
Juste comment? Bien joué.
SuperJedi224
En fait, à part l'alphabet, il n'y a pas de caractère commençant par "LA"
ev3commander
@ ev3commander oui, mais ici je gère LAT, RIG et LEF et 2 caractères semblent trop peu, ayant LEFT et LESS
edc65
Ohh. Je viens de survoler et je n'ai pas vu la partie RIG / LEF.
ev3commander
@ ev3commander sur la deuxième pensée que vous avez un point! Je peux fusionner la gestion MOINS et GAUCHE et économiser 4 octets. Thx
edc65
10

Japt , 230 octets

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

Chacun ¿représente un caractère Unicode non imprimable. Essayez-le en ligne!

Non 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

C'était vraiment amusant. J'ai divisé les noms des personnages en plusieurs gros morceaux:

0. Prenez les deux premières lettres

V=Us0,2;définit la variable Vsur les deux premières lettres de Ula chaîne d'entrée. Cela vous sera utile plus tard.

1. Lettres majuscules

C'est le plus simple: les majuscules sont les seules qui ont un caractère à la position 21, qui se trouvent toutes être la lettre et la casse correctes. Ainsi, Ug21est suffisant.

2. Lettres minuscules

Un autre assez facile; le seul autre nom qui a un caractère à la position 19 est RIGHT SQUARE BRACKET, donc , nous vérifions si le nom est livré avant Ravec U<'R, alors si elle est ( &&), nous prenons le 19 omble chevalier Ug19et le jeta en minuscules avec v.

3. Chiffres

Ces noms commencent tous par DI(et heureusement, aucun des autres), donc si V=="DI", nous pouvons le transformer en un chiffre. Les premières lettres de certains noms de chiffres sont les mêmes, mais les deux premières lettres sont suffisantes. En les combinant en une seule chaîne, nous obtenons ZEONTWTHFOFISISEEINI. Maintenant, nous pouvons simplement prendre l'index bdes deux premiers caractères du nom du chiffre avec Us6,8)et diviser par deux.

4. SIGN

Il y a sept noms qui contiennent SIGN:

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

On vérifie d'abord que le nom contient bien le mot SIGN. Il s'avère que cela GNsuffit; Uf"GN"renvoie toutes les instances de GNdans le nom, c'est-à-dire nulls'il contient 0 instances, et est donc ignoré.

Maintenant, en utilisant la même technique qu'avec les chiffres, nous combinons les deux premières lettres en une chaîne LEGRPLEQDONUPE, puis prenons l'index et divisons par deux. Il en résulte un nombre de 0-6, que nous pouvons utiliser pour prendre le caractère correspondant de la chaîne <>+=$#%.

5. MARK

Il y a trois caractères qui contiennent MARK:

!    EXCLAMATION MARK
"    QUOTATION MARK
?    QUESTION MARK

Ici, nous utilisons la même technique qu'avec SIGN.  Mest suffisant pour différencier ces trois des autres. Pour traduire en symbole, il suffit cette fois de vérifier une lettre: le caractère en position 2 est différent pour les trois caractères. Cela signifie que nous n'avons pas à diviser par deux lors du choix du bon caractère.

6. LEFT/RIGHT

Ce groupe contient les crochets et les parenthèses, []{}(). Ce serait vraiment compliqué de capturer les deux LEFTet RIGHT, mais heureusement, ils contiennent tous la chaîne . Nous vérifions cela avec la même technique que nous l'avons fait avec SIGN. Pour traduire en symbole, comme pour MARK, vérifier une lettre suffit; le personnage en position 6 est unique pour les six.

7. CO

Les autres caractères sont assez uniques, mais pas assez uniques. Trois d'entre eux commencent par CO: COMMA, COLONet COMMERCIAL AT. Nous utilisons exactement la même technique que nous avons fait avec les crochets, choisir le symbole approprié en fonction du caractère à la position 4 ( A, Nou E).

8. Tout le reste

À l'heure actuelle, les deux premiers caractères sont différents pour chaque nom. Nous les combinons tous en une seule grande chaîne SPAMAPASHYFUSORESETICIGRLOVEet mappons chaque paire à son caractère correspondant dans  &'*-./\;~^`_|.

9. Étapes finales

Chacune des parties renvoie une chaîne vide ou nullsi ce n'est pas la bonne, nous pouvons donc toutes les lier de gauche à droite avec ||. L' ||opérateur renvoie l'argument de gauche s'il est vrai et l'argument de droite dans le cas contraire. Japt a également une sortie implicite, donc quel que soit le résultat, il est automatiquement envoyé à la boîte de sortie.

Questions, commentaires et suggestions bienvenus!

ETHproductions
la source
Grande réponse et grande explication. Mais vous avez oublié de mentionner la manipulation ou MARK (!? ") Dans l'explication
edc65
@ edc65 Oups, merci! J'ai ajouté une section sur les MARKcaractères.
ETHproductions
7
spamapashyfusoreseticigrlove= Spam un pâteux pour réinitialiser l'amour des filles glacées ... +1
AdmBorkBork
Non, c'est encore du golf.
Blacklight Shining
3

Python 2, 237 octets

Obtenez le hachage de la chaîne et modulo divisez-le par 535. Convertissez-le ensuite en un caractère unicode avec ce numéro. La position du caractère unicode dans une liste précompilée de caractères unicode est ensuite convertie en caractère ascii.

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

Javascript, 501 499 469 465 451 430 octets

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

Explication:

Cette longue chaîne est une liste compressée. a.length.toString(36)+a[0]+a.slice(-3)détermine comment, le cas échéant, la chaîne sera représentée dans la liste. Aussi, logique spéciale pour les lettres. (avec des cordes, a[0]est un raccourci intégré pour a.charAt(0), soit dit en passant)

SuperJedi224
la source
Si vous avez remplacé _par +, vous pourriez compresser Base64 la liste.
ETHproductions
@ETHproductions base64 rend les choses plus longues , pas plus courtes.
Blacklight Shining
@ETHproductions Javascript a-t -il Base64?
SuperJedi224
@ SuperJedi224 Oui, mais Blacklight est correct à moins que la base 64 ne remplace un nombre qui aurait pu être exprimé dans une base inférieure, en particulier binaire.
Wedstrom
Vous pouvez utiliser btoa("abc")pour compresser le texte de 25% (tant qu'il s'agit d'un texte de base 64 valide, qu'il serait après le remplacer _par -), puis atob("compressed stuff")dans votre code réel.
ETHproductions
1

PowerShell, 603 547 464 octets

$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]

( LineFeedcompte le même octet que ;, donc je laisse les pauses pour plus de lisibilité)

Édition 1 - A retiré de nombreux éléments de l'instruction switch et a plutôt rempli une table de hachage pour les recherches.

Edit 2 - Oh ouais ... l'indexation dans une chaîne, c'est la voie à suivre ...

Prend essentiellement l'entrée, la divise en espaces et fait un caractère générique switchsur le premier mot pour filtrer les maladroits. Définit le résultat de cela sur $b. S'il $bn'existe pas, la chaîne $cest évaluée sur les trois premières lettres du premier mot et sort le caractère immédiatement suivant, sinon nous sortons $b.

Certaines astuces incluent l' LATIN CAPITAL LETTER Rindexation dans un tableau en fonction du deuxième mot CAPITALet la sortie de la lettre majuscule / minuscule correspondante. L'autre "astuce" est pour le DIGITs, en l'indexant dans une table de hachage. Notez qu'il n'est pas plus court de faire la même astuce d'indexation en chaîne ici (c'est en fait plus long d'un octet).

AdmBorkBork
la source
Je te bat encore.
SuperJedi224
1

Javascript, 416 411 389 octets

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

C'est un format plus lisible (explication à venir):

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

Moins 5 octets de la combinaison de chaînes de clés et de valeurs.

Explication: Les expressions régulières sur la première ligne réduisent les entrées en clés uniques à 4 caractères. Notez que l'unicité n'est garantie que pour l'ensemble spécifique de noms spécifié dans le défi, et les doublons seraient très courants pour un anglais normal! Même pour ce défi, j'ai dû supprimer des mots courants comme crochet et signe pour obtenir un ensemble unique.

Pour retourner le caractère, je vérifie s'il s'agit d'un caractère latin en vérifiant les chaînes "SER" et "cer", et retourne le dernier caractère de l'entrée, en minuscule pour ser.

Pour tout le reste, je me réfère à une chaîne qui contient toutes les 4 touches de caractères, suivies du caractère correct. J'utilise ensuite indexof et substring caractères pour extraire et renvoyer le caractère.

Edit: utilisé plus de caractères génériques pour réduire la taille des regex, remplacé les substr par des indices de caractères et rasé vingt autres caractères. Les tenants des règles noteront que cette mise à jour finale est publiée après la fin du défi, mais je ne pense pas que cela ait changé mon classement. C'est juste une pratique pour un novice.

Wedstrom
la source
1

Python 3, 148 octets

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

Pour votre confort de visualisation, j'ai remplacé deux octets non imprimables par les codes d'échappement octaux \32et \34; annulez cela pour obtenir la fonction 148 octets.

J'ai calculé des parties de cette fonction de hachage avec GPerf .

Anders Kaseorg
la source
0

Perl 6 ,  348   242 octets

{
  /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)
}

usage:

my &code = {...}

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

say code 'HYPHEN-MINUS'; # -
Brad Gilbert b2gills
la source