26 piosenkarzy, 26 liter

34

Według RollingStone poniżej znajduje się 26 największych wokalistów wszechczasów:

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

Możesz uzyskać to jako listę ciągów tutaj .

Zadanie

Biorąc pod uwagę nazwę piosenkarz, wydrukować lub powrócić do nas od Acelu Z, który jednoznacznie identyfikuje tę piosenkarkę. (Jeśli kod zwraca A dla Boba Dylana , to nie może zwrócić A dla żadnego innego piosenkarza.)

W przeciwieństwie do innych podobnych wyzwań, mapowanie zależy od ciebie, o ile nie powoduje kolizji.

Zasady

  • Dane wejściowe są gwarantowane jako jedna z 26 nazwisk piosenkarzy wymienionych powyżej z tą dokładną pisownią i bez żadnych początkowych lub końcowych białych znaków.
  • Możesz wydrukować literę małymi lub dużymi literami. Ale to musi być konsekwentne.
  • Zachęcamy do zapewnienia zestawu testów dla wszystkich 26 możliwych danych wejściowych.
  • To jest , więc wygrywa najkrótsza odpowiedź w bajtach!
Arnauld
źródło
17
Dear Rolling Stone: Bob Dylan jest naprawdę jednym z największych muzyków w historii. Ale świetny piosenkarz ?
Luis Mendo,
@LuisMendo Jestem trochę słony o kilku z tych wyborów, jak również ( kaszel kaszel gdzie jest Steven Tyler kaszel )
Lord Farquaad
@LordFarquaad Steve Tyler ma numer # 99 ¯ \ _ (ツ) _ / ¯
Arnauld
może to komuś pomóc, ale nie mam umiejętności korzystania z informacji komputerowych, aby korzystać z informacji: 1-6, 1-8 i 3-5 liter nazw to unikalne kombinacje.
Jeutnarg,

Odpowiedzi:

2

MATL , 28 bajtów

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

Wypróbuj online!

Wyjaśnienie

s98\40\

Uzyskaj niejawnie ciąg wejściowy. Zsumuj znaki ciągu wejściowego i zrób to moduł 98, a następnie moduł 40. Wynik w jednej z następujących liczb: 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 (w kolejności listy Pastebin).

2Y2'ijkl o qst uz'h

Naciśnij alfabet (małe litery) za pomocą 2Y2. Zajmuje się to liczbami z zakresu [1,26]. Jednak brakuje niektórych liczb i mamy liczby do 38. Dlatego dołączamy ( h) ciąg, który zajmuje się wyższymi liczbami, poprzez mapowanie tych liczb na „brakujące” litery. Spacje mogą być dowolne, dla własnej wygody użyłem wielkich liter w moim oryginalnym programie.

w)

Możemy teraz zindeksować liczbę od pierwszego kroku do ciągu od drugiego kroku za pomocą ). Używamy, waby uzyskać argumenty we właściwej kolejności. Chociaż może się wydawać, że korzystamy z indeksowania opartego na 0 (liczby różnią się od 0 do 38, a łańcuch ma 39 znaków), rzeczywistość jest w rzeczywistości nieco bardziej skomplikowana: korzystamy z indeksowania modułowego opartego na 1, unikatowej dla MATL. Oznacza to, że 1indeksuje a, 38faktycznie indeksuje ui 0indeksuje do końcowego zciągu.

Sanchises
źródło
23

Python 2 , 80 71 bajtów

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

Wypróbuj online!

Zmodyfikowane sumy rzędnych dają liczby między 0i38

Liczby większe niż 25 są następnie przesuwane, aby wypełnić puste pola, jak poniżej (pokazano posortowaną sekwencję):

  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

Odejmij, 18jeśli 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

Dodaj, 3jeśli 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

Odejmij, 8jeśli 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

Co daje sekwencję 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

Są one następnie przekształca się A-Zzchr(i+65)

TFeld
źródło
Myślę, że można skrócić (i>31)do i/32itp.
xnor
21

Procedura kodu maszynowego 6502 (C64), 83 bajty

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

Jest to kod niezależny od pozycji, po prostu umieść go gdzieś w pamięci RAM i wskocz tam, np. Za pomocą syspolecenia.

Demo online (ładuje się do$C000/49152).

Zastosowanie: sys49152,"[name]" np sys49152,"Aretha Franklin".

Ważne: Jeśli program został załadowany z dysku (jak w wersji demonstracyjnej online), newnajpierw wydaj polecenie! Jest to konieczne, ponieważ ładowanie programu maszynowego niszczy niektóre wskaźniki C64 BASIC.

Uwaga: C64 jest domyślnie w trybie bez małych liter - aby móc wprowadzać czytelne nazwy, najpierw przełącz na tryb małych liter, naciskając SHIFT+ CBM.


Wyjaśnienie

W rzeczywistości wyzwaniem jest znalezienie minimalnej idealnej funkcji skrótu dla tych nazw; dla C64 musiałem znaleźć taki, który można łatwo obliczyć w prostych 8-bitowych operacjach. Oto skomentowana lista dezasemblacji:

.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

Pakiet testowy (C64 BASIC, zawierający procedurę kodu maszynowego w datawierszach)

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 pakietu testowego .

Felix Palmen
źródło
13

Python 2 , 68 bajtów

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

Wypróbuj online!

ovs
źródło
1
Ciekawe, jak to skomponowałeś
Sarge Borsch,
2
@SargeBorsch hash (n) oblicza unikalną liczbę całkowitą dla wszystkich nazw. Operacje modulo nadal utrzymują te ints unikalne, ale obniżają ich wartość. Druga część ( chr(65+i-i/25*2-i/29*21+i/35*2)) jest podobna do odpowiedzi TFelds . Operacje modulo są brutalnie wymuszone przez skrypt, którego już użyłem tu i tutaj .
ovs
10

JavaScript, 138 132 znaków

Ponieważ wszystkie inicjały są wyjątkowe, z wyjątkiem MJ= M ichael J ackson / M ick J Agger, sprawdzić dla Michaela Jacksona specjalnie (tylko jeden z hna 4 pozycji), a dla wszystkich innych nazw stworzyłem ciąg z inicjałami obserwowanych unikalnym listem.

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

Fragment kodu

Wypróbuj tutaj:

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
źródło
Może być krótsza funkcja haszująca, ale podoba mi się pomysł wypróbowania czegoś, co mógłby zrobić człowiek. Jednak chciałbym, abyś użył funkcji fragmentu kodu zamiast linkowania do JSFiddle.
trlkly 12.10.17
@trlkly Użyłem teraz funkcji fragmentu kodu.
nl-x
7

Java (OpenJDK 8) , 128 126 115 113 bajtów

Niezbyt obskurny jak na zgłoszenie w java!

Dzięki Kevinowi za uratowanie mi całej bajtów dzięki wyrażeniom 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);}

Wypróbuj online!

Luke Stevens
źródło
1
Dobra odpowiedź, +1 ode mnie. Obecnie pracuję również nad rozwiązaniem Java, tworząc skrypt. Na razie nie mam szczęścia. Przy okazji, możesz {a+=i;}a+=i;
zagrać w
1
@KevinCruijssen Na zdrowie, nie mogę uwierzyć, że to przegapiłem! Napisałem skrypt, aby spróbować znaleźć „magiczną liczbę”, która dałaby mi unikalne wartości od 0 do 25, ale najlepsze, co mogłem zrobić, to 24, stąd instrukcje if na końcu.
Luke Stevens,
1
Hmm btw, ponieważ używasz Java 8, możesz także grać char g(String s)w golfa s->. Zmodyfikowałem TIO, aby pokazać, jak to zrobić, na wypadek, gdybyś był przyzwyczajony do metod Java 7.
Kevin Cruijssen
Dzięki, nigdy nie zdawałem sobie sprawy, że możesz to zrobić, zaktualizuję swoje zgłoszenie (ponownie!)
Luke Stevens,
Hahaha, możesz powiedzieć, że jestem nowy
Luke Stevens,
5

Python 3, 132 99 96 bajtów

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

Wypróbuj online!

Nie świetnie grałem w golfa, ale pomyślałem, że spróbuję.

-33 bajtów dzięki modyfikacjom dokonanym przez TFeld.
-3 bajty za pomocą findzamiast indexdzięki ovs.

LyricLy
źródło
Możesz zapisać 6 bajtów, używając sum(map(ord,m)), także dodałem Arethę Franklin dla 128 bajtów
TFeld,
I możesz użyć chr(97+...)zamiast ascii_lowercase: 99 bajtów
TFeld 10.10.17
1
Co z wyjaśnieniem?
Matsemann,
3
Wyjaśnienie: sum(map(ord,m))sumuje wartości ASCII znaków w ciągu m(podaje liczby całkowite z zakresu 702–1506). Potem dzwoni chrkonwertuje go do (Unicode) postać z tego numeru: chr(702)jest ʾ , aby chr(1506) = עi wiele pomiędzy. To rozwiązanie po prostu wyszukuje ten znak na liście wszystkich możliwych (26) takich znaków, aby uzyskać indeks (0–26), a następnie zwraca znak o kodzie ASCII 97 + ten indeks (czyli „a” do „z”).
ShreevatsaR
1
Twoje obecne rozwiązanie nadal zawiera 99-bajtową wersję. Chciałeś użyć wersji OVS?
nl-x
5

PHP, 90 88 86 72 + 1 bajty

może stać się jeszcze krótszy z innym modułem.

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

Zapisz do pliku i uruchom jako potok za pomocą -nFlub wypróbuj online .

Tytus
źródło
2
Aretha Franklin i Paul McCartney generują wyniki Wna testach i nie ma Xdanych wyjściowych. Nie wiem, czy to błąd w samym kodzie, czy po prostu spróbuj konwersji online :)
crazyloonybin,
1
Naprawiono literówkę zastępczą @crazyloonybin. Dzięki za podpowiedź.
Tytus
Jak mam to uruchomić? Twój kod „wypróbuj online” nie korzysta z tej <?=części. I „Biegnij jak rura” nie pracuję. Otrzymuję również powiadomienia, gdy próbuję uruchomić go z wiersza poleceń.
nl-x
@Titus: W CodeGolf należy podać pełną funkcję lub aplikację, która generuje (tylko) pożądane dane wyjściowe. Znam <?=... Więc moje pytanie wciąż brzmi: jak uruchomić kod (z wiersza poleceń)? Nie udaje $argnmi się podać go w wierszu poleceń ... Wszystkie moje dotychczasowe próby dają artefakty i nadal wymagają więcej kodu, aby uruchomić.
nl-x
@ nl-x Twój PHP wyświetla powiadomienia, ponieważ nie dałeś mu opcji n:echo <input> | php -nF <scriptfilename>
Titus
4

Perl, 56 , 54 , 50 , 46 +1 (-p) bajtów

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

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

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

Dzięki komentarzowi Dom mógł zaoszczędzić 4 dodatkowe bajty, również zmieniono na wielkie litery, aby dopasować lepsze wymagania.

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

Wypróbuj online

Nahuel Fouilleul
źródło
Niezłe podejście! Myślę, że musisz jednak napisać / zdobyć całą wywoływalną funkcję?
Felix Palmen
@ FelixPalmen, to program perla, który można nazwać inline: perl -pe '$_=crypt$_,mO;/..(.)/;$_=$1;y/035eft/AHPRXZ/;$_=lc'dodawanie linku do tio
Nahuel Fouilleul
Miły! Szukałem podobnego podejścia, używając, $1^$2ale nie pomyślałem o użyciu crypt... Możesz zapisać 4 bajty z pewną zmianą kolejności: Wypróbuj online!
Dom Hastings,
4

Python 2, 50 43 bajtów

Kredyt dla japh dla nowej wersji

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

Wypróbuj online!

Uwaga: Zależy to od hashwbudowanego i nie będzie działać we wszystkich implementacjach

KSab
źródło
43 bajtów:lambda n:chr(hash(n)%2354%977%237%54%26+65)
japh
@japh Nice! Mój python brute force checker najwyraźniej nie był wystarczająco szybki;)
KSab
3

Ruby, 63 bajty

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

Dodaje kody ascii wejścia, pobiera je mod 98, a następnie mod 66, aby uzyskać jedną z 26 unikalnych liczb nz zakresu 0..65. Ogromna liczba szesnastkowa zawiera 1trochę w każdym z tych 26 miejsc, więc przesuwając ją o prawo n, otrzymujemy liczbę z 1..26 1bitami. Liczymy 1bity, dodając kody ascii i biorąc mod 48, a następnie dodajemy 64 i konwertujemy na kod ASCII.

Program testowy

mapiteracje przez śpiewaków Drukowanie literowy kod i piosenkarka. Następnie zwraca tablicę kodów literowych, która jest sortedytowana w celu wykazania, że ​​każda litera jest używana raz.

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

Wydajność

["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
źródło
3

Oktawa , 85 83 80 74 bajty

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

Ten bałagan anonimowy jest wynikiem pewnego bałaganu w MATLAB, który próbuje znaleźć dobry sposób na kodowanie danych.

Zasadniczo po szybkiej analizie, tylko litery 1,2 i 8 ciągu wejściowego (najmniejszy ciąg to 8 znaków, więc jesteśmy dobrzy) są potrzebne do wytworzenia unikalnej wartości z każdego wejścia. Trudność polega na przekształceniu tej unikalnej wartości w coś użytecznego.

MATLAB ma problemy z kompresowaniem danych, więc musiałem poszukać innego sposobu na mapowanie wyszukiwania. Próbowałem znaleźć jakąś funkcję na trzech literach wejściowych, która dała unikalną wartość, która była również wartością drukowalną ASCII, dzięki czemu mogłem osadzić mapowanie w ciągu jednego znaku na dane wejściowe.

Okazuje się, że macierz pomnożąca znaki w indeksie [1 2 8]przez macierz całkowitą, [1;15;47]a następnie wykonująca mod 124 daje unikalne wartości, które wszystkie drukowane ASCII (i żadna z nich nie jest 'znakiem, który błędnie literałby ciąg znaków). Przyjemnie kończy się mapowanie, TIOco jest całkowicie przypadkowe. Co ciekawe, jest to jedyne odwzorowanie tego równania, które daje 26 unikalnych drukowalnych znaków ASCII.

Więc w zasadzie to moje mapowanie i obliczanie odnośników. Wykonanie wyszukiwania to po prostu wykonanie obliczeń i porównanie z mapowaniem. Dodanie 'A'-1do indeksu na mapie powoduje powstanie znaku AZ.

Możesz wypróbować go online na TIO, który pokazuje pełne mapowanie wejść i wyjść. Dla kompletności pełne mapowanie znajduje się również poniżej:

'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

  • Zapisano 2 bajty dostrajania mapowania do usunięcia +32.
  • Zaoszczędzono 3 bajty, czyniąc Octave tylko logicznym indeksowaniem 'A':'Z'zamiast znajdowania.
  • Zaoszczędzono 6 bajtów, wykonując sumę mnożenia za pomocą mnożenia macierzy.
Tom Carpenter
źródło
Sprytne podejście, może zbyt sprytne? 53 bajty, w oparciu o moją odpowiedź
MATL
@ Prawdopodobnie Sanchises, ale takie podejście wymyśliłem z ¯_ (ツ) _ / ¯. Możesz opublikować swoją wersję jako osobną odpowiedź.
Tom Carpenter,
Doszedłem do wniosku i zgadzam się, że bardziej interesujące jest stosowanie różnych podejść niż tylko kopiowanie najkrótszego podejścia. Chciałem tylko porównać podejścia, myślę, że twoje są bardziej sprytne, ale przypuszczam, że zestaw danych pozwolił na proste podejście oparte na
modach
3

JavaScript (Chrome), 102

Uwaga Niestety działa tylko w Chrome, z powodu aproksymacji zależnych od implementacji w parseInt () (dzięki @Arnauld)

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

Szukałem funkcji skrótu, biorąc kawałek każdego imienia, konwertując na liczby za pomocą bazy 36, a następnie stosując modulo.

Użyłem tego kodu, aby znaleźć najlepszy skrót:

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

A wyniki:

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

Najlepsza funkcja skrótu daje 26 różnych wartości od 0 do 50, ale użyłem innej, z 1 zduplikowanym, ale mniejszym zakresem.

Test

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
źródło
Warto wspomnieć, że działa tylko w Chrome z powodu przybliżeń zależnych od implementacji w parseInt().
Arnauld,
@Arnauld dzięki, nie wiedziałem.
edc65
3

C, 65 55 49 bajtów

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

Takie samo podejście jak odpowiedź KSab . C nie zapewnia hashfunkcji łańcuchowej takiej jak Python. A może to?

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

Wypróbuj online!

hzwraca wartość, dla intktórej wartości są kodami ASCII A .. Z.

japh
źródło
2

JavaScript, 98 bajtów

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

Przekonałem się, że kombinacja drugiej i czwartej postaci imion jest unikalna dla każdego z nich.

Dlatego tworzę ciąg z kombinacjami name[4] + name[2], nie name[2] + name[4]lub chciałbym powtórzyć grupę char eho imieniu Aretha Franklin ehi kiedy Smokey Robinson i Johnny Cashoehn są konkatenowani.

Mógłbym po prostu przenieść Johnny'ego Casha do innej pozycji ciągu i uzyskać inne odwzorowanie, ale połączenie czwartego i drugiego znaku w tej kolejności pozwala uniknąć kolizji i pozostawia nienaruszoną kolejność zestawu danych bez zwiększania długości rozwiązania. Postanowiłem więc pójść tą drogą (to tylko osobiste preferencje)

Poszukuję pozycji konkatenacji czwartej i drugiej litery danego parametru w ciągu i dzielę go przez 2, aby uzyskać liczbę od 0 do 25. Następnie dodam 10 i przekonwertuję go na ciąg z podstawy 36, gdzie 10 odpowiada ai 35 doz

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
źródło
bardzo tasak kombinacja, którą znalazłeś!
Joyal
O tak oczywiście. Mam coś podobnego, ale zamiast dodania znaku char w celu powrotu do ciągu, pozycja wystąpienia może zaoszczędzić 25 znaków. Sprytny!
nl-x
1

Wolfram Language (Mathematica) , 101126 bajty

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

+32 wydaje się prowadzić do najkrótszego mieszania tablicy w Mathematica InputForm .

Wypróbuj online!

Keyu Gan
źródło
1

///, 390 231 bajtów

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

Wypróbuj online!

231 bajtów po usunięciu nowego wiersza.

Jest to bardzo długie, ale /// nie może ogólnie obsługiwać różnych znaków. Innymi słowy, /// nie obsługuje wyrażenia regularnego.

użytkownik202729
źródło
0

Excel, 96 bajtów

Po zbyt długim czasie marnowania na inne podejścia, wdrożyłem podejście @Eduardo Paez:

=CHAR(FIND(MID(A1,5,1)&MID(A1,3,1),"her DbMbdvsv tdeicsm hnhltirac c i uCyrbOyCmeoie nMn")/2+65)
Wernisch
źródło