26 cantantes, 26 letras

34

Según RollingStone , a continuación se encuentran los 26 mejores cantantes de todos los tiempos:

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

Puede obtener esto como una lista de cadenas aquí .

Tarea

Dado un nombre de cantante, imprimir o devolver una carta de Aa Zla que identifica de forma exclusiva este cantante. (Si su código devuelve A para Bob Dylan , entonces no puede devolver A para ningún otro cantante).

A diferencia de otros desafíos similares, el mapeo depende de usted siempre que esté libre de colisiones.

Reglas

  • Se garantiza que la entrada sea uno de los 26 nombres de cantantes mencionados anteriormente con esta ortografía exacta y sin espacios en blanco iniciales o finales.
  • Puede mostrar la letra en minúsculas o mayúsculas. Pero debe ser consistente.
  • Le recomendamos que proporcione un conjunto de pruebas para las 26 entradas posibles.
  • Este es el , por lo que gana la respuesta más corta en bytes.
Arnauld
fuente
17
Querido Rolling Stone: Bob Dylan es verdaderamente uno de los mejores músicos de la historia. ¿Pero un gran cantante ?
Luis Mendo
@LuisMendo estoy un poco salada sobre algunas de estas opciones también ( tos tos dónde está Steve Tyler tos )
Lord Farquaad
@LordFarquaad Steve Tyler es # 99 ¯ \ _ (ツ) _ / ¯
Arnauld
Esto puede ayudar a alguien, pero no tengo las habilidades de CG para usar la información: las letras 1-6, 1-8 y 3-5 de los nombres son combinaciones únicas.
Jeutnarg

Respuestas:

2

MATL , 28 bytes

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

Pruébalo en línea!

Explicación

s98\40\

Implícitamente obtiene la cadena de entrada. Suma los caracteres de la cadena de entrada y hazlo módulo 98 seguido del módulo 40. Resultados en uno de los siguientes números: 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 (en orden de la lista de Pastebin).

2Y2'ijkl o qst uz'h

Empuje el alfabeto (minúscula) con 2Y2. Esto se encarga de los números en el rango [1,26]. Sin embargo, faltan algunos números, y tenemos números hasta 38. Por lo tanto, agregamos ( h) una cadena que se ocupa de los números más altos, asignando estos números a las letras 'faltantes'. Los espacios pueden ser cualquier cosa, utilicé letras mayúsculas en mi programa original para mi propia conveniencia.

w)

Ahora podemos indexar el número del primer paso en la cadena del segundo paso con ). Usamos wpara obtener los argumentos en el orden correcto. Si bien puede parecer que usamos indexación basada en 0 (los números varían de 0 a 38 y la cadena tiene 39 caracteres de largo), la realidad es un poco más complicada: utilizamos indexación modular basada en 1, una característica exclusiva de MATL. Esto significa que 1indexa a, 38indexa ue 0indexa al final zde la cadena.

Sanchises
fuente
23

Python 2 , 80 71 bytes

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

Pruébalo en línea!

Las sumas de ordinales modificados dan números entre 0y38

Los números mayores que 25 se desplazan para completar los espacios en blanco como se muestra a continuación (se muestra la secuencia ordenada):

  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

Resta 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

Agregar 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

Resta 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

Que da la secuencia 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

Estos luego se convierten a A-Zconchr(i+65)

TFeld
fuente
Creo que se puede acortar (i>31)a i/32, etc
XNOR
21

6502 rutina de código de máquina (C64), 83 bytes

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

Este es un código independiente de la posición, simplemente colóquelo en algún lugar de la RAM y salte allí, por ejemplo, utilizando el syscomando

Demostración en línea (cargas a$C000/49152).

Uso: sys49152,"[name]" por ej sys49152,"Aretha Franklin".

Importante: si el programa se cargó desde el disco (como en la demostración en línea), ¡emita newprimero un comando! Esto es necesario porque cargar un programa de máquina destruye algunos punteros BÁSICOS C64.

Nota: El C64 está por defecto en un modo sin letras minúsculas, para poder ingresar legible nombres , primero cambie al modo minúsculas presionando SHIFT+ CBM.


Explicación

El desafío es, de hecho, encontrar una función hash perfecta mínima para estos nombres; para el C64, tuve que encontrar uno que sea fácilmente computable en operaciones simples de 8 bits. Aquí hay un listado de desmontaje comentado:

.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

Conjunto de pruebas (C64 BASIC, que contiene la rutina del código de máquina en datalíneas)

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

Demostración en línea del conjunto de pruebas .

Felix Palmen
fuente
13

Python 2 , 68 bytes

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

Pruébalo en línea!

ovs
fuente
1
interesante saber cómo compusiste esto
Sarge Borsch
2
@SargeBorsch hash (n) calcula un número entero único para cada nombre. Las operaciones de módulo aún mantienen esas entradas únicas, pero disminuye su valor. La segunda parte ( chr(65+i-i/25*2-i/29*21+i/35*2)) es similar a la respuesta de TFelds . Las operaciones de módulo son forzadas por un script que ya usé aquí y aquí .
ovs
10

Javascript, 138 132 caracteres

Como todas las iniciales son únicas, a excepción de MJ= M ichael J ackson / M ick J agger, verifico específicamente a Michael Jackson (el único con un hen la cuarta posición), y para todos los demás nombres, creé una cadena con las iniciales seguidas por una carta única

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

Fragmento de código

Pruébalo aquí:

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
fuente
Puede haber una función de hash más corta, pero me gusta la idea de intentar algo que un humano pueda hacer. Sin embargo, desearía que usaras la función de fragmento de código en lugar de vincular a JSFiddle.
Trlyly
@trlkly utilicé la función de fragmento de código ahora.
nl-x
7

Java (OpenJDK 8) , 128 126 115 113 bytes

¡No está mal para una presentación de Java!

¡Gracias a Kevin por salvarme muchos bytes con las expresiones 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);}

Pruébalo en línea!

Luke Stevens
fuente
1
Buena respuesta, +1 de mi parte. Actualmente también estoy trabajando en una solución Java creando un script. Sin embargo, hasta ahora no he tenido suerte. Por cierto, puedes jugar dos bytes cambiando {a+=i;}aa+=i;
Kevin Cruijssen
1
@KevinCruijssen Cheers, ¡no puedo creer que me haya perdido eso! Escribí un script para tratar de encontrar el 'número mágico' que me daría valores únicos entre 0 y 25, pero lo mejor que pude hacer fue 24, de ahí las declaraciones if al final.
Luke Stevens
1
Hmm por cierto, dado que está utilizando Java 8, también puede golf char g(String s)a s->. Modifiqué tu TIO para mostrar cómo hacerlo, en caso de que solo estés acostumbrado a los métodos Java 7.
Kevin Cruijssen
Gracias, nunca me di cuenta de que podía hacer eso, actualizaré mi presentación (¡otra vez!)
Luke Stevens
Jajaja, puedes decir que soy nuevo en esto
Luke Stevens
5

Python 3, 132 99 96 bytes

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

Pruébalo en línea!

No jugaba al golf de manera brillante, pero pensé en intentarlo.

-33 bytes gracias a las modificaciones realizadas por TFeld.
-3 bytes usando en findlugar de indexgracias a los ovs.

LyricLy
fuente
Puede guardar 6 bytes usando sum(map(ord,m)), también agregué Aretha Franklin por 128 bytes
TFeld
Y puede usar en chr(97+...)lugar de ascii_lowercase: 99 bytes
TFeld
1
¿Qué tal una explicación?
Matsemann
3
Una explicación: sum(map(ord,m))suma los valores ASCII de los caracteres en la cadena m(da enteros en el rango 702-1506). Luego, llamarlo chrlo convierte en un carácter (Unicode) con ese número: chr(702)is ʾ to chr(1506) = עy mucho en el medio. Esta solución simplemente busca este carácter en una lista de todos los caracteres posibles (26) para obtener el índice (0–26), luego devuelve el carácter con el código ASCII 97 + ese índice (entonces 'a' a 'z').
ShreevatsaR
1
Su solución actual todavía contiene una versión de 99 bytes. ¿Querías usar la versión de OVS?
nl-x
5

PHP, 90 88 86 72 + 1 bytes

podría acortarse aún más con un módulo diferente.

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

Guardar en el archivo y ejecutar como canalización -nFo probarlo en línea .

Titus
fuente
2
Aretha Franklin y Paul McCartney salen Wen sus casos de prueba, y no hay Xsalida. No sé si es un error en el código en sí o simplemente la conversión de prueba en línea :)
crazyloonybin
1
Se corrigió el error de reemplazo de @crazyloonybin. Gracias por insinuar.
Titus
Entonces, ¿cómo ejecuto esto? Su código 'pruébelo en línea' no usa la <?=parte. Y el 'Ejecutar como tubería' no estoy trabajando. Además, recibo avisos cuando intento ejecutarlo desde la línea de comandos.
nl-x
@Titus: en CodeGolf debe proporcionar la función o aplicación completa que genera (solo) la salida deseada. Estoy familiarizado con <?=... Entonces mi pregunta es, ¿cómo ejecuto su código (desde la línea de comandos)? No puedo alimentarlo $argnen la línea de comando ... Todos mis intentos hasta ahora dan artefactos y todavía parecen requerir más código para que se ejecute.
nl-x
@ nl-x Tu PHP genera avisos, es porque no le diste la opción n:echo <input> | php -nF <scriptfilename>
Titus
4

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

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

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

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

Gracias al comentario de Dom podría ahorrar 4 bytes más, también cambió a mayúsculas para ajustarse a los mejores requisitos.

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

Pruébalo en línea

Nahuel Fouilleul
fuente
Buen enfoque! Sin embargo, ¿creo que necesita escribir / calificar una función invocable completa?
Felix Palmen
@FelixPalmen, es un programa perl que se puede llamar en línea: perl -pe '$_=crypt$_,mO;/..(.)/;$_=$1;y/035eft/AHPRXZ/;$_=lc'agregar enlace a tio
Nahuel Fouilleul
¡Agradable! Estaba buscando un enfoque similar, $1^$2pero no pensé en usarlo crypt... Puede guardar 4 bytes con algunos reordenamientos: ¡ Pruébelo en línea!
Dom Hastings
4

Python 2, 50 43 bytes

Crédito a japh por la nueva versión

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

Pruébalo en línea!

Nota: Esto depende de lo hashincorporado y no funcionará en todas las implementaciones

KSab
fuente
43 bytes: lambda n:chr(hash(n)%2354%977%237%54%26+65)
japh
@japh Nice! Mi corrector de fuerza bruta de Python claramente no fue lo suficientemente rápido;)
KSab
3

Ruby, 63 bytes

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

Agrega los códigos ascii de la entrada, los toma mod 98 y luego mod 66 para obtener uno de los 26 números únicos nen el rango 0..65. El gran número hexadecimal contiene un 1bit en cada uno de estos 26 lugares, por lo que al desplazarlo con el derecho nobtenemos un número con 1..26 1bits. Contamos los 1bits agregando los códigos ascii y tomando mod 48, luego agregamos 64 y convertimos a un código ASCII.

Programa de prueba

el mapitera a través de los cantantes que imprimen el código de la letra y el cantante. Luego devuelve una matriz de códigos de letras, que se sortedita para demostrar que cada letra se usa una vez.

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

Salida

["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
fuente
3

Octava , 85 83 80 74 bytes

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

Este desorden anónimo es el resultado de algunos errores en MATLAB tratando de encontrar una buena manera de codificar los datos.

Básicamente, después de un análisis rápido, solo se necesitan las letras 1,2 y 8 de la cadena de entrada (la cadena más pequeña es de 8 caracteres, por lo que estamos bien) para producir un valor único de cada entrada. La parte difícil es convertir ese valor único en algo utilizable.

MATLAB es terrible para comprimir datos, así que tuve que buscar otra forma de hacer el mapeo de búsqueda. Me propuse tratar de encontrar alguna función en las tres letras de entrada que resultaran en un valor único que también fuera un valor ASCII imprimible para poder incrustar la asignación en una cadena de un carácter por entrada.

Resulta que la matriz que multiplica los caracteres en el índice [1 2 8]por la matriz entera [1;15;47]y luego realiza el mod 124 da como resultado valores únicos que todos los ASCII imprimibles (y ninguno es un 'carácter que fastidie los literales de cadena). Agradablemente el mapeo termina con lo TIOcual es completamente accidental. Curiosamente, este es el único mapeo para esta ecuación que proporciona 26 caracteres ASCII imprimibles únicos.

Básicamente, ese es mi mapeo de búsqueda y cálculo. Hacer la búsqueda es simplemente un caso de realizar el cálculo y compararlo con el mapeo. Agregar 'A'-1al índice en el mapa da como resultado un carácter AZ.

Puede probarlo en línea en TIO, que muestra la asignación completa de entradas y salidas. Para completar, el mapeo completo también está a continuación:

'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

  • Se guardó la asignación de ajustes de 2 bytes para eliminar +32.
  • Ahorró 3 bytes al hacer solo Octave usando indexación lógica de en 'A':'Z'lugar de find.
  • Ahorro de 6 bytes al hacer la suma de multiplicaciones usando la multiplicación de matrices.
Tom Carpenter
fuente
Enfoque inteligente, tal vez demasiado inteligente? 53 bytes, basado en mi respuesta
MATL
@Sanchises posiblemente, pero fue el enfoque que se me ocurrió ¯_ (ツ) _ / ¯. Puede publicar su versión como una respuesta por separado.
Tom Carpenter
Pensé, y estoy de acuerdo en que es más interesante tener enfoques diferentes que simplemente copiar el enfoque más corto. Solo quería comparar los enfoques, creo que el tuyo es más inteligente, pero supongo que el conjunto de datos solo permitió un enfoque basado en mods fácil (no estoy seguro si es una coincidencia o es estadísticamente probable)
Sanchises
3

JavaScript (Chrome), 102

Nota Desafortunadamente, solo funciona en Chrome, debido a aproximaciones dependientes de la implementación en parseInt () (gracias @Arnauld)

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

Busqué una función hash, tomando una porción de cada nombre, convirtiendo a números usando la base 36 y luego aplicando un módulo.

Usé este código para buscar el mejor 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)
      }

Y los resultados:

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 mejor función hash da 26 valores diferentes entre 0 y 50, pero utilicé uno diferente, con 1 duplicado pero un rango más pequeño.

Prueba

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
fuente
Es posible que desee mencionar que solo funciona en Chrome debido a aproximaciones dependientes de la implementación en parseInt().
Arnauld
@Arnauld gracias, no lo sabía.
edc65
3

C, 65 55 49 bytes

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

El mismo enfoque que la respuesta de KSab . C no proporciona una hashfunción de cadena como Python. O lo hace?

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

Pruébalo en línea!

hdevuelve un intcuyos valores son los códigos ASCII para A .. Z.

japh
fuente
2

Javascript, 98 bytes

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

Descubrí que la combinación de los caracteres segundo y cuarto de los nombres es única para cada uno de ellos.

Por lo tanto, creo una cadena con las combinaciones de name[4] + name[2], no name[2] + name[4]o tendría una repetición del grupo ehde caracteres del primer nombre Aretha Franklin ehy cuando Smokey Robinson y Johnny Cashoehn se concatenan.

Podría mover a Johnny Cash a otra posición de la cadena y obtener un mapeo diferente, pero concatenando el 4 ° y 2 ° carácter en este orden evita la colisión y deja el orden del conjunto de datos intacto sin agregar más longitud a la solución. Así que decidí ir por ese camino (es solo una preferencia personal)

Busco la posición de la concatenación de la 4ª y 2ª letra del parámetro dado en la cadena y la divido por 2 para obtener un número entre 0 y 25. Luego agrego 10 y lo convierto en cadena desde la base 36, donde 10 corresponde a ay 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))

Eduardo Páez Rubio
fuente
¡Muy inteligente la combinación que encontraste!
Joyal
aaah si. por supuesto. Tengo algo bastante similar, pero en lugar de agregar el carácter para regresar en la cadena, la posición de la ocurrencia podría ahorrar 25 caracteres. ¡Inteligente!
nl-x
1

///, 390 231 bytes

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

Pruébalo en línea!

231 bytes después de eliminar las nuevas líneas.

Esto es muy largo, pero /// no puede manejar diferentes caracteres genéricamente. En otras palabras, /// no admite expresiones regulares.

usuario202729
fuente
0

Excel, 96 bytes

Después de perder demasiado tiempo probando otros enfoques, he implementado el enfoque de @Eduardo Paez:

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