26位歌手,26个字母


34

根据RollingStone的统计,以下是有史以来 26位最出色的歌手:

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

您可以在此处以字符串列表的形式获取它。

任务

给定歌手姓名,请打印或返回一个字母,AZ唯一标识该歌手。(如果您的代码为Bob Dylan返回A,则对于其他任何歌手都无法返回A。

与其他类似挑战相反,只要不冲突,映射就取决于您

规则

  • 输入的内容可以保证是上面列出的26个歌手姓名之一,并且具有完全相同的拼写,并且没有任何前导或尾随空格。
  • 您可以以小写或大写形式输出字母。但这必须是一致的。
  • 鼓励您为所有26种可能的输入提供测试套件。
  • 这是,因此最短答案以字节为单位!


17
亲爱的滚石乐队:鲍勃·迪伦(Bob Dylan)确实是有史以来最伟大的音乐家之一。但是伟大的歌手呢?
路易斯·门多

@LuisMendo我约了几个这些选择的有点咸,以及(咳嗽 哪来史蒂夫·泰勒咳嗽
主弗瓜王

@LordFarquaad史蒂夫·泰勒(Stord Tyler)是 99¯ __(ツ)_ / ¯–
Arnauld

这可能对某些人有所帮助,但是我没有CG技能来使用该信息:名称的1-6、1-8和3-5个字母是唯一的组合。
朱塔纳格

Answers:


2

MATL,28字节

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

在线尝试!

说明

s98\40\

隐式获取输入字符串。对输入字符串的字符求和,然后执行模数98和模数40。得出以下数字之一:(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 按Pastebin列表的顺序)。

2Y2'ijkl o qst uz'h

用推动(小写)字母2Y2。这样可以处理[1,26]范围内的数字。但是,缺少一些数字,并且我们最多可以有38个数字。因此,我们h通过将这些数字映射到“丢失”的字母来附加()一个字符串,该字符串负责处理较大的数字。空格可以是任何东西,为了方便我在原始程序中使用了大写字母。

w)

现在,我们可以使用来将第一步中的数字索引到第二步中的字符串中)。我们使用w正确的顺序获取参数。似乎我们使用的是基于0的索引(数字从0到38,字符串长度为39个字符),但实际上实际上要复杂一些:我们使用基于1的模块化索引,这是MATL。这意味着1索引到a38实际上索引到u,并且0索引到z字符串的末尾。


23

Python 2中80 71个字节

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

在线尝试!

模数的总和给出介于0和之间的数字38

然后将大于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

18如果减去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

3如果添加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

8如果减去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

给出顺序 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

然后这些转换为A-Zchr(i+65)


我认为您可以缩短(i>31)i/32,等等
xnor

21

6502机器代码例程(C64),83个字节

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

这是与位置无关的代码,只需将其放在RAM中的某个位置,然后跳转到该位置即可,例如使用sys命令。

在线演示(加载到$C000/49152)。

用法: sys49152,"[name]"例如sys49152,"Aretha Franklin"

重要:如果程序是从磁盘加载的(如在线演示中一样),请new首先发出命令!这是必需的,因为加载机器程序会浪费一些C64 BASIC指针。

注意:默认情况下,C64处于不带小写字母的模式下-为了能够输入可读的名称,请先通过按SHIFT+ 切换到小写模式CBM


说明

实际上,挑战在于为这些名称找到最小的完美哈希函数。对于C64,我必须找到一种可以在简单的8位操作中轻松计算的代码。这是评论的反汇编清单:

.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

测试套件(C64 BASIC,在线包含机器代码例程data

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

测试套件的在线演示


13

Python 2,68个字节

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

在线尝试!


1
知道您是如何组成的很有趣
Sarge Borsch

2
@SargeBorsch hash(n)为每个名称计算一个唯一的整数。模运算仍然保持这些int唯一,但是降低了它们的值。第二部分(chr(65+i-i/25*2-i/29*21+i/35*2))与TFelds答案类似。模运算由我在这里这里已经使用过的脚本强加。
ovs

10

Javascript,138132个字符

由于所有的声母是独一无二的,除了MJ= 中号迈克尔· Ĵ ackson / 中号 ICK Ĵ阿格,我检查Michael Jackson的具体(唯一一个与h第4位置),以及用于所有其他名称我创建与所述缩写随后的字符串通过一个独特的字母。

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

代码段

在这里尝试:

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


散列函数可能会更短一些,但是我喜欢尝试人类可能会做的事情的想法。但是,我希望您使用代码段功能,而不是链接到JSFiddle。
trlkly

@trlkly我现在使用了代码片段功能。
nl-x

7

的Java(OpenJDK的8) 128个 126 115 113字节

对于Java提交来说还不算太简陋!

感谢Kevin用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);}

在线尝试!


1
好的回答,我+1。我目前还在通过创建脚本来开发Java解决方案。顺便说一句,您可以更改{a+=i;}a+=i;
凯文·克鲁伊森

1
@KevinCruijssen干杯,不敢相信我错过了!我编写了一个脚本来尝试查找“幻数”,该幻数将为我提供介于0到25之间的唯一值,但我能做的最好是24,因此if语句位于最后。
卢克·史蒂文斯

1
嗯顺便说一句,因为你使用的是Java 8,你也可以打高尔夫球char g(String s)s->我已经修改了您的TIO,以显示如何执行此操作,以防您仅习惯Java 7方法。
凯文·克鲁伊森

谢谢,我从未意识到您可以这样做,我将再次更新我的提交内容
卢克·史蒂文斯

哈哈哈,你可以说我是新手
卢克·史蒂文斯

5

Python 3,132 99 96字节

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

在线尝试!

高尔夫打得并不出色,但我想我会尝试一下。

-33字节,感谢TFeld所做的修改。
通过使用-3个字节find代替indexovs。


您可以使用来保存6个字节sum(map(ord,m)),我还为128个字节添加了Aretha Franklin
TFeld

您可以使用:99个字节chr(97+...)代替ascii_lowercase
-TFeld

1
那解释呢?
Matsemann '17

3
一种解释:sum(map(ord,m))将字符串中字符的ASCII值相加m(给出702–1506范围内的整数)。然后调用chr它,它转换为与该号码(Unicode)的字符:chr(702)ʾ chr(1506) = ע和地段之间。该解决方案只是在所有可能的此类字符列表中查找该字符(26),以获取索引(0–26),然后返回具有ASCII码97 +该索引的字符(从'a'到'z')。
ShreevatsaR

1
您当前的解决方案仍然包含一个99字节的版本。您是否打算使用OVS的版本?
nl-x

5

PHP,90 88 86 72 + 1字节

使用不同的模数可能会变得更短。

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

保存到文件中并作为管道运行,-nF可以在线尝试


2
Aretha Franklin和Paul McCartney都W在您的测试用例上输出了信息,但没有X输出。不知道这是代码本身的错误还是只是在线尝试转换:)
crazyloonybin

1
@crazyloonybin替换错字已修复。感谢您的提示。
泰特斯

那么我该如何运行呢?您的“在线尝试”代码不使用该<?=部分。还有“以管道方式运行”我没有工作。另外,当尝试从命令行运行它时,我会收到通知。
nl-x

@Titus:在CodeGolf中,您应该提供完整的函数或应用程序(仅生成)所需的输出。我熟悉<?=...所以我的问题仍然是,如何运行您的代码(从命令行)?我无法$argn在命令行中提供它...到目前为止,我所有的尝试都提供了工件,并且似乎仍需要更多代码才能运行它。
nl-x

@ nl-x您的PHP发出通知,这是因为您没有给它n选项:echo <input> | php -nF <scriptfilename>
Titus

4

Perl中,565450,46 1(-p)个字节

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

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

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

多亏了Dom的注释,可以多保存4个字节,并且也更改为大写以适应更好的要求。

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

在线试用


不错的方法!我认为您需要编写/评分整个可调用函数吗?
Felix Palmen '17

@FelixPalmen,它可以内嵌被称为perl程序:perl -pe '$_=crypt$_,mO;/..(.)/;$_=$1;y/035eft/AHPRXZ/;$_=lc'将链接蒂奥
纳乌艾尔乌Fouilleul

真好!正在寻找一种类似的方法,使用$1^$2但不认为使用crypt...您可以通过重新排序节省4个字节:在线尝试!
Dom Hastings

4

Python 2中,50 43个字节

感谢JAPH新版本

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

在线尝试!

注意:这取决于hash内置函数,并非在所有实现中都适用


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

@japh不错!我的python蛮力检查器显然不够快;)
KSab

3

Ruby,63个字节

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

将输入的ascii码相加,将其取为mod 98,然后取为mod 66,以得到n0..65范围内的26个唯一数字之一。巨大的十六进制数1在这26 个位置中的每个位置均包含一个位,因此,通过右移该位,n我们获得其中具有1..26 1位的数字。我们算1通过添加ascii码并采用mod 48来位数,然后添加64并转换为ASCII码。

测试程序

map迭代通过歌手打印字母代码和歌手。然后,它返回一个字母代码数组,sort以证明每个字母使用一次。

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

输出量

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

八度85 83 80 74字节

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

这种匿名状态的混乱是由于MATLAB中一些混乱而导致的,其结果是试图找到一种对数据进行编码的好方法。

基本上,经过快速分析,仅需要输入字符串的字母1,2和8(最小的字符串是8个字符,所以我们很好)就可以从每个输入生成唯一值。然后,困难的部分是将独特的价值转化为可用的价值。

MATLAB在压缩数据方面很糟糕,因此我不得不寻找另一种方式来进行查找映射。我着手尝试在三个输入字母上找到一些函数,这些函数产生一个唯一值,该值也是一个可打印的ASCII值,这样我就可以将映射嵌入每个输入一个字符的字符串中。

事实证明,矩阵将索引处的字符乘以[1 2 8]整数矩阵[1;15;47],然后执行mod 124会得到唯一的值,所有可打印的ASCII值都是唯一的(而且都不是'会干扰字符串文字的字符)。令人愉快的是,映射结束TIO是完全偶然的。有趣的是,这是唯一的映射该方程式,提供了26个唯一的可打印ASCII字符。

所以基本上这就是我的查找映射和计算。查找只是执行计算并与映射进行比较的一种情况。添加'A'-1到地图中的索引会产生一个字符AZ。

您可以在TIO上在线尝试它,它显示了输入和输出的完整映射。为了完整起见,完整的映射也在下面:

'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

  • 保存2个字节的微调映射以删除+32
  • 通过使用逻辑索引'A':'Z'而不是查找将八度设置为仅八度,从而节省了3个字节。
  • 通过使用矩阵乘法的乘法总和节省了6个字节。

聪明的方法,也许太聪明了?53字节,基于我的MATL答案
Sanchises,2017年

@Sanchises可能是,但是这是我想出的方法__(ツ)_ /。欢迎您将版本发布为单独的答案。
汤姆·卡彭特

我认为,并且我同意使用不同的方法比仅仅复制最短的方法更有趣。我只是想比较一下这些方法,我认为您的方法更聪明,但是我想数据集只允许使用一种简单的基于mod的方法(不确定这是巧合还是统计上可能)
Sanchises

3

JavaScript(Chrome),102

注意不幸的是,由于parseInt()中与实现相关的近似值,它仅在Chrome中有效(感谢@Arnauld)

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

我寻找了一个散列函数,将每个名称切成薄片,使用基数36转换为数字,然后应用模。

我使用以下代码来查找最佳哈希:

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

结果:

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

最好的散列函数给出0到50之间的26个不同值,但我使用了一个不同的值,其中1个重复但范围较小。

测试

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


您可能要提及的是,由于中依赖实现的近似值,因此它仅在Chrome 上有效parseInt()
Arnauld

@Arnauld谢谢,我不知道。
edc65

3

C,65 55 49字节

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

KSab的答案相同。C没有提供hash像Python这样的字符串函数。还是呢?

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

在线尝试!

h返回int其值为的ASCII码的A .. Z


2

Javascript,98个字节

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

我发现名称的第二个和第四个字符的组合对于每个名称都是唯一的。

因此,我使用name[4] + name[2]name[2] + name[4]或的组合创建一个字符串,或者重复使用eh名字为Aretha Franklin 的字符组,eh以及Smokey Robinson和Johnny Cash的情况。oehn串联在一起。

我可以将Johnny Cash移到字符串的另一个位置并获得不同的映射,但是以此顺序连接第4个字符和第2个字符可以避免冲突,并使数据集顺序保持不变,而无需增加解决方案的长度。所以我决定走这条路(这只是个人喜好)

我在字符串中搜索给定参数的第4个字母和第2个字母的串联位置,然后将其除以2,以获得0到25之间的数字。然后我将10加并从基数36转换为字符串,其中10对应于a35 对应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))


切肉刀,您找到的组合!
Joyal

是的。当然。我有一个非常相似的东西,但不是将char添加到字符串中返回,发生的位置可以节省25个char。聪明!
nl-x


1

///,390 231字节

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

在线尝试!

删除换行符后的231个字节。

这很长,但是///无法通用地处理不同的字符。换句话说,///不支持正则表达式。


0

Excel,96个字节

在浪费大量时间尝试其他方法之后,已实现@Eduardo Paez的方法:

=CHAR(FIND(MID(A1,5,1)&MID(A1,3,1),"her DbMbdvsv tdeicsm hnhltirac c i uCyrbOyCmeoie nMn")/2+65)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.