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人の歌手の名前の1つであることが保証されています。
  • 文字は小文字でも大文字でも出力できます。しかし、それは一貫している必要があります。
  • 26の可能な入力すべてに対してテストスイートを提供することをお勧めします。
  • これはなので、バイト単位の最短回答が勝ちです!


17
親愛なるローリング・ストーン:ボブ・ディランは、これまでで最高のミュージシャンの一人です。しかし、偉大な歌手ですか?
ルイスメンドー

@LuisMendo私は(これらの選択肢の数だけでなくについてのビット塩辛いだ のスティーヴン・タイラーの
主Farquaad

@LordFarquaadスティーヴン・タイラーがある#99 ¯\ _(ツ)_ /¯
アルノー

これは誰かを助けるかもしれませんが、私は情報を使用するためのCGスキルを持っていません。名前の1-6、1-8、3-5文字はユニークな組み合わせです。
ジュートナル

回答:


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)

これで、最初のステップの数を2番目のステップの文字列にインデックス付けできます)w引数を正しい順序で取得するために使用します。0ベースのインデックス(数字は0から38、文字列の長さは39文字)を使用しているように見えるかもしれませんが、実際は少し複雑です:1ベースのモジュラーインデックス、 MATL。この手段その1インデックスにa38実際にインデックスu、および0最終的にインデックスz文字列の。


23

パイソン280の 71バイト

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

オンラインでお試しください!

moddedの序数の合計は、038

次に、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-Zれますchr(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のボルシチ

2
@SargeBorsch hash(n)は、すべての名前に対して一意の整数を計算します。モジュロ演算は、これらの整数を一意に保ちますが、値を下げます。2番目の部分(chr(65+i-i/25*2-i/29*21+i/35*2))はTFelds回答と同様です。モジュロ演算は、ここここですでに使用したスクリプトによってブルートフォースされています
ovs

10

Javascript、138132文字

すべてのイニシャルは一意であるため、 MJ = M ichael Jの ackson / MJのアッガー、私は(と一つだけ特別マイケル・ジャクソンをチェックしh4位に)、そして私が続くイニシャルで文字列を作成し、他のすべての名前についてユニークな手紙で。

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を提出するのにあまりにも粗末ではありません!

ラムダ式で大量のバイトを節約してくれたケビンに感謝します!

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;}することで2バイトをゴルフすることができますa+=i;
ケビンCruijssen

1
@KevinCruijssen乾杯、それを見逃したなんて信じられない!0〜25の一意の値を与える「マジックナンバー」を見つけて見つけるためのスクリプトを作成しましたが、できることは24でした。したがって、最後のifステートメントです。
ルークスティーブンス

1
うーんところで、あなたは、Java 8を使用しているので、することもできますゴルフchar g(String s)s->Java 7メソッドにしか慣れていない場合に備えて、これを行う方法を示すためにTIOを変更しました。
ケビンCruijssen

おかげで、私はあなたがそれを行うことができることに気づかなかった、私は私の提出物を更新します(再び!)
ルークスティーブンス

ハハハ、あなたは私がこれに新しいことを伝えることができます
ルークスティーブンス

5

Python 3、 3、132 99 96バイト

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

オンラインでお試しください!

見事にゴルフをしていませんが、これを試してみると思いました。

TFeldによる変更のおかげで-33バイト。
find代わりに使用して-3バイトindexovsおかげで、。


を使用すると6バイト節約できますsum(map(ord,m))。また、アレサフランクリン を128バイト
-TFeld

次のchr(97+...)代わりに使用できますascii_lowercase99バイト
-TFeld

1
説明はどうですか?
マツマン

3
説明:sum(map(ord,m))文字列の文字のASCII値をm合計します(範囲702〜1506の整数を与えます)。次に、それを呼び出すchrと、その番号を持つ(Unicode)文字に変換されます:chr(702)is ʾ to chr(1506) = עand lots between。このソリューションは、可能なすべての(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

パール、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

オンラインで試す


素敵なアプローチ!ただし、呼び出し可能な関数全体を作成/スコアリングする必要があると思いますか?
フェリックスパルメン

@FelixPalmen、インラインと呼ばれることができるperlプログラムです:perl -pe '$_=crypt$_,mO;/..(.)/;$_=$1;y/035eft/AHPRXZ/;$_=lc'tioへのリンクを追加
Nahuel Fouilleul

いいね!同様のアプローチを探していましたが、使用することを$1^$2考えていませんでしたcrypt...あなたはいくつかの並べ替えで4バイトを節約できます:オンラインで試してみてください!
ドムヘイスティングス

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

ルビー、63バイト

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

入力のASC​​IIコードを追加し、mod 98からmod 66を取りn、範囲0..65の26の一意の番号のいずれかを取得します。巨大な16進数には、1これらの26の場所それぞれにビットが含まれnているため、1..26 1ビットの数値を取得して右シフトすることにより、数えます1ASCIIコードを追加してmod 48を取得し、64を追加してASCIIコードに変換することでビットます。

テストプログラム

map文字コードや歌手を印刷する歌手を反復処理します。次に、文字コードの配列を返します。これはsort、各文字が1回使用されることを示すために編集されます。

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はデータの圧縮がひどいため、ルックアップマッピングを作成する別の方法を探す必要がありました。私は、入力ごとに1文字の文字列にマッピングを埋め込むことができるように、印刷可能なASCII値でもある一意の値をもたらす3つの入力文字の関数を見つけることを試みました。

インデックスの文字に[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'findではなくofの論理インデックスを使用してOctaveのみを作成することにより、3バイトを節約しました。
  • 行列乗算を使用して乗算の合計を行うことにより、6バイトを節約しました。

賢いアプローチ、賢すぎるかも?MATLの回答に基づく53バイト
-Sanchises

@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ありがとう、知りませんでした。
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はhashPythonのような文字列関数を提供しません。それともそうですか?

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

オンラインでお試しください!

hはのintASCIIコードを値として返しますA .. Z


2

Javascript、98バイト

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

名前の2番目と4番目の文字の組み合わせは、それぞれに一意であることがわかりました。

したがって、の組み合わせで文字列を作成します。そうでname[4] + name[2]ないname[2] + name[4]場合は、ehAretha Franklinという名前のcharグループehと、Smokey RobinsonとJohnny Cashの繰り返しがあります。oehnが連結されたます。

ジョニーキャッシュを文字列の別の位置に移動して別のマッピングを取得できますが、この順序で4番目と2番目の文字を連結すると、衝突を回避し、ソリューションに長さを追加せずにデータセットの順序をそのまま残します。だから私はそのように行くことにしました(それは個人的な好みです)

ストリング内の指定されたパラメーターの4番目と2番目の文字の連結の位置を検索し、0から25の間の数値を得るために2で除算します。その後、10を追加し、ベース36からストリングに変換します。ここで、10はに対応しa、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))


あなたが見つけた組み合わせを非常に包丁!
ジョイアル

そうそう。もちろん。私は非常に似たものを持っていますが、文字列に返すために文字を追加する代わりに、発生の位置は25文字を節約できます。賢い!
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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.