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 LINE
votre 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
, JavaCharacter.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
COLON COLON
sortie devrait::
-elle ou un comportement non défini?String.fromCharCode
interdit?CLON
?Réponses:
Code machine IA-32,
161160122 octetsHexdump du code:
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:
Il multiplie
x
par 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 exempleLATIN CAPITAL LETTER A
etLATIN CAPITAL LETTER X
donne 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 LETTER
etLATIN SMALL LETTER
donnent les codes de hachage 52 et 26; ils sont traités séparément. Voici un code C pour cela:Le code du langage d'assemblage correspondant (syntaxe d'assemblage en ligne MS Visual Studio):
Quelques détails de mise en œuvre remarquables:
CALL
instruction 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 à larip
place.BT
instruction pour accéder à la table de sauteax
,ecx
,edx
qui peut être mis à mal - il n'y a donc pas besoin de sauvegarder et de restaurer les registresal
etah
soigneusement, de sorte qu'au bon endroitah
est réduit à 0, et leeax
registre entier peut être utilisé comme un index LUTla source
JavaScript ES6, 228
236 247 257 267 274 287Remarque: 7 caractères ont enregistré thx @ ev3commander
Note 2: mieux que JAPT après 7 modifications majeures,
Exécutez l'extrait de code pour tester
la source
Japt , 230 octets
Chacun
¿
représente un caractère Unicode non imprimable. Essayez-le en ligne!Non golfé:
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 variableV
sur les deux premières lettres deU
la 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,
Ug21
est 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é avantR
avecU<'R
, alors si elle est (&&
), nous prenons le 19 omble chevalierUg19
et le jeta en minuscules avecv
.3. Chiffres
Ces noms commencent tous par
DI
(et heureusement, aucun des autres), donc siV=="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 obtenonsZEONTWTHFOFISISEEINI
. Maintenant, nous pouvons simplement prendre l'indexb
des deux premiers caractères du nom du chiffre avecUs6,8)
et diviser par deux.4.
SIGN
Il y a sept noms qui contiennent
SIGN
:On vérifie d'abord que le nom contient bien le mot
SIGN
. Il s'avère que celaGN
suffit;Uf"GN"
renvoie toutes les instances deGN
dans le nom, c'est-à-direnull
s'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 de0-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
:Ici, nous utilisons la même technique qu'avec
SIGN
.M
est 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 deuxLEFT
etRIGHT
, mais heureusement, ils contiennent tous la chaîneT
. Nous vérifions cela avec la même technique que nous l'avons fait avecSIGN
. Pour traduire en symbole, comme pourMARK
, 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
,COLON
etCOMMERCIAL 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
,N
ouE
).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
SPAMAPASHYFUSORESETICIGRLOVE
et mappons chaque paire à son caractère correspondant dans&'*-./\;~^`_|
.9. Étapes finales
Chacune des parties renvoie une chaîne vide ou
null
si 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!
la source
MARK
caractères.spamapashyfusoreseticigrlove
= Spam un pâteux pour réinitialiser l'amour des filles glacées ... +1Python 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.
la source
Javascript,
501499469465451430 octetsExplication:
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é poura.charAt(0)
, soit dit en passant)la source
_
par+
, vous pourriez compresser Base64 la liste.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-
), puisatob("compressed stuff")
dans votre code réel.PowerShell,
603547464 octets(
LineFeed
compte 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
switch
sur le premier mot pour filtrer les maladroits. Définit le résultat de cela sur$b
. S'il$b
n'existe pas, la chaîne$c
est é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 R
indexation dans un tableau en fonction du deuxième motCAPITAL
et la sortie de la lettre majuscule / minuscule correspondante. L'autre "astuce" est pour leDIGIT
s, 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).la source
Javascript,
416411389 octetsC'est un format plus lisible (explication à venir):
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
substringcaractè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.
la source
Python 3, 148 octets
Pour votre confort de visualisation, j'ai remplacé deux octets non imprimables par les codes d'échappement octaux
\32
et\34
; annulez cela pour obtenir la fonction 148 octets.J'ai calculé des parties de cette fonction de hachage avec GPerf .
la source
Perl 6 ,
348242 octetsusage:
la source