26 Penyanyi, 26 Surat

34

Menurut RollingStone , di bawah ini adalah 26 penyanyi terhebat sepanjang masa:

Aretha Franklin         Al Green
Ray Charles             Robert Plant
Elvis Presley           Mick Jagger
Sam Cooke               Tina Turner
John Lennon             Freddie Mercury
Marvin Gaye             Bob Marley
Bob Dylan               Smokey Robinson
Otis Redding            Johnny Cash
Stevie Wonder           Etta James
James Brown             David Bowie
Paul McCartney          Van Morrison
Little Richard          Michael Jackson
Roy Orbison             Jackie Wilson

Anda bisa mendapatkan ini sebagai daftar string di sini .

Tugas

Mengingat nama penyanyi, mencetak atau kembali surat dari Ake Zmana unik mengidentifikasi penyanyi ini. (Jika kode Anda mengembalikan A untuk Bob Dylan , maka tidak dapat mengembalikan A untuk penyanyi lain.)

Berbeda dengan tantangan serupa lainnya, pemetaan terserah Anda selama bebas dari benturan.

Aturan

  • Masukan tersebut dijamin menjadi salah satu dari 26 nama penyanyi yang tercantum di atas dengan ejaan yang tepat ini dan tanpa spasi putih terkemuka atau tertinggal.
  • Anda dapat menampilkan huruf dalam huruf kecil atau besar. Tetapi harus konsisten.
  • Anda disarankan untuk memberikan suite uji untuk semua 26 input yang mungkin.
  • Ini , jadi jawaban tersingkat dalam byte menang!
Arnauld
sumber
17
Rolling Stone yang terhormat: Bob Dylan benar-benar salah satu musisi terhebat yang pernah ada. Tapi penyanyi yang hebat ?
Luis Mendo
@LuisMendo Saya agak asin tentang beberapa pilihan ini juga ( batuk batuk di mana Steve Tyler batuk )
Lord Farquaad
@LordFarquaad Steve Tyler adalah # 99 ¯ \ _ (ツ) _ / ¯
Arnauld
ini dapat membantu seseorang tetapi saya tidak memiliki keterampilan CG untuk menggunakan info: 1-6, 1-8, dan 3-5 huruf dari nama-nama itu adalah kombinasi unik.
Jeutnarg

Jawaban:

2

MATL , 28 byte

s98\40\2Y2'ijkl o qst uz'hw)

Cobalah online!

Penjelasan

s98\40\

Secara implisit mendapatkan string input. Jumlah karakter dari string input, dan lakukan modulus 98 diikuti oleh modulus 40. Hasil dalam salah satu angka berikut: 38 18 13 34 29 23 27 30 5 28 22 1 0 16 7 32 8 14 3 36 25 4 2 6 24 35 (dalam urutan daftar Pastebin).

2Y2'ijkl o qst uz'h

Tekan alfabet (huruf kecil) dengan 2Y2. Ini menangani angka dalam kisaran [1,26]. Namun, beberapa angka hilang, dan kami memiliki angka hingga 38. Karenanya, kami menambahkan ( h) string yang menangani angka yang lebih tinggi, dengan memetakan angka-angka ini ke huruf 'hilang'. Ruang bisa apa saja, saya menggunakan huruf kapital dalam program asli saya untuk kenyamanan saya sendiri.

w)

Kita sekarang dapat mengindeks nomor dari langkah pertama ke dalam string dari langkah kedua dengan ). Kami menggunakan wuntuk mendapatkan argumen dalam urutan yang benar. Meskipun tampaknya kita menggunakan pengindeksan berbasis 0 (jumlahnya bervariasi dari 0 hingga 38, dan string sepanjang 39 karakter), kenyataannya sebenarnya sedikit lebih rumit: kita menggunakan pengindeksan modular berbasis 1, fitur yang unik untuk MATL. Ini berarti bahwa 1indeks ke a, 38sebenarnya indeks ke u, dan 0indeks ke akhir zstring.

Sanchises
sumber
23

Python 2 , 80 71 byte

def f(s):i=sum(map(ord,s))%98%40;return chr(i-i/26*18+i/32*3-i/37*8+65)

Cobalah online!

Jumlah ordinals yang diubah memberi angka antara 0dan38

Angka-angka yang lebih besar dari 25 kemudian digeser untuk mengisi kekosongan seperti di bawah ini (urutan diurutkan ditampilkan):

  0  1  2  3  4  5  6  7  8  -  -  -  - 13 14  - 16  - 18  -  -  - 22 23 24 25  - 27 28 29 30  - 32  - 34 35 36  - 38

Kurangi 18jika i>25:

  0  1  2  3  4  5  6  7  8  -  -  -  - 13 14  - 16  - 18  -  -  - 22 23 24 25
                          - 27 28 29 30  - 32  - 34 35 36  - 38

Tambahkan 3jika i>31:

  0  1  2  3  4  5  6  7  8  -  -  -  - 13 14  - 16  - 18  -  -  - 22 23 24 25
                          - 27 28 29 30  
                                                  - 32  - 34 35 36  - 38

Kurangi 8jika i>37:

  0  1  2  3  4  5  6  7  8  -  -  -  - 13 14  - 16  - 18  -  -  - 22 23 24 25
                          - 27 28 29 30  
                                                  - 32  - 34 35 36  
                                            - 38

Yang memberi urutan 0..25

  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

Ini kemudian dikonversi ke A-Zdenganchr(i+65)

TFeld
sumber
Saya pikir Anda dapat mempersingkat (i>31)untuk i/32, dll
xnor
21

6502 rutin kode mesin (C64), 83 byte

20 FD AE 20 9E AD 85 FC 20 A3 B6 A9 79 85 FB A0 00 84 FD B1 22 10 03 69 A0 18
45 FD 65 FB 85 FD E6 FB C8 C4 FC D0 EC E9 29 B0 FC 69 29 C9 1A 90 1C 29 0F C9
0D 90 04 69 09 90 12 C9 02 F0 0F C9 08 D0 04 A9 06 D0 06 C9 0C D0 02 A9 11 18
69 41 4C D2 FF

Ini adalah kode posisi-independen, taruh saja di suatu tempat di RAM dan lompat ke sana, misalnya menggunakan sysperintah.

Demo online (memuat ke$C000/49152).

Penggunaan:, sys49152,"[name]" mis sys49152,"Aretha Franklin".

Penting: Jika program dimuat dari disk (seperti di demo online), keluarkan newperintah terlebih dahulu! Ini diperlukan karena memuat program mesin menghancurkan beberapa pointer BASIC C64.

Catatan: C64 secara default dalam mode tanpa huruf kecil - untuk dapat memasukkan nama yang dapat dibaca , beralih ke mode huruf kecil terlebih dahulu dengan menekan SHIFT+ CBM.


Penjelasan

Tantangannya adalah menemukan fungsi hash minimal yang sempurna untuk nama-nama ini; untuk C64, saya harus menemukan satu yang mudah dihitung dalam operasi 8bit sederhana. Berikut daftar pembongkaran yang dikomentari:

.C:c000  20 FD AE    JSR $AEFD          ; consume comma
.C:c003  20 9E AD    JSR $AD9E          ; evaluate expression
.C:c006  85 FC       STA $FC            ; save string length
.C:c008  20 A3 B6    JSR $B6A3          ; free string
.C:c00b  A9 79       LDA #$79           ; value for adding during hashing
.C:c00d  85 FB       STA $FB
.C:c00f  A0 00       LDY #$00           ; offset for reading string
.C:c011  84 FD       STY $FD            ; and initial hash value
.C:c013   .hashloop:
.C:c013  B1 22       LDA ($22),Y        ; read next character from string
.C:c015  10 03       BPL .xor           ; if bit 8 set (shifted)
.C:c017  69 A0       ADC #$A0           ; translate to same unshifted character
.C:c019  18          CLC
.C:c01a   .xor:
.C:c01a  45 FD       EOR $FD            ; xor with previous hash
.C:c01c  65 FB       ADC $FB            ; add offset
.C:c01e  85 FD       STA $FD            ; store new hash
.C:c020  E6 FB       INC $FB            ; increment offset
.C:c022  C8          INY
.C:c023  C4 FC       CPY $FC
.C:c025  D0 EC       BNE .hashloop      ; repeat until last character
.C:c027   .modloop:
.C:c027  E9 29       SBC #$29           ; subtract $29 until
.C:c029  B0 FC       BCS .modloop       ; underflow, then
.C:c02b  69 29       ADC #$29           ; add once again ( => mod $29)
.C:c02d  C9 1A       CMP #$1A           ; value in hash range?
.C:c02f  90 1C       BCC .tochar        ; -> output
.C:c031  29 0F       AND #$0F           ; mask lowest 4 bits only
.C:c033  C9 0D       CMP #$0D           ; greater 12 ?
.C:c035  90 04       BCC .fixedvals     
.C:c037  69 09       ADC #$09           ; then just add 10 (9 plus carry)
.C:c039  90 12       BCC .tochar        ; and done -> output
.C:c03b   .fixedvals:
.C:c03b  C9 02       CMP #$02           ; 2 becomes 3 by adding
.C:c03d  F0 0F       BEQ .tochar2       ; with carry (jump after the CLC)
.C:c03f  C9 08       CMP #$08           ; if value was 8
.C:c041  D0 04       BNE .check2
.C:c043  A9 06       LDA #$06           ; new value is 6
.C:c045  D0 06       BNE .tochar        ; and output
.C:c046   .check2:
.C:c047  C9 0C       CMP #$0C           ; else if value was 12
.C:c049  D0 02       BNE .tochar
.C:c04b  A9 11       LDA #$11           ; new value is 17
.C:c04d   .tochar:
.C:c04d  18          CLC
.C:c04d   .tochar2:
.C:c04e  69 41       ADC #$41           ; add character code for 'a'
.C:c050  4C D2 FF    JMP $FFD2          ; jump to kernal CHROUT routine

Test suite (C64 BASIC, berisi kode mesin rutin dalam databarisan)

0fOa=49152to49234:rEb:pOa,b:nE:pO53272,23
1sY49152,"Aretha Franklin":?":Aretha Franklin"
2sY49152,"Ray Charles":?":Ray Charles"
3sY49152,"Elvis Presley":?":Elvis Presley"
4sY49152,"Sam Cooke":?":Sam Cooke"
5sY49152,"John Lennon":?":John Lennon"
6sY49152,"Marvin Gaye":?":Marvin Gaye"
7sY49152,"Bob Dylan":?":Bob Dylan"
8sY49152,"Otis Redding":?":Otis Redding"
9sY49152,"Stevie Wonder":?":Stevie Wonder"
10sY49152,"James Brown":?":James Brown"
11sY49152,"Paul McCartney":?":Paul McCartney"
12sY49152,"Little Richard":?":Little Richard"
13sY49152,"Roy Orbison":?":Roy Orbison"
14sY49152,"Al Green":?":Al Green"
15sY49152,"Robert Plant":?":Robert Plant"
16sY49152,"Mick Jagger":?":Mick Jagger"
17sY49152,"Tina Turner":?":Tina Turner"
18sY49152,"Freddie Mercury":?":Freddie Mercury"
19sY49152,"Bob Marley":?":Bob Marley"
20sY49152,"Smokey Robinson":?":Smokey Robinson"
21sY49152,"Johnny Cash":?":Johnny Cash"
22sY49152,"Etta James":?":Etta James"
23sY49152,"David Bowie":?":David Bowie"
24sY49152,"Van Morrison":?":Van Morrison"
25sY49152,"Michael Jackson":?":Michael Jackson"
26sY49152,"Jackie Wilson":?":Jackie Wilson"
27dA32,253,174,32,158,173,133,252,32,163,182,169,121,133,251,160,0,132,253,177
28dA34,16,3,105,160,24,69,253,101,251,133,253,230,251,200,196,252,208,236,233
29dA41,176,252,105,41,201,26,144,28,41,15,201,13,144,4,105,9,144,18,201,2,240
30dA15,201,8,208,4,169,6,208,6,201,12,208,2,169,17,24,105,65,76,210,255

Demo online test suite .

Felix Palmen
sumber
13

Python 2 , 68 byte

def f(n):i=hash(n)%337%125%45;return chr(65+i-i/25*2-i/29*21+i/35*2)

Cobalah online!

ovs
sumber
1
menarik untuk mengetahui bagaimana Anda menulis ini
Sarge Borsch
2
@SargeBorsch hash (n) menghitung integer unik untuk setiap nama. Operasi modulo masih membuat int tersebut unik, tetapi menurunkan nilainya. Bagian kedua ( chr(65+i-i/25*2-i/29*21+i/35*2)) mirip dengan jawaban TFelds . Operasi modulo dilakukan dengan skrip yang sudah saya gunakan di sini dan di sini .
Ovs
10

Javascript, 138 132 karakter

Karena semua inisial unik, kecuali untuk MJ= M ichael J ackson / M ick J agger, saya memeriksa Michael Jackson secara khusus (satu-satunya dengan hposisi 4), dan untuk semua nama lain saya membuat string dengan inisial diikuti oleh surat yang unik.

s=>s[3]=='h'?'y':"AFaRCbEPcSCdJLeMGfBDgORhSWiJBjPMCkLRlROmAGnRPoMJpTTqFMrBMsSRtJCuEJvDBwVMxJWz".split(s.replace(/[^A-Z]/g,''))[1][0]

Cuplikan Kode

Coba di sini:

var solution =
s=>s[3]=='h'?'y':"AFaRCbEPcSCdJLeMGfBDgORhSWiJBjPMCkLRlROmAGnRPoMJpTTqFMrBMsSRtJCuEJvDBwVMxJWz".split(s.replace(/[^A-Z]/g,''))[1][0]

var testnames = [
"Aretha Franklin",
"Ray Charles",
"Elvis Presley",
"Sam Cooke",
"John Lennon",
"Marvin Gaye",
"Bob Dylan",
"Otis Redding",
"Stevie Wonder",
"James Brown",
"Paul McCartney",
"Little Richard",
"Roy Orbison",
"Al Green",
"Robert Plant",
"Mick Jagger",
"Tina Turner",
"Freddie Mercury",
"Bob Marley",
"Smokey Robinson",
"Johnny Cash",
"Etta James",
"David Bowie",
"Van Morrison",
"Michael Jackson",
"Jackie Wilson"
];
testnames.forEach(name=>document.body.append( solution(name) ));

nl-x
sumber
Mungkin ada fungsi hashing yang lebih pendek, tapi saya suka ide mencoba sesuatu yang mungkin dilakukan manusia. Namun, saya berharap Anda akan menggunakan fitur potongan kode alih-alih menautkan ke JSFiddle.
trlkly
@ CtrlKly saya menggunakan fitur snipet kode sekarang.
nl-x
7

Java (OpenJDK 8) , 128 126 115 113 byte

Tidak terlalu buruk untuk pengiriman java!

Terima kasih kepada Kevin karena telah menyelamatkan saya banyak byte dengan ekspresi lambda!

s->{int a=0;for(int i:s.substring(1,6).getBytes())a+=i;a*=a==431?0.108:2.65108;return(char)(a==1341?70:a%26+65);}

Cobalah online!

Luke Stevens
sumber
1
Jawaban yang bagus, +1 dari saya. Saya saat ini juga sedang mengerjakan solusi Java dengan membuat skrip .. Namun tidak beruntung sejauh ini. Btw, Anda dapat bermain golf dua byte dengan mengubah {a+=i;}kea+=i;
Kevin Cruijssen
1
@KevinCruijssen Cheers, tidak percaya saya melewatkan itu! Saya menulis sebuah skrip untuk mencoba dan menemukan 'angka ajaib' yang akan memberi saya nilai-nilai unik antara 0 dan 25 tetapi yang terbaik yang bisa saya lakukan adalah 24, maka pernyataan if pada akhirnya.
Luke Stevens
1
Hmm btw, karena Anda menggunakan Java 8, Anda juga dapat golf char g(String s)ke s->. Saya telah memodifikasi TIO Anda untuk menunjukkan bagaimana melakukan ini, jika Anda hanya terbiasa dengan metode Java 7.
Kevin Cruijssen
Terima kasih, saya tidak pernah menyadari Anda bisa melakukan itu, saya akan memperbarui kiriman saya (lagi!)
Luke Stevens
Hahaha, Anda dapat mengatakan saya baru dalam hal ini
Luke Stevens
5

Python 3, 132 99 96 byte

lambda m:chr(98+"ԇ̲ЙГ̫ѼӿИԸՋжʾҍϴЬֺΝעЕΞϾҞ֜ӣ֪".find(chr(sum(map(ord,m)))))

Cobalah online!

Tidak bermain golf dengan cemerlang, tetapi saya pikir saya akan mencobanya.

-33 byte berkat modifikasi yang dilakukan oleh TFeld.
-3 byte dengan menggunakan findbukan indexberkat ovs.

Lirik
sumber
Anda dapat menyimpan 6 byte dengan menggunakan sum(map(ord,m)), saya juga menambahkan Aretha Franklin untuk 128 byte
TFeld
Dan Anda dapat menggunakan chr(97+...)sebagai gantinya ascii_lowercase: 99 byte
TFeld
1
Bagaimana dengan penjelasannya?
Matsemann
3
Penjelasan: sum(map(ord,m))menjumlahkan nilai ASCII dari karakter dalam string m(memberikan bilangan bulat dalam kisaran 702–1506). Kemudian memanggilnya chrmengkonversinya menjadi karakter (Unicode) dengan nomor itu: chr(702)adalah ʾ ke chr(1506) = עdan banyak di antaranya. Solusi ini hanya mencari karakter ini di daftar semua kemungkinan (26) karakter tersebut untuk mendapatkan indeks (0-26), lalu mengembalikan karakter dengan kode ASCII 97 + indeks itu (jadi 'a' ke 'z').
ShreevatsaR
1
Solusi Anda saat ini masih berisi versi 99 byte. Anda bermaksud menggunakan versi OVS?
nl-x
5

PHP, 90 88 86 72 + 1 byte

mungkin menjadi lebih pendek dengan modulo yang berbeda.

<?=strtr(chr(hexdec(substr(md5($argn),0,2))%65+58),"^<adins",bcfgqvx)&_;

Simpan ke file dan jalankan sebagai pipa dengan -nFatau coba online .

Titus
sumber
2
Aretha Franklin dan Paul McCartney sama-sama membuat output Wpada kasus uji Anda, dan tidak ada Xoutput. Tidak tahu apakah ini kesalahan kode itu sendiri atau coba saja konversi daring :)
crazyloonybin
1
Kesalahan ketik pengganti @crazyloonybin diperbaiki. Terima kasih telah mengisyaratkan.
Titus
Jadi bagaimana saya menjalankan ini? Kode 'coba online' Anda tidak menggunakan <?=bagian itu. Dan 'Jalankan sebagai pipa' saya tidak mulai bekerja. Juga, saya mendapat pemberitahuan ketika mencoba menjalankannya dari baris perintah.
nl-x
@Itus: Di CodeGolf Anda harus memberikan fungsi atau aplikasi lengkap yang menghasilkan (hanya) output yang diinginkan. Saya kenal <?=... Jadi pertanyaan saya adalah, bagaimana saya menjalankan kode Anda (dari baris perintah)? Saya gagal memberi makan $argndi baris perintah ... Semua upaya saya sejauh ini baik memberikan artefak, dan tampaknya masih membutuhkan lebih banyak kode untuk menjalankannya.
nl-x
@ nl-x PHP Anda menghasilkan pemberitahuan, itu karena Anda tidak memberikannya opsi n:echo <input> | php -nF <scriptfilename>
Titus
4

Perl, 56 , 54 , 50 , 46 +1 (-p) byte

$ = crypt $ , DT; / .. (.) /; $ _ = $ 1; y / 01268ADIJNVW / adhilmnpqsux /

$ = crypt $ , DT; / .. (.) /; $ = $ 1; y / 01268JVW / hlmpqsux /; $ = lc

$ = crypt $ , mO; / .. (.) /; $ = $ 1; y / 035eft / AHPRXZ /; $ = lc

Berkat komentar Dom dapat menghemat 4 byte lebih banyak, juga diubah menjadi huruf besar agar sesuai dengan permintaan yang lebih baik.

$_=crypt$_,mO;y/035eft/AHPRXZ/;/..(.)/;$_=uc$1

Cobalah secara Online

Nahuel Fouilleul
sumber
Pendekatan yang bagus! Saya pikir Anda perlu menulis / mencetak seluruh fungsi yang bisa dipanggil?
Felix Palmen
@FelixPalmen, ini adalah program perl yang dapat disebut inline: perl -pe '$_=crypt$_,mO;/..(.)/;$_=$1;y/035eft/AHPRXZ/;$_=lc'menambahkan tautan ke tio
Nahuel Fouilleul
Bagus! Sedang mencari pendekatan yang serupa, menggunakan $1^$2tetapi tidak berpikir untuk menggunakan crypt... Anda dapat menyimpan 4 byte dengan memesan ulang: Cobalah online!
Dom Hastings
4

Python 2, 50 43 byte

Kredit untuk japh untuk versi baru

lambda n:chr(hash(n)%2354%977%237%54%26+65)

Cobalah online!

Catatan: Ini tergantung pada hashbuiltin dan tidak akan bekerja di semua implementasi

KSab
sumber
43 byte:lambda n:chr(hash(n)%2354%977%237%54%26+65)
japh
@ jaf Bagus! Pemeriksa python brute force saya jelas tidak cukup cepat;)
KSab
3

Ruby, 63 byte

->s{((0x3c4001c151861b27d>>s.sum%98%66).to_s(2).sum%48+64).chr}

Tambahkan kode ascii dari input, bawa mod 98 dan kemudian mod 66 untuk mendapatkan salah satu dari 26 angka unik ndi kisaran 0..65. Angka heksadesimal besar berisi 1sedikit di masing-masing 26 tempat ini, jadi dengan hakhifting dengan nkami memperoleh nomor dengan 1,26 1bit di dalamnya. Kami menghitung 1bit dengan menambahkan kode ascii dan mengambil mod 48, kemudian menambahkan 64 dan mengkonversi ke kode ASCII.

Program uji

yang mapiterates melalui penyanyi mencetak kode huruf dan penyanyi. Kemudian mengembalikan array kode surat, yang sorted untuk menunjukkan bahwa setiap huruf digunakan sekali.

f=->s{((0x3c4001c151861b27d>>s.sum%98%66).to_s(2).sum%48+64).chr}
a= [
  "Aretha Franklin","Ray Charles",
  "Elvis Presley","Sam Cooke",
  "John Lennon","Marvin Gaye",
  "Bob Dylan","Otis Redding",
  "Stevie Wonder","James Brown",
  "Paul McCartney","Little Richard",
  "Roy Orbison","Al Green",
  "Robert Plant","Mick Jagger",
  "Tina Turner","Freddie Mercury",
  "Bob Marley","Smokey Robinson",
  "Johnny Cash","Etta James",
  "David Bowie","Van Morrison",
  "Michael Jackson","Jackie Wilson"
]

p a.map{|i|p [f[i],i];f[i]}.sort

Keluaran

["S", "Aretha Franklin"]
["E", "Ray Charles"]
["R", "Elvis Presley"]
["J", "Sam Cooke"]
["X", "John Lennon"]
["C", "Marvin Gaye"]
["M", "Bob Dylan"]
["W", "Otis Redding"]
["V", "Stevie Wonder"]
["Y", "James Brown"]
["D", "Paul McCartney"]
["Q", "Little Richard"]
["Z", "Roy Orbison"]
["P", "Al Green"]
["O", "Robert Plant"]
["K", "Mick Jagger"]
["N", "Tina Turner"]
["L", "Freddie Mercury"]
["G", "Bob Marley"]
["I", "Smokey Robinson"]
["A", "Johnny Cash"]
["F", "Etta James"]
["H", "David Bowie"]
["U", "Van Morrison"]
["B", "Michael Jackson"]
["T", "Jackie Wilson"]
["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] 
Level River St
sumber
3

Oktaf , 85 83 80 74 byte

@(n)('A':'Z')(mod(n([1 2 8])*[1;15;47],124)=='#iZo,gp<C&4Y1!8-G`Kn3wtTIO')

Kekacauan anonim ini adalah hasil dari beberapa main-main di MATLAB mencoba menemukan cara yang baik untuk menyandikan data.

Pada dasarnya setelah analisis cepat, hanya huruf 1,2, dan 8 dari string input (string terkecil adalah 8 karakter, jadi kami baik) diperlukan untuk menghasilkan nilai unik dari setiap input. Bagian yang sulit kemudian mengubah nilai unik itu menjadi sesuatu yang dapat digunakan.

MATLAB sangat buruk dalam mengompresi data, jadi saya harus mencari cara lain untuk melakukan pemetaan pencarian. Saya mencoba mencari beberapa fungsi pada tiga huruf input yang menghasilkan nilai unik yang juga merupakan nilai ASCII yang dapat dicetak sehingga saya bisa menanamkan pemetaan dalam string satu karakter per input.

Ternyata matriks yang mengalikan karakter pada indeks [1 2 8]dengan matriks integer [1;15;47]dan kemudian melakukan mod 124 menghasilkan nilai-nilai unik yang semua dicetak ASCII (dan tidak ada 'karakter yang akan mengganggu string literal). Menyenangkan pemetaan berakhir dengan TIOyang benar-benar tidak disengaja. Menariknya ini adalah satu - satunya pemetaan untuk persamaan ini yang memberikan 26 karakter ASCII yang dapat dicetak yang unik.

Jadi pada dasarnya itu adalah pemetaan dan perhitungan pencarian saya. Melakukan pencarian hanyalah kasus melakukan perhitungan dan membandingkan dengan pemetaan. Menambahkan 'A'-1ke indeks di peta menghasilkan karakter AZ.

Anda dapat mencobanya secara online di TIO, yang menunjukkan pemetaan penuh input dan output. Untuk kelengkapan pemetaan lengkapnya juga di bawah ini:

'Aretha Franklin' ==> B
'Ray Charles'     ==> S
'Elvis Presley'   ==> F
'Sam Cooke'       ==> V
'John Lennon'     ==> L
'Marvin Gaye'     ==> N
'Bob Dylan'       ==> C
'Otis Redding'    ==> Q
'Stevie Wonder'   ==> X
'James Brown'     ==> I
'Paul McCartney'  ==> R
'Little Richard'  ==> M
'Roy Orbison'     ==> T
'Al Green'        ==> A
'Robert Plant'    ==> U
'Mick Jagger'     ==> P
'Tina Turner'     ==> Y
'Freddie Mercury' ==> H
'Bob Marley'      ==> D
'Smokey Robinson' ==> W
'Johnny Cash'     ==> K
'Etta James'      ==> G
'David Bowie'     ==> E
'Van Morrison'    ==> Z
'Michael Jackson' ==> O
'Jackie Wilson'   ==> J

  • Menyimpan pemetaan tweaking 2 byte untuk dihapus +32.
  • Disimpan 3 byte dengan membuat Oktaf-satunya menggunakan pengindeksan logis 'A':'Z'daripada menemukan.
  • Disimpan 6 byte dengan melakukan penjumlahan dari perkalian menggunakan perkalian matriks.
Tom Carpenter
sumber
Pendekatan pintar, mungkin terlalu pintar? 53 byte, berdasarkan jawaban MATL saya
Sanchises
@ Menyembunyikan mungkin, tapi itu adalah pendekatan yang saya gunakan dengan ¯_ (ツ) _ / ¯. Anda boleh memposting versi Anda sebagai jawaban terpisah.
Tom Carpenter
Saya pikir, dan saya setuju bahwa lebih menarik untuk memiliki pendekatan yang berbeda daripada hanya menyalin pendekatan terpendek. Saya hanya ingin membandingkan pendekatan, saya pikir milik Anda lebih pintar tapi saya kira dataset hanya diperbolehkan untuk pendekatan berbasis mod yang mudah (tidak yakin apakah itu kebetulan atau kemungkinan secara statistik)
Sanchises
3

JavaScript (Chrome), 102

Catatan Sayangnya ini hanya berfungsi di Chrome, karena pendekatan yang bergantung pada implementasi di parseInt () (terima kasih @Arnauld)

s=>s[0]=='L'?'z':"ab.c..defghijklmn...o..pqrst.u.vwxy"[parseInt(s.replace(/ /,'o').slice(0,14),36)%35]

Saya mencari fungsi hash, mengambil sepotong nama masing-masing, mengkonversi ke angka menggunakan basis 36 dan kemudian menerapkan modulo.

Saya menggunakan kode ini untuk mencari hash terbaik:

x=`Al Green\nAretha Franklin\nBob Dylan\nBob Marley\nDavid Bowie\nElvis Presley\nEtta James\nFreddie Mercury\nJackie Wilson\nJames Brown\nJohn Lennon\nJohnny Cash\nLittle Richard\nMarvin Gaye\nMichael Jackson\nMick Jagger\nOtis Redding\nPaul McCartney\nRay Charles\nRobert Plant\nRoy Orbison\nSam Cooke\nSmokey Robinson\nStevie Wonder\nTina Turner\nVan Morrison`.split(`\n`)

max=0
for(m=26;m<60;m++)
  for(i=0;i<20;i++)
    for(j=i;++j<20;)
      for(k=0;k<37;k++)
      {
        S=new Set();
        f=k ? (k-1).toString(36) : ''
        x.forEach(x=>(n=parseInt(x.replace(/ /,f).slice(i,j),36)%m, S.add(n)))
        if (S.size > max) console.log(i,j,f,m,max=S.size)
      }

Dan hasilnya:

0 1 "" 26 14
0 2 "" 26 15
0 4 "" 26 16
0 5 "" 26 18
0 6 "0" 26 19
0 6 "3" 26 20
0 8 "a" 26 21
2 5 "7" 28 23
0 14 "h" 35 24
0 14 "o" 35 25
2 9 "" 51 26

Fungsi hash terbaik memberikan 26 nilai yang berbeda antara 0 dan 50, tapi saya menggunakan yang berbeda, dengan 1 duplikat tetapi rentang yang lebih kecil.

Uji

var names=x=`Al Green\nAretha Franklin\nBob Dylan\nBob Marley\nDavid Bowie\nElvis Presley\nEtta James\nFreddie Mercury\nJackie Wilson\nJames Brown\nJohn Lennon\nJohnny Cash\nLittle Richard\nMarvin Gaye\nMichael Jackson\nMick Jagger\nOtis Redding\nPaul McCartney\nRay Charles\nRobert Plant\nRoy Orbison\nSam Cooke\nSmokey Robinson\nStevie Wonder\nTina Turner\nVan Morrison`.split(`\n`)

var F=
s=>s[0]=='L'?'z':"ab.c..defghijklmn...o..pqrst.u.vwxy"[parseInt(s.replace(/ /,'o').slice(0,14),36)%35]

var Singers={}
names.forEach(n=>Singers[F(n)]=n)

;Object.keys(Singers).sort().forEach(i=> console.log(i, Singers[i]))

edc65
sumber
Anda mungkin ingin menyebutkan bahwa itu hanya bekerja pada Chrome karena perkiraan tergantung dari implementasi di parseInt().
Arnauld
@Arnauld terima kasih, saya tidak tahu.
edc65
3

C, 65 55 49 byte

h(char*s){return*s<77?(*s^s[5]+40)%13+65:(s[5]&s[4]+s[1])%13+78;}

h(char*s){return*(long*)s%887%392%224%120%67%40%26+65;}

Pendekatan yang sama dengan jawaban KSab . C tidak menyediakan hashfungsi string seperti Python. Atau apakah itu?

h(char*s){return*(long*)s%2004%857%361%94%26+65;}

Cobalah online!

hmengembalikan intnilai yang merupakan kode ASCII untuk A .. Z.

japh
sumber
2

Javascript, 98 byte

s=l=>("heCysvCm hirDb iiesm ultOyr rb c ndeMbeonh tdvMnacic".indexOf(l[4]+l[2])/2+10).toString(36)

Saya menemukan bahwa kombinasi karakter kedua dan keempat adalah unik untuk masing-masing.

Oleh karena itu saya membuat string dengan kombinasi name[4] + name[2], tidak name[2] + name[4]atau saya akan memiliki pengulangan dari grup char ehnama pertama Aretha Franklin ehdan ketika Smokey Robinson dan Johnny Cash oehndigabungkan.

Saya hanya bisa memindahkan Johnny Cash ke posisi lain dari string dan mendapatkan pemetaan yang berbeda, tetapi menggabungkan karakter ke-4 dan ke-2 dalam urutan ini untuk menghindari tabrakan dan membiarkan urutan dataset tetap utuh tanpa menambahkan lebih panjang untuk solusi. Jadi saya memutuskan untuk pergi ke sana (itu hanya pilihan pribadi)

Saya mencari posisi gabungan dari huruf 4 dan 2 dari parameter yang diberikan dalam string dan membaginya dengan 2 sehingga saya mendapatkan angka antara 0 dan 25. Kemudian saya menambahkan 10 dan mengubahnya menjadi string dari basis 36, di mana 10 sesuai dengan adan 35 kez

let singers = [
  "Aretha Franklin",
  "Ray Charles",
  "Elvis Presley",
  "Sam Cooke",
  "John Lennon",
  "Marvin Gaye",
  "Bob Dylan",
  "Otis Redding",
  "Stevie Wonder",
  "James Brown",
  "Paul McCartney",
  "Little Richard",
  "Roy Orbison",
  "Al Green",
  "Robert Plant",
  "Mick Jagger",
  "Tina Turner",
  "Freddie Mercury",
  "Bob Marley",
  "Smokey Robinson",
  "Johnny Cash",
  "Etta James",
  "David Bowie",
  "Van Morrison",
  "Michael Jackson",
  "Jackie Wilson"
]

s=l=>("heCysvCm hirDb iiesm ultOyr rb c ndeMbeonh tdvMnacic".indexOf(l[4]+l[2])/2+10).toString(36)

singers.forEach(singer => console.log(s(singer), singer))

Eduardo Páez Rubio
sumber
sangat golok kombinasi yang Anda temukan!
Setia
aaah ya. tentu saja. saya punya sesuatu yang sangat mirip, tetapi alih-alih menambahkan char untuk kembali dalam string, posisi terjadinya dapat menghemat 25 karakter. Pintar!
nl-x
1

Bahasa Wolfram (Mathematica) , 101126 byte

Alphabet[][[#&@@#&@@Position[(t=ToCharacterCode)@"nZ-Be_;f%d^q 0w@x~KDaLJ&`k",Total@t@#~Mod~98+32]]]&

+32tampaknya mengarah ke hashtable stirng terpendek di Mathematica InputForm.

Cobalah online!

Keyu Gan
sumber
1

///, 390 231 byte

/gg/U/
/a///b///c///d///e///f///g///h///i///j///k///l///m///n///o///p///q///r///s///t///u///v///w///x///y///z//
/ F//
/A //
/ G//
/ M//
/M //
/J B/X/
/J //
/L //
/ R//
/R C/Y/
/S C/Z/
/B D/K/
/ B//
/ J//
/ T//
/S W/I/
/R O/N/
/JU/U/
/R //
/E P/H/
/PC/Q/

Cobalah online!

231 byte setelah menghapus baris baru.

Ini sangat panjang, tetapi /// tidak dapat menangani karakter yang berbeda secara umum. Dengan kata lain, /// tidak mendukung regex.

pengguna202729
sumber
0

Excel, 96 byte

Setelah terlalu banyak waktu yang terbuang untuk mencoba pendekatan lain, telah menerapkan pendekatan @Eduardo Paez:

=CHAR(FIND(MID(A1,5,1)&MID(A1,3,1),"her DbMbdvsv tdeicsm hnhltirac c i uCyrbOyCmeoie nMn")/2+65)
Wernisch
sumber