Wróćmy do podstaw!
- Twój kod, kompletny program lub funkcja, musi przekonwertować oficjalną nazwę Unicode drukowalnego podstawowego znaku łacińskiego na odpowiedni znak. Na przykład dla danych wejściowych
LOW LINE
kod musi zostać wygenerowany_
. - Musisz tylko wpisać jedną nazwę postaci jako dane wejściowe.
- Nie można korzystać z żadnej istniejącej funkcji lub biblioteki, wbudowanej lub innej, która oferuje logikę związaną konkretnie z nazwami znaków Unicode (np. Python
unicodedata
, JavaCharacter.getName
itp.) - W przypadku danych wejściowych innych niż jedna z tych nazw każde zachowanie jest dopuszczalne.
To jest kod golfowy: wygrywa najkrótszy kod w bajtach.
Aby uniknąć dwuznaczności, jest to pełny zestaw oficjalnych nazw postaci, których będziemy używać (zapożyczone z tego pytania ):
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
dane wyjściowe::
lub niezdefiniowane zachowanie?String.fromCharCode
zabronione?CLON
?Odpowiedzi:
Kod maszynowy IA-32,
161160122 bajtówHexdump kodu:
Ten kod używa haszowania. W wyniku wyszukiwania metodą brute-force odkryłem, że do bajtów ciągu wejściowego można zastosować następującą funkcję skrótu:
To mnoży
x
przez 89, dodaje następny bajt (kod ASCII), a pozostałą zajmuje modulo 113. Czyni to na wszystkich bajtów ciągu wejściowego, z wyjątkiem ostatniej, więc npLATIN CAPITAL LETTER A
iLATIN CAPITAL LETTER X
podać ten sam kod skrótu.Ta funkcja skrótu nie powoduje kolizji, a dane wyjściowe mieszczą się w zakresie 0 ... 113 (na szczęście zakres jest jeszcze węższy: 3 ... 108).
Wartości skrótów wszystkich odpowiednich ciągów nie wypełniają tego miejsca całkowicie, więc postanowiłem użyć tego do skompresowania tabeli skrótów. Dodałem tabelę „pomiń” (112 bitów), która zawiera 0, jeśli odpowiednie miejsce w tablicy skrótów jest puste, i 1 w przeciwnym razie. Ta tabela przekształca wartość skrótu w „skompresowany” indeks, którego można użyć do rozwiązania gęstej LUT.
Ciągi znaków
LATIN CAPITAL LETTER
iLATIN SMALL LETTER
dają kody skrótu 52 i 26; są obsługiwane osobno. Oto kod C:Odpowiedni kod języka asemblera (składnia wbudowana w MS Visual Studio):
Kilka ważnych szczegółów implementacji:
CALL
instrukcji, aby uzyskać wskaźnik do kodu, w którym znajduje się tabela zakodowana na stałe. W trybie 64-bitowymrip
zamiast tego mógłby użyć rejestru .BT
instrukcji, aby uzyskać dostęp do tabeli pomijaniaeax
,ecx
,edx
, który może być niszczona - więc nie ma potrzeby, aby zapisać i przywrócić rejestrówal
iah
ostrożnie, aby w odpowiednim miejscuah
zmniejszyć do 0, a całyeax
rejestr można wykorzystać jako indeks LUTźródło
JavaScript ES6, 228
236 247 257 267 274 287Uwaga: zapisano 7 znaków przez thx @ ev3commander
Uwaga 2: lepszy niż JAPT po 7 głównych zmianach,
Uruchom fragment kodu, aby go przetestować
źródło
Japt , 230 bajtów
Każda
¿
reprezentuje niezadrukowany znak Unicode. Wypróbuj online!Nie golfowany:
To było naprawdę fajne. Podzieliłem nazwy postaci na kilka dużych części:
0. Weź pierwsze dwie litery
V=Us0,2;
ustawia zmiennąV
na dwie pierwsze literyU
ciągu wejściowego. Przyda się to później.1. Wielkie litery
Jest to najłatwiejsze: wielkie litery są jedynymi, które mają znak na pozycji 21, a wszystkie są poprawnymi literami i dużymi literami. Zatem
Ug21
wystarczy.2. Małe litery
Kolejny dość łatwy; jedyną inną nazwą, która ma znak na pozycji 19, jest
RIGHT SQUARE BRACKET
więc, więc sprawdzamy, czy nazwa jest wcześniejszaR
zU<'R
, a jeśli tak, to (&&
), bierzemy 19. znak zUg19
i rzucamy na małe literyv
.3. Cyfry
Wszystkie te nazwy zaczynają się od
DI
(i na szczęście nie ma innych), więc jeśliV=="DI"
możemy, możemy zamienić je na cyfrę. Pierwsze litery niektórych nazw cyfr są takie same, ale pierwsze dwie litery są wystarczające. Łącząc je w jeden ciąg, otrzymujemyZEONTWTHFOFISISEEINI
. Teraz możemy po prostu wziąć indeksb
pierwszych dwóch znaków w nazwie cyfryUs6,8)
i podzielić przez dwa.4
SIGN
Istnieje siedem nazw, które zawierają
SIGN
:Najpierw sprawdzamy, czy nazwa zawiera słowo
SIGN
. Okazuje się, żeGN
wystarczy;Uf"GN"
zwraca wszystkie wystąpieniaGN
w nazwie, czylinull
jeśli zawiera 0 wystąpień, a zatem zostaje pominięty.Teraz, używając tej samej techniki, co cyfry, łączymy pierwsze dwie litery w ciąg
LEGRPLEQDONUPE
, a następnie bierzemy indeks i dzielimy przez dwie. Wynika z tego liczba, z0-6
której możemy użyć, aby pobrać odpowiedni znak z ciągu<>+=$#%
.5
MARK
Istnieją trzy znaki, które zawierają
MARK
:Tutaj używamy tej samej techniki, co z
SIGN
.M
wystarczy odróżnić te trzy od pozostałych. Aby przetłumaczyć na symbol, tym razem wystarczy sprawdzić jedną literę: znak na pozycji 2 jest inny dla wszystkich trzech znaków. Oznacza to, że nie musimy dzielić przez dwa przy wyborze właściwej postaci.6.
LEFT/RIGHT
Grupa ta zawiera wsporniki i nawiasy
[]{}()
. Byłoby naprawdę skomplikowane, aby uchwycić zarównoLEFT
iRIGHT
, na szczęście, wszystkie one zawierają ciągT
. Sprawdzamy to za pomocą tej samej techniki, co mySIGN
. Aby przetłumaczyć na symbol, tak jak w przypadkuMARK
, wystarczy sprawdzić jedną literę; postać na pozycji 6 jest wyjątkowa dla wszystkich sześciu.7
CO
Reszta znaków jest dość wyjątkowa, ale niewystarczająco wyjątkowa. Trzy z nich zaczynają się
CO
:COMMA
,COLON
, iCOMMERCIAL AT
. Używamy dokładnie taką samą technikę jak my ze wspornikami, wybór właściwego symbolu na podstawie znaku w pozycji 4 (A
,N
lubE
).8. Wszystko inne
Do tej pory pierwsze dwa znaki są różne dla każdego imienia. Łączymy je wszystkie w jeden duży ciąg
SPAMAPASHYFUSORESETICIGRLOVE
i mapujemy każdą parę na odpowiadający jej znak&'*-./\;~^`_|
.9. Ostatnie kroki
Każda z części zwraca pusty ciąg lub
null
jeśli nie jest poprawny, więc możemy połączyć je wszystkie od lewej do prawej||
.||
Operator zwraca lewy argument jeśli to truthy i właściwej argumentacji inaczej. Japt ma również niejawne dane wyjściowe, więc bez względu na wynik jest automatycznie wysyłany do pola wyjściowego.Pytania, komentarze i sugestie mile widziane!
źródło
MARK
znakach.spamapashyfusoreseticigrlove
= Spam niechlujny za tak reset lodowatej miłości dziewczyny ... +1Python 2, 237 bajtów
Pobierz skrót łańcucha i podziel go modulo przez 535. Następnie przekonwertuj go na znak Unicode o tym numerze. Pozycja znaku Unicode na wstępnie skompilowanej liście znaków Unicode jest następnie konwertowana na znak ascii.
źródło
JavaScript,
501499469465451430 bajtówWyjaśnienie:
Ten długi ciąg jest skompresowaną listą.
a.length.toString(36)+a[0]+a.slice(-3)
określa, jak w ogóle łańcuch będzie reprezentowany na liście. Również specjalna logika dla liter. (przy okazji,a[0]
jest wbudowanym skrótema.charAt(0)
, nawiasem mówiąc,)źródło
_
się+
, można skompresować Base64 listę.btoa("abc")
do kompresji tekstu o 25% (o ile jest on ważny tekst base-64, które byłoby po wymianie_
z-
), a następnieatob("compressed stuff")
w rzeczywistym kodzie.PowerShell,
603547464 bajtów(
LineFeed
liczy ten sam bajt co;
, więc zostawię przerwy dla czytelności)Edycja 1 - Wyjęto wiele elementów z instrukcji switch i zamiast tego wypełniłem tabelę skrótów dla odnośników.
Edycja 2 - O tak ... indeksowanie w ciąg znaków, to jest droga ...
Zasadniczo pobiera dane wejściowe, dzieli je na spacje i wykonuje znak wieloznaczny
switch
przy pierwszym słowie, aby odfiltrować głupie. Ustawia wynik tego na$b
. Jeśli$b
nie istnieje, łańcuch$c
jest oceniany na pierwszych trzech literach pierwszego słowa i wypisuje znak bezpośrednio po nim, w przeciwnym razie wypisujemy$b
.Niektóre sztuczki obejmują
LATIN CAPITAL LETTER R
indeksowanie do tablicy w zależności od tego, czy drugim słowem jestCAPITAL
, i generowanie odpowiednich wielkich / małych liter. Druga „sztuczka” dotyczyDIGIT
s, poprzez indeksowanie do tablicy mieszającej. Zauważ, że wykonanie tej samej sztuczki polegającej na indeksowaniu w ciąg znaków nie jest krótsze (w rzeczywistości jest dłuższe o jeden bajt).źródło
JavaScript,
416411389 bajtówTo jest bardziej czytelny format (wyjaśnienie w dalszej części):
Minus 5 bajtów od połączenia ciągów klucza i wartości.
Objaśnienie: Wyrażenia regularne w pierwszym wierszu redukują dane wejściowe do unikalnych 4-znakowych klawiszy. Pamiętaj, że unikalność jest gwarantowana tylko dla określonego zestawu nazw określonych w wyzwaniu, a duplikaty byłyby bardzo powszechne w normalnym języku angielskim! Nawet w przypadku tego wyzwania musiałem usunąć typowe słowa, takie jak nawias kwadratowy i znak, aby uzyskać unikalny zestaw.
Aby zwrócić znak, sprawdzam, czy jest to znak łaciński, sprawdzając ciągi znaków „SER” i „cer”, i zwracam ostatni znak wejściowy małymi literami dla ser.
W pozostałym zakresie odnoszę się do ciągu zawierającego wszystkie 4-znakowe klucze, po których następuje poprawny znak. Następnie używam indexof i
podciągówindeksów znaków, aby pobrać i zwrócić znak.Edycja: Użyłem więcej symboli wieloznacznych, aby zmniejszyć rozmiar wyrażenia regularnego, zastąpiłem substrat indeksami znaków i ogoliłem jeszcze dwadzieścia znaków. Zwolennicy reguł zauważą, że ta ostatnia aktualizacja zostanie opublikowana po zakończeniu wyzwania, ale nie sądzę, żeby zmieniła mój ranking. To tylko praktyka dla początkującego.
źródło
Python 3, 148 bajtów
Dla wygody przeglądania zastąpiłem dwa bajty niedrukowalne ósemkowymi kodami ucieczki
\32
i\34
; cofnij to, aby uzyskać funkcję 148 bajtów.Obliczyłem części tej funkcji skrótu za pomocą GPerf .
źródło
Perl 6 ,
348242 bajtówstosowanie:
źródło