26 chanteurs, 26 lettres

34

Selon RollingStone , voici les 26 plus grands chanteurs de tous les temps:

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

Vous pouvez obtenir ceci sous forme de liste de chaînes ici .

Tâche

Étant donné un nom de chanteur, imprimer ou retourner une lettre Aà Zqui identifie de manière unique ce chanteur. (Si votre code renvoie A pour Bob Dylan , il ne peut pas renvoyer A pour un autre chanteur.)

Contrairement à d'autres défis similaires, la cartographie vous appartient tant que vous évitez les collisions.

Règles

  • L’entrée est l’un des 26 noms de chanteurs énumérés ci-dessus avec cette orthographe exacte et sans aucun espace au début ni à la fin.
  • Vous pouvez écrire la lettre en minuscule ou en majuscule. Mais cela doit être cohérent.
  • Nous vous encourageons à fournir une suite de tests pour les 26 entrées possibles.
  • C'est du , donc la réponse la plus courte en octets gagne!
Arnauld
la source
17
Cher Rolling Stone, Bob Dylan est vraiment l'un des plus grands musiciens de tous les temps. Mais un grand chanteur ?
Luis Mendo
@LuisMendo Je suis un peu salé de quelques - uns de ces choix aussi bien ( toux toux où Steve Tyler toux )
Lord Farquaad
@ LordFarquaad Steve Tyler est le # 99 ¯ \ _ (ツ) _ / ¯
Arnauld
cela peut aider quelqu'un, mais je n'ai pas les compétences en informatique pour utiliser l'info: les lettres 1-6, 1-8 et 3-5 lettres des noms sont des combinaisons uniques.
Jeutnarg

Réponses:

2

MATL , 28 octets

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

Essayez-le en ligne!

Explication

s98\40\

Obtenir implicitement la chaîne d'entrée. Faites la somme des caractères de la chaîne d'entrée et faites-le module 98 suivi du module 40. Résultat dans l'un des nombres suivants: 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 (dans l'ordre de la liste de Pastebin).

2Y2'ijkl o qst uz'h

Appuyez sur l'alphabet (minuscule) avec 2Y2. Ceci prend en charge les nombres dans l'intervalle [1,26]. Cependant, certains nombres manquent et nous avons des nombres allant jusqu'à 38. Par conséquent, nous ajoutons ( h) une chaîne qui prend en charge les nombres les plus élevés, en mappant ces nombres aux lettres «manquantes». Les espaces peuvent être n'importe quoi, j'ai utilisé des majuscules dans mon programme original pour ma propre commodité.

w)

Nous pouvons maintenant indexer le nombre de la première étape dans la chaîne de la deuxième étape avec ). Nous utilisons wpour obtenir les arguments dans le bon ordre. Il peut sembler que nous utilisions une indexation basée sur 0 (les nombres varient de 0 à 38, et une chaîne de 39 caractères), mais la réalité est en réalité un peu plus compliquée: nous utilisons l’indexation modulaire à 1, une fonctionnalité unique en son genre. MATL. Cela signifie que les 1index vers a, les 38index vers uet les 0index vers la fin zde la chaîne.

Sanchises
la source
23

Python 2 , 80 71 octets

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

Essayez-le en ligne!

Les sommes des ordinaux modded donnent des nombres entre 0et38

Les nombres supérieurs à 25 sont ensuite décalés pour remplir les blancs comme ci-dessous (séquence triée affichée):

  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

Soustrayez 18si 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

Ajouter 3si 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

Soustrayez 8si 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

Ce qui donne la séquence 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

Ceux-ci sont ensuite convertis en A-Zavecchr(i+65)

TFeld
la source
Je pense que vous pouvez réduire (i>31)à i/32, etc
xnor
21

6502 routine de code machine (C64), 83 octets

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

C'est un code indépendant de la position, mettez-le simplement quelque part dans la RAM et sautez-y, par exemple en utilisant la syscommande.

Démo en ligne (chargement vers$C000/49152).

Utilisation: sys49152,"[name]" , par exemple sys49152,"Aretha Franklin".

Important: Si le programme a été chargé à partir du disque (comme dans la démonstration en ligne), lancez d'abord une newcommande! Cela est nécessaire car le chargement d'un programme machine supprime certains pointeurs C64 BASIC.

Remarque: le C64 est par défaut en mode sans lettres minuscules. Pour pouvoir saisir des noms lisibles , passez tout d'abord en mode minuscule en appuyant sur SHIFT+ CBM.


Explication

Le défi consiste en fait à trouver une fonction de hachage parfaite minimale pour ces noms; pour le C64, je devais en trouver un facilement calculable en opérations 8 bits simples. Voici une liste de désassemblage commentée:

.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 de tests (C64 BASIC, contenant la routine de code machine en datalignes)

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

Démo en ligne de la suite de tests .

Felix Palmen
la source
13

Python 2 , 68 octets

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

Essayez-le en ligne!

ovs
la source
1
intéressant de savoir comment vous avez composé cela
Sarge Borsch
2
@SargeBorsch hash (n) calcule un entier unique pour chaque nom. Les opérations modulo gardent toujours ces entrées uniques, mais réduisent leur valeur. La deuxième partie ( chr(65+i-i/25*2-i/29*21+i/35*2)) est similaire à la réponse de TFelds . Les opérations modulo sont renforcées par un script que j'ai déjà utilisé ici et ici .
ovs
10

Javascript, 138 132 caractères

Comme toutes les initiales sont uniques, à l'exception de MJ= M ichael J ackson / M e Jick J agger, je vérifie plus particulièrement Michael Jackson (le seul avec un h4ème position), et pour tous les autres noms, j'ai créé une chaîne avec les initiales suivies par une lettre unique.

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

Extrait de code

Essayez-le ici:

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
la source
Il peut y avoir une fonction de hachage plus courte, mais j'aime bien l'idée d'essayer quelque chose qu'un humain pourrait faire. Cependant, j'aimerais que vous utilisiez la fonctionnalité d'extrait de code au lieu de vous lier à JSFiddle.
trlkly
@trlkly J'ai utilisé la fonctionnalité d'extrait de code maintenant.
nl-x
7

Java (OpenJDK 8) , 128 126 115 113 octets

Pas trop mal pour une soumission java!

Merci à Kevin de m'avoir épargné beaucoup d'octets avec les expressions 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);}

Essayez-le en ligne!

Luke Stevens
la source
1
Bonne réponse, +1 de moi. Je travaille aussi actuellement sur une solution Java en créant un script. Pas de chance pour l'instant cependant. Au fait, vous pouvez jouer au golf deux octets en changeant {a+=i;}dea+=i;
Kevin Cruijssen
1
@KevinCruijssen À la vôtre, je ne peux pas croire que j'ai raté ça! J'ai écrit un script pour essayer de trouver le «nombre magique» qui me donnerait des valeurs uniques comprises entre 0 et 25, mais le mieux que je pouvais faire était de 24, d'où les déclarations si à la fin.
Luke Stevens
1
Hmm btw, puisque vous utilisez Java 8, vous pouvez aussi jouer char g(String s)au golf s->. J'ai modifié votre TIO pour montrer comment procéder, au cas où vous ne seriez habitué qu'aux méthodes Java 7.
Kevin Cruijssen
Merci, je n'avais jamais réalisé que tu pouvais faire ça, je mettrai à jour ma soumission (encore!)
Luke Stevens
Hahaha, vous pouvez dire que je suis novice dans ce domaine
Luke Stevens
5

Python 3, 132 99 96 octets

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

Essayez-le en ligne!

Pas brillamment au golf, mais je pensais tenter le coup.

-33 octets grâce aux modifications apportées par TFeld.
-3 octets en utilisant findau lieu de indexgrâce à ovs.

LyricLy
la source
Vous pouvez économiser 6 octets en utilisant sum(map(ord,m)), j'ai aussi ajouté Aretha Franklin pour 128 octets
TFeld 10/10
Et vous pouvez utiliser chr(97+...)au lieu de ascii_lowercase: 99 octets
TFeld
1
Qu'en est-il d'une explication?
Matsemann 10/10
3
Une explication: sum(map(ord,m))additionne les valeurs ASCII des caractères de la chaîne m(donne les entiers compris entre 702 et 1506). Puis appelle , chril la convertit en un caractère (Unicode) avec ce numéro: chr(702)est ʾ à chr(1506) = עet beaucoup entre les deux. Cette solution cherche simplement ce caractère dans une liste de tous les caractères possibles (26) pour obtenir l'index (0 à 26), puis renvoie le caractère avec le code ASCII 97 + cet index (donc 'a' à 'z').
ShreevatsaR
1
Votre solution actuelle contient toujours une version à 99 octets. Vous vouliez utiliser la version d'OVS?
nl-x
5

PHP, 90 88 86 72 + 1 octets

pourrait devenir encore plus court avec un modulo différent.

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

Enregistrez dans un fichier et exécutez-le comme un tuyau -nFou essayez-le en ligne .

Titus
la source
2
Aretha Franklin et Paul McCartney produisent tous les deux Wsur vos cas de test, et il n'y a pas de Xsortie. Je ne sais pas s'il s'agit d'une erreur dans le code lui-même ou si vous essayez simplement la conversion en ligne :)
crazyloonybin 10/10
1
@ typo de remplacement crazyloonybin corrigé. Merci d'avoir laissé entendre.
Titus
Alors, comment je fais ça? Votre code "essayez-le en ligne" n'utilise pas la <?=pièce. Et le 'Run as pipe`, je ne travaille pas. En outre, je reçois des avis lorsque j'essaie de l'exécuter en ligne de commande.
nl-x
@ Titre: Dans CodeGolf, vous devez donner la fonction complète ou l'application qui génère (uniquement) la sortie souhaitée. Je suis familier avec <?=... Donc ma question est toujours, comment puis-je exécuter votre code (en ligne de commande)? Je ne parviens pas à le nourrir $argnen ligne de commande ... Tous mes essais jusqu'à présent donnent des artefacts et semblent toujours nécessiter plus de code pour le faire fonctionner.
nl-x
@ nl-x Votre PHP donne des avis, c'est parce que vous ne lui avez pas donné l'option n:echo <input> | php -nF <scriptfilename>
Titus
4

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

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

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

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

Grâce au commentaire de Dom, nous avons pu économiser 4 octets supplémentaires, qui ont également été changés en majuscules pour mieux répondre aux besoins.

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

Essayez-le en ligne

Nahuel Fouilleul
la source
Belle approche! Je pense que vous avez besoin d'écrire / marquer toute une fonction appelable si?
Felix Palmen
@FelixPalmen, c'est un programme perl qui peut s'appeler inline: perl -pe '$_=crypt$_,mO;/..(.)/;$_=$1;y/035eft/AHPRXZ/;$_=lc'ajout d'un lien vers tio
Nahuel Fouilleul
Agréable! Je cherchais une approche similaire, $1^$2mais je n’avais pas pensé à l’utiliser crypt... Vous pouvez économiser 4 octets avec quelques réorganisations: essayez-le en ligne!
Dom Hastings
4

Python 2, 50 43 octets

Crédit à japh pour la nouvelle version

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

Essayez-le en ligne!

Remarque: Cela dépend de la commande hashintégrée et ne fonctionnera pas dans toutes les implémentations.

KSab
la source
43 octets:lambda n:chr(hash(n)%2354%977%237%54%26+65)
japh
@japh Nice! Mon vérificateur de force brute en python n'était clairement pas assez rapide;)
KSab
3

Ruby, 63 octets

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

Ajoute les codes ascii de l’entrée, les prend mod 98 puis mod 66 pour obtenir l’un des 26 nombres uniques ndans la plage 0..65. L'énorme nombre hexadécimal contient un 1bit dans chacun de ces 26 emplacements. Ainsi, en le décalant avec des droits, nnous obtenons un nombre contenant 1..26 1bits. Nous comptons les 1bits en ajoutant les codes ASCII et en prenant le mod 48, puis nous ajoutons 64 et les convertissons en code ASCII.

Programme de test

les mapitèrent à travers les chanteurs imprimant le code lettre et le chanteur. Il retourne ensuite un tableau des codes de lettre, qui est sortédité pour démontrer que chaque lettre est utilisée une fois.

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

Sortie

["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
la source
3

Octave , 85 83 80 74 octets

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

Ce fouillis d’anonymat est le résultat d’une foutaise dans MATLAB qui tente de trouver un bon moyen de coder les données.

Fondamentalement, après une analyse rapide, seules les lettres 1, 2 et 8 de la chaîne d'entrée (la plus petite chaîne est composée de 8 caractères, nous sommes donc bons) sont nécessaires pour produire une valeur unique à partir de chaque entrée. La partie difficile est alors de convertir cette valeur unique en quelque chose d’utilisable.

MATLAB supporte mal la compression des données. J'ai donc dû rechercher un autre moyen de mapper le mappage de recherche. Je me suis mis à la recherche d’une fonction sur les trois lettres d’entrée qui donnait une valeur unique qui était aussi une valeur ASCII imprimable afin de pouvoir incorporer le mappage dans une chaîne d’un caractère par entrée.

Il s'avère que cette matrice qui multiplie les caractères d'index [1 2 8]par la matrice entière [1;15;47], puis exécute le mod 124, donne des valeurs uniques qui sont toutes imprimables en ASCII (et aucune n'est un 'caractère susceptible de semer la confusion dans les chaînes de caractères). Heureusement la cartographie se termine par TIOce qui est complètement accidentel. Fait intéressant, il s'agit du seul mappage de cette équation qui donne 26 caractères ASCII imprimables uniques.

Donc, en gros, c’est ma cartographie et mon calcul de recherche. La recherche consiste simplement à effectuer le calcul et à comparer le mappage. L'ajout 'A'-1à l'index de la carte donne un caractère AZ.

Vous pouvez l' essayer en ligne sur TIO, qui montre la cartographie complète des entrées et des sorties. Pour être complet, le mappage complet est également présenté ci-dessous:

'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

  • Sauvegardé 2 octets peaufinant le mappage à supprimer +32.
  • Sauvegardé 3 octets en faisant Octave uniquement en utilisant l'indexation logique de 'A':'Z'plutôt que trouver.
  • Sauvegardé 6 octets en faisant la somme de multiplications en utilisant la multiplication de matrice.
Tom Carpenter
la source
Une approche intelligente, peut-être trop intelligente? 53 octets, basé sur ma réponse MATL
Sanchises
@Sanchises peut-être, mais c'est l'approche que j'ai proposée avec ¯_ (ツ) _ / ¯. Vous êtes invités à poster votre version en tant que réponse séparée.
Tom Carpenter
J'ai pensé, et je suis d'accord qu'il est plus intéressant d'avoir des approches différentes que de simplement copier l'approche la plus courte. Je voulais juste comparer les approches, je pense que le vôtre est plus intelligent , mais je suppose que l'ensemble de données juste permis une approche basée sur le mod-facile (pas sûr que ce soit une coïncidence ou statistiquement probable)
Sanchises
3

JavaScript (Chrome), 102

Note Malheureusement, cela ne fonctionne que dans Chrome, à cause des approximations dépendantes de l'implémentation dans parseInt () (merci @Arnauld)

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

J'ai cherché une fonction de hachage, prenant une tranche de chaque nom, la convertissant en nombres en utilisant la base 36, puis en appliquant un modulo.

J'ai utilisé ce code pour rechercher le meilleur 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)
      }

Et les résultats:

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 meilleure fonction de hachage donne 26 valeurs différentes entre 0 et 50, mais j'ai utilisé une valeur différente, avec 1 duplicata mais avec une plage plus petite.

Tester

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
la source
Vous voudrez peut-être mentionner que cela ne fonctionne que sur Chrome en raison d' approximations dépendantes de l' implémentation dans parseInt().
Arnauld
@Arnauld merci, je ne savais pas.
Edc65
3

C, 65 55 49 octets

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

Même approche que la réponse de KSab . C ne fournit pas une hashfonction de chaîne comme Python. Ou le fait-il?

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

Essayez-le en ligne!

hrenvoie un intdont les valeurs sont les codes ASCII pour A .. Z.

japh
la source
2

Javascript, 98 octets

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

J'ai trouvé que la combinaison du 2ème et du 4ème caractère des noms est unique pour chacun d'eux.

Par conséquent, je crée une chaîne avec les combinaisons de name[4] + name[2], pas name[2] + name[4]ou j'aurais une répétition du groupe ehde caractères du prénom Aretha Franklin ehet lorsque Smokey Robinson et Johnny Cash oehnsont concaténés.

Je pourrais simplement déplacer Johnny Cash à un autre emplacement de la chaîne et obtenir un mappage différent, mais concaténer le 4ème et le 2ème caractère dans cet ordre évite la collision et laisse l'ordre de jeu de données intact sans ajouter plus de longueur à la solution. J'ai donc décidé de suivre cette voie (c'est juste une préférence personnelle)

Je recherche la position de la concaténation des 4ème et 2ème lettres du paramètre donné dans la chaîne et la divise par 2 pour obtenir un nombre compris entre 0 et 25. Ensuite, j'ajoute 10 et le convertis en chaîne à partir de la base 36, où 10 correspond à aet 35 àz

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
la source
très coupé la combinaison que vous avez trouvé!
Joyal
aaah oui. bien sur. J'ai quelque chose d'assez similaire, mais au lieu d'ajouter le caractère à renvoyer dans la chaîne, la position de l'occurrence pourrait économiser 25 caractères. Intelligent!
nl-x
1

Wolfram Language (Mathematica) , 101126 octets

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

+32semble conduire à la table de hachage la plus courte de Mathematica InputForm.

Essayez-le en ligne!

Keyu Gan
la source
1

///, 390 231 octets

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

Essayez-le en ligne!

231 octets après la suppression des nouvelles lignes.

C'est très long, mais /// ne peut pas gérer différents caractères de manière générique. En d'autres termes, /// ne supporte pas les regex.

utilisateur202729
la source
0

Excel, 96 octets

Après avoir perdu trop de temps à essayer d'autres approches, nous avons mis en œuvre l'approche de @Eduardo Paez:

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