Nama karakter Latin dasar ke karakter

23

Mari kembali ke dasar!

  • Kode Anda, program atau fungsi yang lengkap, harus mengubah nama Unicode resmi dari karakter Latin Dasar yang dapat dicetak menjadi karakter yang sesuai. Misalnya, untuk input, LOW LINEkode Anda harus ditampilkan _.
  • Anda hanya perlu menggunakan satu nama karakter sebagai input.
  • Anda tidak dapat menggunakan fungsi atau pustaka yang sudah ada sebelumnya, built-in atau sebaliknya, yang menawarkan logika apa pun yang berkaitan khusus dengan nama karakter Unicode (misalnya Python unicodedata, Java Character.getName, dan sebagainya.)
  • Untuk masukan selain dari salah satu nama ini, perilaku apa pun dapat diterima.

Ini adalah kode golf: kode terpendek dalam byte menang.

Untuk menghindari ambiguitas, ini adalah set lengkap nama karakter resmi yang akan kami gunakan (dipinjam dari pertanyaan ini ):

     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
sumber
2
Apakah program hanya perlu menangani satu nama karakter? Misalnya, haruskah COLON COLONmenghasilkan ::, atau perilaku yang tidak jelas?
Kevin W.
Diedit untuk memperjelas.
Lukas
Kenapa String.fromCharCodedilarang?
SuperJedi224
Ups, saya salah mengerti apa fungsi itu.
Lukas
Bagaimana kita harus menangani input yang tidak valid CLON?
edc65

Jawaban:

25

Kode mesin IA-32, 161 160 122 byte

Hexdump kode:

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

Kode ini menggunakan beberapa hashing. Dengan beberapa pencarian brute-force, saya menemukan bahwa fungsi hash berikut dapat diterapkan ke byte dari string input:

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

Ini dikalikan xdengan 89, menambahkan byte berikutnya (kode ASCII), dan mengambil modulo 113 sisanya. Ia melakukan ini pada semua byte dari string input kecuali yang terakhir, jadi mis. LATIN CAPITAL LETTER ADan LATIN CAPITAL LETTER Xmemberikan kode hash yang sama.

Fungsi hash ini tidak memiliki tabrakan, dan output di kisaran 0 ... 113 (sebenarnya, untungnya, kisarannya bahkan lebih sempit: 3 ... 108).

Nilai hash dari semua string yang relevan tidak mengisi ruang itu sepenuhnya, jadi saya memutuskan untuk menggunakan ini untuk mengompres tabel hash. Saya menambahkan tabel "lewati" (112 bit), yang berisi 0 jika tempat yang sesuai di tabel hash kosong, dan 1 sebaliknya. Tabel ini mengubah nilai hash menjadi indeks "terkompresi", yang dapat digunakan untuk mengatasi LUT padat.

String LATIN CAPITAL LETTERdan LATIN SMALL LETTERmemberikan kode hash 52 dan 26; mereka ditangani secara terpisah. Berikut adalah kode C untuk itu:

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

Kode bahasa assembly yang sesuai (sintaksis MS-Visual Studio inline-assembly):

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

Beberapa detail implementasi yang patut diperhatikan:

  • Ini menggunakan CALLinstruksi untuk mendapatkan pointer ke kode, di mana tabel hard-kode berada. Dalam mode 64-bit, ia bisa menggunakan register rip.
  • Ini menggunakan BTinstruksi untuk mengakses tabel lewati
  • Itu berhasil melakukan pekerjaan dengan hanya menggunakan 3 register eax, ecx, edx, yang dapat musnah - sehingga tidak perlu untuk menyimpan dan mengembalikan register
  • Saat mendekode tabel hash, ia menggunakan aldan ahhati - hati, sehingga di tempat yang tepat ahdikurangi menjadi 0, dan seluruh eaxregister dapat digunakan sebagai indeks LUT
anatolyg
sumber
18

JavaScript ES6, 228 236 247 257 267 274 287

Catatan: 7 karakter disimpan thx @ ev3commander

Catatan 2: lebih baik daripada JAPT setelah 7 suntingan utama,

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

Jalankan cuplikan untuk menguji

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
sumber
5
Cuma ... bagaimana? Sudah selesai dilakukan dengan baik.
SuperJedi224
Sebenarnya, selain alfabet, tidak ada char yang dimulai dengan "LA"
ev3commander
@ ev3commander ya, tapi di sini saya mengelola LAT, RIG dan LEF dan 2 karakter sepertinya terlalu sedikit, memiliki KIRI dan KURANG
edc65
Ohh Saya hanya membaca sekilas dan tidak melihat bagian RIG / LEF.
ev3commander
@ ev3commander berpikir kedua Anda ada benarnya! Saya dapat menggabungkan penanganan KURANG dan KIRI dan menyimpan 4 byte. Thx
edc65
10

Japt , 230 byte

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

Masing-masing ¿mewakili karakter Unicode yang tidak dapat dicetak. Cobalah online!

Tidak Disatukan:

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

Ini sangat menyenangkan. Saya telah membagi nama karakter menjadi beberapa bagian besar:

0. Ambil dua huruf pertama

V=Us0,2;set variabel Vke dua huruf pertama U, string input. Ini akan berguna nanti.

1. Huruf kapital

Ini adalah yang termudah: huruf kapital adalah satu-satunya yang memiliki karakter pada posisi 21, yang semuanya merupakan huruf dan huruf yang benar. Dengan demikian, Ug21sudah cukup.

2. Huruf kecil

Satu lagi yang cukup mudah; satu-satunya nama lain yang memiliki karakter pada posisi 19 adalah RIGHT SQUARE BRACKET, jadi kami memeriksa apakah nama adalah datang sebelum Rdengan U<'R, maka jika ( &&), kita mengambil char ke-19 dengan Ug19dan melemparkannya ke huruf kecil dengan v.

3. Digit

Semua nama ini dimulai dengan DI(dan untungnya, tidak ada yang lain), jadi jika V=="DI", kita bisa mengubahnya menjadi digit. Huruf pertama dari beberapa nama digit adalah sama, tetapi dua huruf pertama sudah cukup. Menggabungkan ini menjadi satu string, kita dapatkan ZEONTWTHFOFISISEEINI. Sekarang kita bisa mengambil indeks bdari dua karakter pertama dalam nama digit dengan Us6,8)dan membaginya dengan dua.

4. SIGN

Ada tujuh nama yang mengandung SIGN:

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

Pertama kita periksa apakah namanya mengandung kata SIGN. Ternyata GNcukup; Uf"GN"mengembalikan semua instance GNdalam nama, yang nulljika mengandung 0 instance, dan karenanya dilewati.

Sekarang, menggunakan teknik yang sama dengan digit, kita menggabungkan dua huruf pertama menjadi string LEGRPLEQDONUPE, lalu ambil indeks dan bagi dengan dua. Ini menghasilkan angka dari 0-6, yang dapat kita gunakan untuk mengambil karakter yang sesuai dari string <>+=$#%.

5. MARK

Ada tiga karakter yang mengandung MARK:

!    EXCLAMATION MARK
"    QUOTATION MARK
?    QUESTION MARK

Di sini kita menggunakan teknik yang sama dengan SIGN.  Mcukup untuk membedakan ketiga ini dari yang lain. Untuk menerjemahkan ke simbol, kali ini memeriksa satu huruf sudah cukup: karakter di posisi 2 berbeda untuk ketiga karakter. Ini berarti kita tidak perlu membaginya dengan dua ketika memilih karakter yang benar.

6. LEFT/RIGHT

Grup ini berisi tanda kurung dan tanda kurung []{}(),. Akan sangat rumit untuk menangkap keduanya LEFTdan RIGHT, tetapi untungnya, mereka semua mengandung string . Kami memeriksa ini dengan teknik yang sama seperti yang kami lakukan dengan SIGN. Untuk menerjemahkan simbol, cukup dengan MARKmemeriksa satu huruf saja; karakter pada posisi 6 adalah unik untuk keenamnya.

7. CO

Karakter lainnya cukup unik, tetapi tidak cukup unik. Tiga dari mereka mulai dengan CO: COMMA, COLON, dan COMMERCIAL AT. Kami menggunakan persis teknik yang sama seperti yang kita lakukan dengan kurung, memilih simbol yang tepat berdasarkan karakter pada posisi 4 ( A, N, atau E).

8. Yang lainnya

Sekarang, dua karakter pertama berbeda untuk setiap nama. Kami menggabungkan semuanya menjadi satu string besar SPAMAPASHYFUSORESETICIGRLOVEdan memetakan setiap pasangan ke karakter terkait  &'*-./\;~^`_|.

9. Langkah terakhir

Masing-masing bagian mengembalikan string kosong atau nulljika itu bukan yang benar, sehingga kami dapat menautkannya dari kiri ke kanan ||. The ||Operator mengembalikan argumen kiri jika truthy itu, dan argumen yang tepat sebaliknya. Japt juga memiliki output implisit, jadi apa pun hasilnya, secara otomatis dikirim ke kotak output.

Selamat datang pertanyaan, komentar, dan saran!

Produksi ETH
sumber
Jawaban yang bagus dan penjelasan yang bagus. Tetapi Anda lupa menyebutkan penanganan atau MARK (!? ") Dalam penjelasannya
edc65
@ edc65 Whoops, terima kasih! Saya telah menambahkan di bagian tentang MARKkarakter.
ETHproduk
7
spamapashyfusoreseticigrlove= Spam a pashy untuk jadi setel ulang cinta gadis es ... +1
AdmBorkBork
Tidak, itu masih banyak golf.
Blacklight Shining
3

Python 2, 237 byte

Dapatkan hash dari string dan modulo membaginya dengan 535. Selanjutnya mengubahnya menjadi karakter unicode dengan nomor itu. Posisi karakter unicode dalam daftar karakter unicode yang dikompilasi kemudian dikonversi ke karakter ascii.

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

Javascript, 501 499 469 465 451 430 byte

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

Penjelasan:

String panjang itu adalah daftar terkompresi. a.length.toString(36)+a[0]+a.slice(-3)menentukan bagaimana, jika sama sekali, string akan diwakili dalam daftar. Juga, logika khusus untuk surat. (dengan string, a[0]adalah singkatan untuk a.charAt(0), omong-omong)

SuperJedi224
sumber
Jika Anda diganti _dengan +, Anda dapat memadatkan daftar Base64.
ETHproduksi
@ ETHproductions base64 membuat segalanya lebih panjang , bukan lebih pendek.
Blacklight Shining
@ ETHproductions Apakah Javascript memiliki Base64?
SuperJedi224
@ SuperJedi224 Ya, tapi Blacklight benar kecuali basis 64 mengganti nomor yang bisa dinyatakan dalam basis lebih rendah, terutama biner.
wedstrom
Anda dapat menggunakan btoa("abc")untuk mengompresi teks sebesar 25% (selama itu adalah teks dasar-64 yang valid, yang akan setelah diganti _dengan -), kemudian atob("compressed stuff")dalam kode Anda yang sebenarnya.
ETHproduk
1

PowerShell, 603 547 464 byte

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

( LineFeedmenghitung byte yang sama dengan ;, jadi saya akan meninggalkan jeda untuk dibaca)

Sunting 1 - Mengambil banyak elemen dari pernyataan sakelar dan malah mengisi hashtable untuk pencarian.

Sunting 2 - Oh yeah ... pengindeksan menjadi string, itulah cara untuk pergi ...

Pada dasarnya mengambil input, membaginya pada spasi, dan melakukan wildcard switchpada kata pertama untuk menyaring yang konyol. Tetapkan hasil itu menjadi $b. Jika $btidak ada, string $cakan dievaluasi pada tiga huruf pertama dari kata pertama dan menampilkan karakter segera berikut, jika tidak kita output $b.

Beberapa trik termasuk LATIN CAPITAL LETTER Ryang mengindeks ke dalam array berdasarkan pada apakah kata kedua adalah CAPITAL, dan mengeluarkan huruf besar / huruf kecil yang sesuai. "Trik" lainnya adalah untuk DIGITs, dengan mengindeks ke dalam hashtable. Perhatikan bahwa tidak pendek untuk melakukan trik index-into-a-string yang sama di sini (sebenarnya lebih lama satu byte).

AdmBorkBork
sumber
Aku memukulmu lagi.
SuperJedi224
1

Javascript, 416 411 389 byte

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

Ini adalah format yang lebih mudah dibaca (penjelasan datang kemudian):

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

Mengurangi 5 byte dari penggabungan kunci dan nilai string.

Penjelasan: Ekspresi reguler pada baris pertama mengurangi input menjadi kunci karakter 4 yang unik. Perhatikan bahwa keunikan hanya dijamin untuk set nama tertentu yang ditentukan dalam tantangan, dan duplikat akan sangat umum untuk bahasa Inggris normal! Bahkan untuk tantangan ini, saya harus menghapus kata-kata umum seperti tanda kurung dan masuk untuk mendapatkan set yang unik.

Untuk mengembalikan karakter, saya memeriksa untuk melihat apakah itu karakter latin dengan memeriksa string "SER" dan "cer", dan mengembalikan karakter terakhir dari input, dalam huruf kecil untuk ser.

Untuk yang lainnya, saya merujuk ke string yang berisi semua kunci 4 karakter, diikuti oleh karakter yang benar. Saya kemudian menggunakan indeks karakter indexof dan substring untuk menarik dan mengembalikan karakter.

Sunting: Menggunakan lebih banyak wildcard untuk mengurangi ukuran regex, mengganti substrat dengan indeks karakter dan mencukur lebih dari dua puluh karakter. Stickler aturan akan mencatat bahwa pembaruan terakhir ini diposting setelah tantangan telah berakhir, namun saya tidak berpikir itu mengubah peringkat saya. Ini hanya latihan untuk pemula.

kamar tidur
sumber
1

Python 3, 148 byte

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

Untuk kenyamanan menonton Anda, saya telah mengganti dua byte yang tidak dapat dicetak dengan kode pelepasan oktal \32dan \34; batalkan ini untuk mendapatkan fungsi 148 byte.

Saya menghitung bagian dari fungsi hash ini dengan GPerf .

Anders Kaseorg
sumber
0

Perl 6 ,  348   242 byte

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

pemakaian:

my &code = {...}

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

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