26 cantores, 26 letras

34

De acordo com a RollingStone , abaixo estão os 26 maiores cantores de todos os tempos:

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

Você pode obter isso como uma lista de strings aqui .

Tarefa

Dado um nome de cantor, imprimir ou retornar uma carta Apara Zque identifica exclusivamente o cantor. (Se o seu código retornar A para Bob Dylan , ele não poderá retornar A para nenhum outro cantor.)

Ao contrário de outros desafios semelhantes, o mapeamento depende de você , contanto que seja livre de colisões.

Regras

  • A entrada é garantida como um dos 26 nomes de cantor listados acima com essa ortografia exata e sem nenhum espaço em branco à esquerda ou à direita.
  • Você pode imprimir a letra em minúsculas ou maiúsculas. Mas deve ser consistente.
  • Você é incentivado a fornecer um conjunto de testes para todas as 26 entradas possíveis.
  • Isso é , então a resposta mais curta em bytes vence!
Arnauld
fonte
17
Caro Rolling Stone: Bob Dylan é realmente um dos maiores músicos de todos os tempos. Mas um ótimo cantor ?
Luis Mendo
@LuisMendo estou um pouco salgado sobre algumas dessas escolhas, bem como ( tosse tosse onde está Steve Tyler tosse )
Lord Farquaad
@LordFarquaad Steve Tyler é # 99 ¯ \ _ (ツ) _ / ¯
Arnauld
isso pode ajudar alguém, mas não tenho as habilidades de computação gráfica para usar as informações: as letras 1-6, 1-8 e 3-5 dos nomes são combinações únicas.
Jeutnarg 10/10

Respostas:

2

MATL , 28 bytes

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

Experimente online!

Explicação

s98\40\

Obter implicitamente a sequência de entrada. Soma os caracteres da sequência de entrada e faça-o no módulo 98 seguido pelo módulo 40. Resultados em um dos seguintes 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 (na ordem da lista Pastebin).

2Y2'ijkl o qst uz'h

Empurre o alfabeto (minúsculo) com 2Y2. Isso cuida dos números no intervalo [1,26]. No entanto, alguns números estão ausentes e temos números até 38. Portanto, anexamos ( h) uma string que cuida dos números mais altos, mapeando esses números para as letras 'ausentes'. Os espaços podem ser qualquer coisa, usei letras maiúsculas no meu programa original para minha própria conveniência.

w)

Agora podemos indexar o número do primeiro passo na string do segundo passo com ). Usamos wpara obter os argumentos na ordem correta. Embora possa parecer que usamos indexação baseada em 0 (os números variam de 0 a 38 e a string tem 39 caracteres), a realidade é um pouco mais complicada: usamos indexação modular baseada em 1, um recurso exclusivo para MATL. Isso significa que 1indexa para a, 38na verdade indexa para ue 0indexa para a final zda string.

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

Experimente online!

As somas dos ordinais modificados fornecem números entre 0e38

Os números maiores que 25 são então deslocados para preencher os espaços em branco como abaixo (sequência classificada mostrada):

  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

Subtraia 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

Adicione 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

Subtraia 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

O que dá a sequência 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

Estes são então convertidos em A-Zcomchr(i+65)

TFeld
fonte
Eu acho que você pode encurtar (i>31)a i/32, etc
xnor
21

Rotina de código de máquina 6502 (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 é um código independente da posição, basta colocá-lo em algum lugar da RAM e pular para lá, por exemplo, usando o syscomando

Demonstração online (carrega para $C000/ 49152).

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

Importante: Se o programa foi carregado a partir do disco (como na demonstração online), emita um newcomando primeiro! Isso é necessário porque o carregamento de um programa de máquina elimina alguns ponteiros C64 BASIC.

Nota: Por padrão, o C64 está em um modo sem letras minúsculas - para poder inserir nomes legíveis , alterne para o modo minúsculo primeiro pressionandoSHIFT +CBM .


Explicação

O desafio é, de fato, encontrar uma função hash perfeita mínima para esses nomes; para o C64, tive que encontrar um que fosse facilmente computável em operações simples de 8 bits. Aqui está uma lista de desmontagem comentada:

.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 testes (C64 BASIC, contendo a rotina do código da máquina em datalinhas)

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

Demonstração on-line do conjunto de testes .

Felix Palmen
fonte
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)

Experimente online!

ovs
fonte
1
interessante saber como você compor esta
Sarge Borsch
2
O hash @SargeBorsch (n) calcula um número inteiro exclusivo para todos os nomes. As operações do módulo ainda mantêm essas entradas únicas, mas diminuem seu valor. A segunda parte ( chr(65+i-i/25*2-i/29*21+i/35*2)) é semelhante à resposta do TFelds . As operações do módulo são brutais, forçadas por um script que eu já usei aqui e aqui .
ovs 11/11
10

Javascript, 138 132 caracteres

Como todas as iniciais são únicos, com excepção de MJ= H ichael J ACKSON / M ick J Agger, verifico para Michael Jackson especificamente (o único com um hsobre o quarto posição), e para todos os outros nomes Criei uma corda com as iniciais seguido por uma letra única.

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

Fragmento de código

Experimente aqui:

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
fonte
Pode haver uma função de hash mais curta, mas eu gosto da ideia de tentar algo que um humano possa fazer. No entanto, eu gostaria que você usasse o recurso de trecho de código em vez de vincular ao JSFiddle.
trlkly
@trlkly Eu usei o recurso de snippet de código agora.
Nl-x
7

Java (OpenJDK 8) , 128 126 115 113 bytes

Não é muito pobre para uma submissão java!

Obrigado a Kevin por me salvar um monte de bytes com as expressões 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);}

Experimente online!

Luke Stevens
fonte
1
Boa resposta, +1 de mim. Atualmente, também estou trabalhando em uma solução Java, criando um script. Btw, você pode golfe dois bytes, alterando {a+=i;}aa+=i;
Kevin Cruijssen
1
@KevinCruijssen Cheers, não posso acreditar que eu perdi isso! Eu escrevi um script para tentar encontrar o 'número mágico' que me daria valores únicos entre 0 e 25, mas o melhor que pude fazer foi 24, daí as declarações if no final.
Luke Stevens
1
Hmm btw, desde que você está usando Java 8, você também pode golf char g(String s)para s->. Modifiquei seu TIO para mostrar como fazer isso, caso você esteja acostumado apenas aos métodos Java 7.
Kevin Cruijssen 10/10
Obrigado, eu nunca percebi que você poderia fazer isso, eu vou atualizar a minha submissão (de novo!)
Luke Stevens
Hahaha, você pode dizer que eu sou novo nisso
Luke Stevens
5

Python 3, 132 99 96 bytes

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

Experimente online!

Não jogava golfe de maneira brilhante, mas pensei em tentar.

-33 bytes graças a modificações feitas pelo TFeld.
-3 bytes usando em findvez de indexgraças a ovs.

LyricLy
fonte
Você pode salvar 6 bytes usando sum(map(ord,m)), também adicionei Aretha Franklin por 128 bytes #
TFeld 10/10
E você pode usar em chr(97+...)vez de ascii_lowercase: 99 bytes
TFeld 10/10
1
Que tal uma explicação?
Matsemann 10/10
3
Uma explicação: sum(map(ord,m))adiciona os valores ASCII dos caracteres na sequência m(fornece números inteiros no intervalo 702–1506). Em seguida, chamá- chrlo o converte em um caractere (Unicode) com esse número: chr(702)é ʾ para chr(1506) = עe muito no meio. Essa solução simplesmente consulta esse caractere em uma lista de todos os caracteres possíveis (26) para obter o índice (0–26), depois retorna o caractere com código ASCII 97 + esse índice (então 'a' a 'z').
ShreevatsaR
1
Sua solução atual ainda contém uma versão de 99 bytes. Você queria usar a versão da OVS?
Nl-x
5

PHP, 90 88 86 72 + 1 bytes

pode ficar ainda mais curto com um módulo diferente.

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

Salve em arquivo e execute como pipe -nFou experimente online .

Titus
fonte
2
Aretha Franklin e Paul McCartney produzem Wnos seus casos de teste e não há Xsaída. Não sei se é um erro no próprio código ou apenas a experimentá-lo conversão online :)
crazyloonybin
1
Erro de substituição @crazyloonybin corrigido. Obrigado por sugerir.
Titus
Então, como faço para executar isso? O seu código 'experimente online' não usa a <?=peça. E o 'Run as pipe' não estou trabalhando. Além disso, recebo avisos ao tentar executá-lo na linha de comando.
Nl-x
@ Titus: No CodeGolf, você deve fornecer a função ou aplicativo completo que gera (somente) a saída desejada. Estou familiarizado com <?=... Então, minha pergunta ainda é: como executo seu código (na linha de comando)? Falha ao alimentá-lo $argnna linha de comando ... Até agora, todas as minhas tentativas fornecem artefatos e ainda parecem exigir mais código para executá-lo.
Nl-x
@ nl-x Seu PHP gera avisos, é porque você não deu a opção n:echo <input> | php -nF <scriptfilename>
Titus
4

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

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

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

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

Graças ao comentário do Dom, foi possível salvar mais 4 bytes, também alterado para maiúsculas para atender a melhores requisitos.

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

Experimente Online

Nahuel Fouilleul
fonte
Boa abordagem! Eu acho que você precisa escrever / marcar toda uma função que pode ser chamada?
Felix Palmen
@FelixPalmen, é um programa perl que pode ser chamado de linha: perl -pe '$_=crypt$_,mO;/..(.)/;$_=$1;y/035eft/AHPRXZ/;$_=lc'adicionando link para tio
Nahuel FOUILLEUL
Agradável! Estava procurando uma abordagem semelhante, usando $1^$2mas não pensou em usar crypt... Você pode salvar 4 bytes com alguns pedidos novamente: Experimente on-line!
Dom Hastings
4

Python 2, 50 43 bytes

Crédito para japh pela nova versão

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

Experimente online!

Nota: Isso depende do hashembutido e não funcionará em todas as implementações

KSab
fonte
43 bytes:lambda n:chr(hash(n)%2354%977%237%54%26+65)
japh 14/10
@japh Nice! Meu verificador python força bruta claramente não foi rápido o suficiente;)
KSab
3

Ruby, 63 bytes

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

Adiciona os códigos ASCII da entrada, usa o mod 98 e, em seguida, o mod 66 para obter um dos 26 números exclusivos nno intervalo de 0 a 65. O grande número hexadecimal contém um 1pouco em cada um desses 26 locais; portanto, ao deslocar o direito n, obtemos um número com 1 a 26 1bits. Contamos os 1bits adicionando os códigos ascii e usando o mod 48, depois adicionamos 64 e convertemos em um código ASCII.

Programa de teste

o mappercorre o cantores imprimir o código de letras e cantor. Em seguida, ele retorna uma matriz dos códigos das letras, sorteditada para demonstrar que cada letra é usada uma 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

Saída

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

Oitava , 85 83 80 74 bytes

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

Essa bagunça de um anônimo é o resultado de algumas bagunças no MATLAB tentando encontrar uma boa maneira de codificar os dados.

Basicamente, após uma análise rápida, são necessárias apenas as letras 1,2 e 8 da sequência de entrada (a menor seqüência é de 8 caracteres, portanto, somos bons) para produzir um valor único para cada entrada. A parte difícil é então converter esse valor único em algo utilizável.

O MATLAB é péssimo na compactação de dados, então tive que procurar outra maneira de fazer o mapeamento de pesquisa. Comecei a tentar encontrar alguma função nas três letras de entrada que resultassem em um valor único que também fosse um valor ASCII imprimível, para que eu pudesse incorporar o mapeamento em uma sequência de um caractere por entrada.

Acontece que a matriz multiplicando os caracteres no índice [1 2 8]pela matriz inteira [1;15;47]e, em seguida, realizando o mod 124 resulta em valores únicos, todos os ASCII imprimíveis (e nenhum é um 'caractere que possa causar erros literais em strings). Agradavelmente, o mapeamento termina com o TIOque é completamente acidental. Curiosamente, este é o único mapeamento para essa equação que fornece 26 caracteres ASCII imprimíveis exclusivos.

Basicamente, esse é o meu mapeamento e cálculo de pesquisa. Fazer a pesquisa é simplesmente um caso de executar o cálculo e comparar com o mapeamento. Adicionando'A'-1 ao índice no mapa resulta em um caractere AZ.

Você pode experimentá-lo online no TIO, que mostra o mapeamento completo de entradas e saídas. Para completar, o mapeamento completo também está abaixo:

'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

  • Salva 2 bytes ajustando o mapeamento para remover +32.
  • Economizou 3 bytes, tornando o Octave somente usando indexação lógica em 'A':'Z'vez de localizar.
  • Economizou 6 bytes fazendo a soma das multiplicações usando a multiplicação de matrizes.
Tom Carpenter
fonte
Abordagem inteligente, talvez muito inteligente? 53 bytes, com base na minha resposta
MATL
@Sanchises possivelmente, mas foi a abordagem que me propus a ¯_ (ツ) _ / ¯. Você pode publicar sua versão como uma resposta separada.
Tom Carpenter
Imaginei e concordo que é mais interessante ter abordagens diferentes do que apenas copiar a abordagem mais curta. Eu só queria comparar as abordagens, acho que a sua é mais inteligente, mas suponho que o conjunto de dados permita uma abordagem baseada em mod fácil (não tenho certeza se isso é uma coincidência ou estatisticamente provável)
Sanchises
3

JavaScript (Chrome), 102

Nota Infelizmente, ele funciona apenas no Chrome, devido às aproximações dependentes da implementação em parseInt () (obrigado @Arnauld)

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

Procurei uma função hash, pegando uma fatia de cada nome, convertendo em números usando a base 36 e aplicando um módulo.

Eu usei esse código para procurar o melhor 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 os 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

A melhor função hash fornece 26 valores diferentes entre 0 e 50, mas usei um diferente, com 1 duplicado, mas um intervalo menor.

Teste

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
fonte
Convém mencionar que ele só funciona no Chrome devido a aproximações dependentes da implementação em parseInt().
Arnauld 11/10
@ Arnauld obrigado, eu não sabia.
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;}

Mesma abordagem que a resposta do KSab . C não fornece uma hashfunção de string como Python. Ou faz?

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

Experimente online!

hretorna um intcujos valores são os códigos ASCII para A .. Z.

japh
fonte
2

Javascript, 98 bytes

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

Descobri que a combinação dos caracteres 2 e 4 dos nomes é única para cada um deles.

Portanto, eu crio uma string com as combinações de name[4] + name[2] , not name[2] + name[4]ou eu teria uma repetição do grupo ehde caracteres com o nome Aretha Franklin ehe quando Smokey Robinson e Johnny Cashoehn forem concatenados.

Eu poderia simplesmente mover Johnny Cash para outra posição da string e obter um mapeamento diferente, mas concatenar o 4º e o 2º caracteres nesta ordem evita a colisão e deixa intacta a ordem do conjunto de dados sem adicionar mais comprimento à solução. Então eu decidi seguir esse caminho (é apenas preferência pessoal)

Eu procuro a posição da concatenação da 4ª e 2ª letra do parâmetro fornecido na string e divido-a por 2 para obter um número entre 0 e 25. Em seguida, adiciono 10 e a converto em string da base 36, onde 10 corresponde 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))

Eduardo Páez Rubio
fonte
muito cutelo a combinação que você encontrou!
Joyal
aaah sim. claro. Eu tenho algo bastante semelhante, mas em vez de adicionar o caractere para retornar na string, a posição da ocorrência poderia salvar 25 caracteres. Inteligente!
Nl-x
1

Língua Wolfram (Mathematica) , 101126 bytes

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

+32parece levar à menor hashtable de agitação do Mathematica InputForm.

Experimente online!

Keyu Gan
fonte
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/

Experimente online!

231 bytes após remover as novas linhas.

Isso é muito longo, mas /// não pode lidar com caracteres diferentes genericamente. Em outras palavras, /// não suporta regex.

user202729
fonte
0

Excel, 96 bytes

Depois de muito tempo desperdiçado tentando outras abordagens, implementamos a abordagem de @Eduardo Paez:

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