26 cantanti, 26 lettere


34

Secondo RollingStone , di seguito sono riportati i 26 più grandi cantanti di tutti i tempi:

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

Puoi ottenere questo come un elenco di stringhe qui .

Compito

Dato un nome di cantante, stampare o restituire una lettera da Aa Zche identifica univocamente questo cantante. (Se il tuo codice restituisce A per Bob Dylan , non può restituire A per nessun altro cantante.)

A differenza di altre sfide simili, la mappatura dipende da te purché sia ​​libera da collisioni.

Regole

  • L'ingresso è garantito per essere uno dei 26 nomi di cantanti sopra elencati con questo ortografia esatta e senza spazi bianchi iniziali o finali.
  • È possibile emettere la lettera in minuscolo o maiuscolo. Ma deve essere coerente.
  • Siete incoraggiati a fornire una suite di test per tutti i 26 possibili input.
  • Questo è , quindi vince la risposta più breve in byte!


17
Caro Rolling Stone: Bob Dylan è davvero uno dei più grandi musicisti di sempre. Ma un grande cantante ?
Luis Mendo,

@LuisMendo Sono un po 'salato su alcune di queste scelte così ( tosse tosse dov'è Steve Tyler tosse )
Lord Farquaad

@LordFarquaad Steve Tyler è # 99 ¯ \ _ (ツ) _ / ¯
Arnauld

questo può aiutare qualcuno, ma non ho le competenze CG per usare le informazioni: le lettere 1-6, 1-8 e 3-5 dei nomi sono combinazioni uniche.
Jeutnarg,

Risposte:


2

MATL , 28 byte

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

Provalo online!

Spiegazione

s98\40\

Ottieni implicitamente la stringa di input. Somma i caratteri della stringa di input ed esegui il modulo 98 seguito dal modulo 40. Risultati in uno dei seguenti numeri: 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 (in ordine dell'elenco di Pastebin).

2Y2'ijkl o qst uz'h

Spingere l'alfabeto (minuscolo) con 2Y2. Questo si occupa dei numeri nell'intervallo [1,26]. Tuttavia, mancano alcuni numeri e abbiamo numeri fino a 38. Quindi, aggiungiamo ( h) una stringa che si occupa dei numeri più alti, mappando questi numeri sulle lettere "mancanti". Gli spazi possono essere qualsiasi cosa, ho usato le lettere maiuscole nel mio programma originale per mia comodità.

w)

Ora possiamo indicizzare il numero dal primo passaggio nella stringa dal secondo passaggio con ). Usiamo wper ottenere gli argomenti nell'ordine corretto. Mentre può sembrare che utilizziamo l'indicizzazione basata su 0 (i numeri variano da 0 a 38 e la stringa ha una lunghezza di 39 caratteri), la realtà è in realtà un po 'più complicata: utilizziamo l'indicizzazione modulare basata su 1, una caratteristica unica di MATL. Ciò significa che 1indicizza a, 38indicizza ue 0indicizza il finale zdella stringa.


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)

Provalo online!

Le somme di ordinali modificate danno numeri tra 0e38

I numeri maggiori di 25 vengono quindi spostati per riempire gli spazi vuoti come sotto (sequenza ordinata mostrata):

  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

Sottrai 18se 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

Aggiungi 3se 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

Sottrai 8se 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

Che dà la sequenza 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

Questi vengono quindi convertiti in A-Zconchr(i+65)


Penso che si possa ridurre (i>31)a i/32, ecc
XNOR

21

6502 routine codice macchina (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

Questo è un codice indipendente dalla posizione, basta inserirlo da qualche parte nella RAM e saltare lì, ad esempio usando il syscomando.

Demo online (carica in$C000/49152).

Utilizzo: sys49152,"[name]" ad es sys49152,"Aretha Franklin".

Importante: se il programma è stato caricato dal disco (come nella demo online), emettere newprima un comando! Ciò è necessario perché il caricamento di un programma macchina elimina alcuni puntatori BASIC C64.

Nota: il C64 è di default in una modalità senza lettere minuscole - per poter inserire nomi leggibili , passare prima alla modalità minuscole premendo SHIFT+ CBM.


Spiegazione

La sfida è infatti trovare una funzione hash perfetta minima per questi nomi; per il C64, ho dovuto trovarne uno facilmente calcolabile in semplici operazioni a 8 bit. Ecco un elenco di smontaggio commentato:

.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

Suite di test (C64 BASIC, contenente la routine del codice macchina in datarighe)

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 della suite di test .


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)

Provalo online!


1
interessante sapere come hai composto questo
Sarge Borsch,

2
L'hash @SargeBorsch (n) calcola un numero intero univoco per ogni nome. Le operazioni del modulo mantengono comunque quegli interi unici, ma ne riducono il valore. La seconda parte ( chr(65+i-i/25*2-i/29*21+i/35*2)) è simile alla risposta di TFelds . Le operazioni del modulo sono rinforzate da uno script che ho già usato qui e qui .
Ovs,

10

Javascript, 138 132 caratteri

Poiché tutte le iniziali sono uniche, ad eccezione di MJ= M ichael J ackson / M ick J agger, controllo specificamente Michael Jackson (l'unico con un hin quarta posizione), e per tutti gli altri nomi ho creato una stringa con le iniziali seguite da una lettera unica.

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

Snippet di codice

Provalo qui:

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


Potrebbe esserci una funzione di hashing più breve, ma mi piace l'idea di provare qualcosa che un essere umano potrebbe fare. Tuttavia, vorrei che tu usassi la funzione snippet di codice invece di collegarti a JSFiddle.
sinceramente il

@trlkly Ho usato la funzione snippet di codice ora.
nl-x

7

Java (OpenJDK 8) , 128 126 115 113 byte

Non troppo malandato per una presentazione java!

Grazie a Kevin per avermi salvato un sacco di byte con le espressioni 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);}

Provalo online!


1
Bella risposta, +1 da parte mia. Attualmente sto anche lavorando a una soluzione Java creando uno script .. Per fortuna finora non ho avuto fortuna. A proposito, puoi giocare a golf a due byte cambiando {a+=i;}ina+=i;
Kevin Cruijssen il

1
@KevinCruijssen Saluti, non posso credere che mi sia perso! Ho scritto una sceneggiatura per cercare di trovare il "numero magico" che mi avrebbe dato valori univoci compresi tra 0 e 25, ma il meglio che potevo fare era 24, quindi le dichiarazioni if ​​alla fine.
Luke Stevens,

1
A proposito, dal momento che stai usando Java 8, puoi anche giocare char g(String s)a golf s->. Ho modificato il tuo TIO per mostrare come farlo, nel caso in cui tu sia abituato solo ai metodi Java 7.
Kevin Cruijssen,

Grazie, non ho mai capito che potresti farlo, aggiornerò la mia richiesta (di nuovo!)
Luke Stevens,

Hahaha, puoi dire che sono nuovo a questo
Luke Stevens,

5

Python 3, 132 99 96 byte

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

Provalo online!

Non ho giocato a golf brillantemente, ma ho pensato di provarlo.

-33 byte grazie alle modifiche apportate da TFeld.
-3 byte usando findinvece di indexgrazie a ovs.


Puoi salvare 6 byte usando sum(map(ord,m)), inoltre ho aggiunto Aretha Franklin per 128 byte
TFeld

E puoi usare chr(97+...)invece di ascii_lowercase: 99 byte
TFeld il

1
Che ne dici di una spiegazione?
Matsemann,

3
Una spiegazione: sum(map(ord,m))somma i valori ASCII dei caratteri nella stringa m(fornisce numeri interi compresi nell'intervallo 702–1506). Quindi chiamarlo chrlo converte in un carattere (Unicode) con quel numero: chr(702)è ʾ in chr(1506) = עe molto in mezzo. Questa soluzione cerca semplicemente questo carattere in un elenco di tutti i possibili (26) caratteri per ottenere l'indice (0–26), quindi restituisce il carattere con il codice ASCII 97 + quell'indice (quindi da 'a' a 'z').
ShreevatsaR,

1
La tua soluzione attuale contiene ancora una versione di 99 byte. Volevi usare la versione di OVS?
nl-x

5

PHP, 90 88 86 72 + 1 byte

potrebbe diventare ancora più breve con un modulo diverso.

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

Salva su file ed eseguilo come pipe con -nFo provalo online .


2
Aretha Franklin e Paul McCartney sono entrambi in uscita Wsui casi di test e non è disponibile alcun Xoutput. Non so se si tratta di un errore nel codice stesso o solo di provarlo nella conversione online :)
crazyloonybin

1
Errore di sostituzione di @crazyloonybin corretto. Grazie per il suggerimento.
Tito,

Quindi, come posso eseguire questo? Il tuo codice "provalo online" non utilizza la <?=parte. E il 'Run as pipe` non sto funzionando. Inoltre, ricevo avvisi quando provo a eseguirlo dalla riga di comando.
nl-x

@Titus: in CodeGolf dovresti fornire la funzione o l'applicazione completa che genera (solo) l'output desiderato. Ho familiarità con <?=... Quindi la mia domanda è ancora, come posso eseguire il codice (dalla riga di comando)? Non riesco ad alimentarlo $argndalla riga di comando ... Tutti i miei tentativi finora forniscono artefatti e sembrano ancora richiedere più codice per farlo funzionare.
nl-x

@ nl-x Il tuo PHP genera avvisi, è perché non gli hai dato l'opzione n:echo <input> | php -nF <scriptfilename>
Tito

4

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

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

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

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

Grazie al commento di Dom è stato possibile salvare altri 4 byte, anch'essi modificati in maiuscolo per soddisfare i requisiti migliori.

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

Provalo online


Bel approccio! Penso che tu debba scrivere / segnare un'intera funzione richiamabile però?
Felix Palmen,

@FelixPalmen, è un programma perl che può essere chiamato in linea: perl -pe '$_=crypt$_,mO;/..(.)/;$_=$1;y/035eft/AHPRXZ/;$_=lc'aggiunta del link a tio
Nahuel Fouilleul,

Bello! Stavo cercando un approccio simile, usando $1^$2ma non pensavo di usare crypt... Puoi salvare 4 byte con un po 'di riordino: provalo online!
Dom Hastings,

4

Python 2, 50 43 byte

Ringraziamo japh per la nuova versione

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

Provalo online!

Nota: dipende hashdall'integrato e non funzionerà in tutte le implementazioni


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

@japh Nice! Il mio controllo della forza bruta in pitone chiaramente non era abbastanza veloce;)
KSab il

3

Rubino, 63 byte

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

Aggiunge i codici ascii dell'input, li prende mod 98 e quindi mod 66 per ottenere uno dei 26 numeri univoci nnell'intervallo 0..65. L'enorme numero esadecimale contiene un 1bit in ognuna di queste 26 posizioni, quindi spostandolo con i diritti notteniamo un numero con 1..26 1bit al suo interno. Contiamo i 1bit aggiungendo i codici ASCII e prendendo la mod 48, quindi aggiungendo 64 e convertendoli in un codice ASCII.

Programma di test

l' mapitera i cantanti stampa il codice lettera e cantante. Restituisce quindi un array di codici di lettere, che viene sorteditato per dimostrare che ogni lettera viene utilizzata una volta.

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

Produzione

["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"] 

3

Ottava , 85 83 80 74 byte

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

Questo pasticcio di un anonimo è il risultato di qualche pasticcio in MATLAB che cerca di trovare un buon modo per codificare i dati.

Fondamentalmente dopo una rapida analisi, sono necessarie solo le lettere 1,2 e 8 della stringa di input (la stringa più piccola è 8 caratteri, quindi siamo bravi) per produrre un valore univoco da ciascun input. La parte difficile è quindi convertire quel valore unico in qualcosa di utilizzabile.

MATLAB è terribile nel comprimere i dati, quindi ho dovuto cercare un altro modo per creare il mapping di ricerca. Ho iniziato cercando di trovare una funzione sulle tre lettere di input che ha prodotto un valore univoco che era anche un valore ASCII stampabile in modo da poter incorporare la mappatura in una stringa di un carattere per input.

Si scopre che la matrice moltiplicando i caratteri all'indice [1 2 8]per la matrice intera [1;15;47]e quindi eseguendo la mod 124 risulta in valori univoci che tutti ASCII stampabili (e nessuno è un 'carattere che inciderebbe letteralmente stringhe). Piacevolmente la mappatura termina con la TIOquale è completamente accidentale. È interessante notare che questa è l' unica mappatura per questa equazione che fornisce 26 caratteri ASCII stampabili unici.

Quindi fondamentalmente questa è la mia mappatura e il mio calcolo di ricerca. Fare la ricerca è semplicemente un caso di eseguire il calcolo e confrontarlo con la mappatura. Aggiungendo 'A'-1all'indice nella mappa si ottiene un carattere AZ.

Puoi provarlo online su TIO, che mostra la mappatura completa di ingressi e uscite. Per completezza la mappatura completa è anche di seguito:

'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

  • Salvato 2 byte modificando la mappatura per rimuoverla +32.
  • Ho salvato 3 byte rendendo Octave solo usando l'indicizzazione logica di 'A':'Z'piuttosto che trovare.
  • Salvato 6 byte eseguendo la somma delle moltiplicazioni usando la moltiplicazione di matrici.

Approccio intelligente, forse troppo intelligente? 53 byte, in base alla mia risposta
MATL

@Sanchise forse, ma è stato l'approccio che ho trovato ¯_ (ツ) _ / ¯. Puoi pubblicare la tua versione come risposta separata.
Tom Carpenter,

Ho pensato, e sono d'accordo sul fatto che è più interessante avere approcci diversi che semplicemente copiare l'approccio più breve. Volevo solo confrontare gli approcci, penso che il tuo sia più intelligente, ma suppongo che il set di dati abbia appena consentito un approccio basato su mod semplice (non sono sicuro che sia una coincidenza o statisticamente probabile)
Sanchises,

3

JavaScript (Chrome), 102

Nota Sfortunatamente funziona solo in Chrome, a causa delle approssimazioni dipendenti dall'implementazione in parseInt () (grazie @Arnauld)

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

Ho cercato una funzione hash, prendendo una porzione di ogni nome, convertendola in numeri usando la base 36 e quindi applicando un modulo.

Ho usato questo codice per cercare il miglior hash:

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

E i risultati:

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

La migliore funzione hash fornisce 26 valori diversi tra 0 e 50, ma ne ho usato uno diverso, con 1 duplicato ma un intervallo più piccolo.

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


Potresti voler dire che funziona solo su Chrome a causa delle approssimazioni dipendenti dall'implementazione in parseInt().
Arnauld,

@Arnauld grazie, non lo sapevo.
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;}

Stesso approccio della risposta di KSab . C non fornisce una hashfunzione stringa come Python. O lo fa?

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

Provalo online!

hrestituisce un i intcui valori sono i codici ASCII per A .. Z.


2

Javascript, 98 byte

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

Ho scoperto che la combinazione del 2o e del 4o carattere dei nomi è unica per ciascuno di essi.

Quindi creo una stringa con le combinazioni di name[4] + name[2], no name[2] + name[4]o avrei una ripetizione del gruppo ehdi caratteri del nome Aretha Franklin ehe quando Smokey Robinson e Johnny Cash oehnsono concatenati.

Potrei semplicemente spostare Johnny Cash in un'altra posizione della stringa e ottenere una mappatura diversa, ma concatenare il 4o e il 2o carattere in questo ordine evita la collisione e lascia intatto l'ordine del set di dati senza aggiungere più lunghezza alla soluzione. Quindi ho deciso di andare in quel modo (è solo una preferenza personale)

Cerco la posizione della concatenazione della 4a e 2a lettera del parametro dato nella stringa e la divido per 2 in modo da ottenere un numero compreso tra 0 e 25. Quindi aggiungo 10 e lo converto in stringa dalla base 36, dove 10 corrisponde a ae 35 az

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


molto mannaia la combinazione che hai trovato!
Joyal,

aaah si. fuori rotta. ho qualcosa di abbastanza simile, ma invece di aggiungere il carattere per tornare nella stringa, la posizione dell'evento potrebbe salvare 25 caratteri. Intelligente!
nl-x


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/

Provalo online!

231 byte dopo aver rimosso le nuove righe.

Questo è molto lungo, ma /// non può gestire genericamente caratteri diversi. In altre parole, /// non supporta regex.


0

Excel, 96 byte

Dopo aver sprecato troppo tempo a provare altri approcci, ho implementato l'approccio di @Eduardo Paez:

=CHAR(FIND(MID(A1,5,1)&MID(A1,3,1),"her DbMbdvsv tdeicsm hnhltirac c i uCyrbOyCmeoie nMn")/2+65)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.