26 Sänger, 26 Buchstaben


34

Laut RollingStone sind im Folgenden die 26 größten Sänger aller Zeiten aufgeführt:

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

Sie können dies als eine Liste von Strings bekommen hier .

Aufgabe

Bei einem Sängernamen, drucken oder einen Brief Rückkehr aus Azu Zdem eindeutig diesen Sänger identifiziert. (Wenn Ihr Code zurückgibt A für Bob Dylan , dann kann es nicht zurück A für andere Sänger.)

Im Gegensatz zu anderen ähnlichen Herausforderungen liegt das Mapping bei Ihnen , solange es kollisionsfrei ist.

Regeln

  • Die Eingabe ist garantiert einer der 26 oben aufgeführten Sängernamen mit genau dieser Schreibweise und ohne führende oder nachfolgende Leerzeichen.
  • Sie können den Buchstaben in Klein- oder Großbuchstaben ausgeben. Aber es muss konsequent sein.
  • Sie werden aufgefordert, eine Testsuite für alle 26 möglichen Eingaben bereitzustellen.
  • Das ist , also gewinnt die kürzeste Antwort in Bytes!


17
Lieber Rolling Stone, Bob Dylan ist wirklich einer der größten Musiker aller Zeiten. Aber ein großartiger Sänger ?
Luis Mendo

@LuisMendo ich ein wenig salzig über einige dieser Entscheidungen als auch (bin Husten Husten , wo Steve Tyler ist Husten )
Herr Farquaad

@ LordFarquaad Steve Tyler ist # 99 ¯ \ _ (ツ) _ / ¯
Arnauld

Dies mag jemandem helfen, aber ich habe nicht die CG-Kenntnisse, um die Informationen zu verwenden: Die Buchstaben 1-6, 1-8 und 3-5 der Namen sind eindeutige Kombinationen.
Jeutnarg

Antworten:


2

MATL , 28 Bytes

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

Probieren Sie es online!

Erläuterung

s98\40\

Ruft implizit die Eingabezeichenfolge ab. Summieren Sie die Zeichen der Eingabezeichenfolge, und führen Sie Modul 98 aus, gefolgt von Modul 40. Ergibt eine der folgenden Zahlen: 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 (in der Reihenfolge der Pastebin-Liste).

2Y2'ijkl o qst uz'h

Drücken Sie das (Klein-) Alphabet mit 2Y2. Dies kümmert sich um die Zahlen im Bereich [1,26]. Einige Zahlen fehlen jedoch, und wir haben Zahlen bis zu 38. Daher hängen wir ( h) eine Zeichenfolge an, die sich um die höheren Zahlen kümmert, indem wir diese Zahlen den 'fehlenden' Buchstaben zuordnen. Die Leerzeichen können beliebig sein. Ich habe in meinem ursprünglichen Programm Großbuchstaben verwendet, um die Eingabe zu vereinfachen.

w)

Wir können jetzt die Zahl vom ersten Schritt in den String vom zweiten Schritt mit indizieren ). Wir verwenden w, um die Argumente in der richtigen Reihenfolge zu erhalten. Während es den Anschein hat, als würden wir eine 0-basierte Indizierung verwenden (die Zahlen variieren von 0 bis 38, und die Zeichenfolge ist 39 Zeichen lang), ist die Realität etwas komplizierter: Wir verwenden eine 1-basierte modulare Indizierung, eine Besonderheit MATL. Dies bedeutet, dass 1Indizes zu a, 38tatsächlich zu uund 0Indizes zum Finale zder Zeichenfolge erstellt werden.


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)

Probieren Sie es online!

Die Summen der Ordnungszahlen geben Zahlen zwischen 0und an38

Die Zahlen, die größer als 25 sind, werden dann verschoben, um die folgenden Lücken auszufüllen (die sortierte Reihenfolge wird angezeigt):

  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

Subtrahieren Sie, 18wenn 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

Hinzufügen, 3wenn 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

Subtrahieren Sie, 8wenn 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

Welches gibt die Reihenfolge 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

Diese werden dann umgesetzt A-Zmitchr(i+65)


Ich denke, Sie können sich (i>31)auf i/32usw. verkürzen
bis zum

21

6502 Maschinencode- Routine (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

Dies ist ein positionsunabhängiger Code, den Sie einfach irgendwo im RAM ablegen und dorthin springen, z sys. B. mit dem Befehl.

Online-Demo (lädt nach$C000/49152).

Verwendung: sys49152,"[name]" zB sys49152,"Aretha Franklin".

Wichtig: Wenn das Programm von der Festplatte geladen wurde (wie in der Online-Demo), geben Sie zuerst einen newBefehl aus! Dies ist notwendig, weil das Laden eines Maschinenprogramms einige C64 BASIC-Zeiger in den Papierkorb wirft.

Hinweis: Der C64 befindet sich standardmäßig in einem Modus ohne Kleinbuchstaben. Um lesbare Namen eingeben zu können, müssen Sie zuerst in den Kleinbuchstabenmodus wechseln, indem Sie SHIFT+ drücken CBM.


Erläuterung

Die Herausforderung besteht darin, für diese Namen eine minimale perfekte Hash-Funktion zu finden. Für den C64 musste ich einen finden, der mit einfachen 8-Bit-Operationen leicht zu berechnen ist. Hier ist eine kommentierte Auflistung der Demontage:

.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

Testsuite (C64 BASIC, enthält die Maschinencode-Routine in dataZeilen)

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

Online-Demo der Testsuite .


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)

Probieren Sie es online!


1
Interessant zu wissen, wie du das komponiert hast
Sarge Borsch

2
@SargeBorsch Hash (n) berechnet für jeden Namen eine eindeutige Ganzzahl. Die Modulo-Operationen behalten diese Ints immer noch bei, senken aber ihren Wert. Der zweite Teil ( chr(65+i-i/25*2-i/29*21+i/35*2)) ähnelt der Antwort von TFelds . Die Modulo-Operationen werden durch ein Skript, das ich hier und hier bereits verwendet habe, brachial verstärkt .
Ovs

10

Javascript, 138 132 Zeichen

Da alle Initialen außer MJ= M ichael J ackson / M ick J agger eindeutig sind, überprüfe ich speziell Michael Jackson (der einzige mit einem hauf der 4. Position) und für alle anderen Namen habe ich eine Zeichenfolge mit den folgenden Initialen erstellt durch einen eindeutigen Buchstaben.

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

Code-Auszug

Probieren Sie es hier aus:

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


Es mag eine kürzere Hash-Funktion geben, aber ich mag die Idee, etwas auszuprobieren, was ein Mensch tun könnte. Ich möchte jedoch, dass Sie die Codefragment-Funktion verwenden, anstatt eine Verknüpfung zu JSFiddle herzustellen.
trlkly

@trlkly Ich habe jetzt die Code-Snippet-Funktion verwendet.
nl-x

7

Java (OpenJDK 8) , 128 126 115 113 Bytes

Nicht zu schäbig für eine Java-Vorlage!

Vielen Dank an Kevin, der mir mit den Lambda-Ausdrücken eine Menge Bytes erspart hat!

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

Probieren Sie es online!


1
Schöne Antwort, +1 von mir. Derzeit arbeite ich auch an einer Java-Lösung, indem ich ein Skript erstelle. Bisher jedoch kein Glück. Übrigens können Sie zwei Bytes Golf spielen, indem Sie {a+=i;}zua+=i;
Kevin Cruijssen

1
@ KevinCruijssen Prost, kann nicht glauben, dass ich das verpasst habe! Ich habe ein Skript geschrieben, um zu versuchen, die 'magische Zahl' zu finden, die mir eindeutige Werte zwischen 0 und 25 gibt, aber das Beste, was ich tun konnte, waren 24, daher die if-Anweisungen am Ende.
Luke Stevens

1
Hmm btw, da Sie verwenden Java 8, können Sie auch Golf char g(String s)auf s->. Ich habe Ihr TIO geändert, um zu zeigen, wie dies gemacht wird, falls Sie nur an Java 7-Methoden gewöhnt sind.
Kevin Cruijssen

Danke, mir ist nie klar geworden, dass Sie das tun können. Ich werde meine Einsendung (wieder!) Aktualisieren
Luke Stevens

Hahaha, Sie können sagen, ich bin neu in diesem
Luke Stevens

5

Python 3, 132 99 96 Bytes

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

Probieren Sie es online!

Nicht brillant golfen, aber ich dachte, ich würde es versuchen.

-33 Bytes dank Modifikationen von TFeld.
-3 Bytes durch Verwendung von findanstelle von indexDank an Ovs.


Sie können 6 Bytes sparen, indem Sie verwenden sum(map(ord,m)), außerdem habe ich Aretha Franklin für 128 Bytes
TFeld

Und Sie können chr(97+...)anstelle von ascii_lowercase: 99 Bytes verwenden
TFeld

1
Was ist mit einer Erklärung?
Matsemann

3
Eine Erklärung: sum(map(ord,m))Addiert die ASCII-Werte der Zeichen in der Zeichenfolge m(gibt Ganzzahlen im Bereich von 702 bis 1506 an). Wenn chrSie es dann aufrufen , wird es in ein (Unicode-) Zeichen mit dieser Nummer konvertiert: chr(702)ist ʾ zu chr(1506) = עund Lose dazwischen. Diese Lösung sucht dieses Zeichen einfach in einer Liste aller möglichen (26) derartigen Zeichen nach, um den Index (0–26) zu erhalten, und gibt dann ein Zeichen mit dem ASCII-Code 97 + diesem Index zurück (also 'a' bis 'z').
ShreevatsaR

1
Ihre aktuelle Lösung enthält noch eine 99-Byte-Version. Sie wollten die Version von OVS verwenden?
nl-x

5

PHP, 90 88 86 72 + 1 Bytes

könnte mit einem anderen Modulo noch kürzer werden.

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

In Datei speichern und als Pipe mit ausführen -nFoder online ausprobieren .


2
Aretha Franklin und Paul McCartney geben beide WIhre Testfälle aus, und es gibt keine XAusgabe. Ich weiß nicht, ob es sich um einen Fehler im Code selbst handelt oder nur um eine Online-Konvertierung :)
crazyloonybin

1
@crazyloonybin Ersatz Tippfehler behoben. Danke für den Hinweis.
Titus

Wie führe ich das aus? Ihr 'online ausprobieren'-Code verwendet das <?=Teil nicht. Und die "Run as Pipe" werde ich nicht arbeiten. Außerdem erhalte ich Hinweise, wenn ich versuche, es über die Befehlszeile auszuführen.
nl-x

@Titus: In CodeGolf sollten Sie die vollständige Funktion oder Anwendung angeben, die (nur) die gewünschte Ausgabe erzeugt. Ich kenne mich aus mit <?=... Meine Frage lautet also immer noch: Wie führe ich Ihren Code aus (von der Befehlszeile aus)? Ich kann es nicht über die $argnBefehlszeile eingeben ... Alle meine bisherigen Versuche liefern entweder Artefakte und scheinen immer noch mehr Code zu benötigen, um es zum Laufen zu bringen.
nl-x

@ nl-x Dein PHP liefert Hinweise, weil du die Option n nicht angegeben hast: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

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

Dank Doms Kommentar konnten 4 weitere Bytes eingespart werden, die auch in Großbuchstaben geändert wurden, um bessere Anforderungen zu erfüllen.

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

Probieren Sie es online


Netter Ansatz! Ich denke, Sie müssen eine ganze aufrufbare Funktion schreiben / notieren?
Felix Palmen

@FelixPalmen, es ist ein Perl-Programm, das inline aufgerufen werden kann: perl -pe '$_=crypt$_,mO;/..(.)/;$_=$1;y/035eft/AHPRXZ/;$_=lc'Hinzufügen eines Links zu tio
Nahuel Fouilleul

Nett! Habe nach einem ähnlichen Ansatz gesucht, $1^$2aber nicht daran gedacht, ihn zu verwenden crypt... Sie können 4 Bytes sparen , wenn Sie etwas nachbestellen: Probieren Sie es online aus!
Dom Hastings

4

Python 2, 50 43 Bytes

Dank an Japh für die neue Version

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

Probieren Sie es online!

Hinweis: Dies ist vom hasheingebauten System abhängig und funktioniert nicht in allen Implementierungen


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

@japh Schön! Mein Python Brute Force Checker war eindeutig nicht schnell genug;)
KSab

3

Ruby, 63 Bytes

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

Addiert die ASCII-Codes der Eingabe, nimmt sie mit Mod 98 und dann mit Mod 66, um eine von 26 eindeutigen Zahlen nim Bereich 0..65 zu erhalten. Die riesige hexadezimale Zahl enthält 1an jeder dieser 26 Stellen ein Bit. Wenn Sie also die Rechte verschieben, nerhalten Sie eine Zahl mit 1..26 1Bits. Wir zählen die 1Bits, indem wir die ASCII-Codes addieren und Mod 48 nehmen, dann 64 addieren und in einen ASCII-Code konvertieren.

Testprogramm

das mapiteriert durch die Sänger, die den Buchstabencode und den Sänger drucken. Anschließend wird ein Array der Buchstabencodes zurückgegeben, um sortzu demonstrieren, dass jeder Buchstabe einmal verwendet wird.

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

Ausgabe

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

Oktave , 85 83 80 74 Bytes

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

Dieses Durcheinander eines Anonymen ist das Ergebnis von einigem Durcheinander in MATLAB, das versucht, einen guten Weg zu finden, um die Daten zu verschlüsseln.

Grundsätzlich werden nach einer schnellen Analyse nur die Buchstaben 1,2 und 8 der Eingabezeichenfolge (die kleinste Zeichenfolge besteht aus 8 Zeichen, wir sind also gut) benötigt, um aus jeder Eingabe einen eindeutigen Wert zu erzeugen. Der schwierige Teil ist dann, diesen einzigartigen Wert in etwas Nutzbares umzuwandeln.

MATLAB ist schrecklich in der Komprimierung von Daten, daher musste ich nach einer anderen Möglichkeit suchen, um das Lookup-Mapping zu erstellen. Ich habe versucht, eine Funktion für die drei Eingabebuchstaben zu finden, die zu einem eindeutigen Wert führte, der auch als druckbarer ASCII-Wert fungierte, sodass ich die Zuordnung in eine Zeichenfolge mit einem Zeichen pro Eingabe einbetten konnte.

Es stellt sich heraus, dass eine Matrix, die die Zeichen am Index [1 2 8]mit der Ganzzahlmatrix multipliziert [1;15;47]und dann Mod 124 ausführt, eindeutige Werte ergibt, die alle druckbaren ASCII-Werte enthalten (und keines ist ein 'Zeichen, das Zeichenfolgenliterale nervt). Erfreulicherweise endet das Mapping mit TIOdem völlig zufällig. Interessanterweise ist dies die einzige Zuordnung für diese Gleichung, die 26 eindeutige druckbare ASCII-Zeichen ergibt.

Das ist also im Grunde meine Lookup-Zuordnung und Berechnung. Bei der Suche wird lediglich die Berechnung durchgeführt und mit dem Mapping verglichen. Das Hinzufügen 'A'-1zu dem Index in der Karte führt zu einem Buchstaben AZ.

Sie können es online bei TIO ausprobieren , wo die vollständige Zuordnung der Ein- und Ausgänge angezeigt wird. Der Vollständigkeit halber ist das vollständige Mapping auch unten aufgeführt:

'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

  • Gespeicherte 2-Byte-Optimierungszuordnung zum Entfernen +32.
  • 3 Bytes gespart, indem Octave-only mit der logischen Indizierung von 'A':'Z'statt find gemacht wurde.
  • 6 Bytes gespart, indem die Summe der Multiplikationen mit der Matrixmultiplikation durchgeführt wurde.

Kluger Ansatz, vielleicht zu klug? 53 Bytes, basierend auf meiner MATL-Antwort
Sanchises

@Sanchises möglicherweise, aber es war der Ansatz, den ich mit ¯_ (ツ) _ / ¯ kam. Gerne können Sie Ihre Version als separate Antwort veröffentlichen.
Tom Carpenter

Ich dachte mir, und ich stimme zu, dass es interessanter ist, verschiedene Ansätze zu haben, als nur den kürzesten Ansatz zu kopieren. Ich wollte nur die Ansätze vergleichen, ich denke, deine sind schlauer, aber ich nehme an, der Datensatz erlaubt nur einen einfachen mod-basierten Ansatz (nicht sicher, ob das ein Zufall oder statistisch wahrscheinlich ist)
Sanchises

3

JavaScript (Chrome), 102

Hinweis Leider funktioniert es nur in Chrome, da implementierungsabhängige Approximationen in parseInt () (danke @Arnauld)

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

Ich suchte nach einer Hash-Funktion, nahm ein Stück von jedem Namen, konvertierte mit Basis 36 in Zahlen und wandelte dann ein Modulo an.

Mit diesem Code habe ich nach dem besten Hash gesucht:

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

Und die Ergebnisse:

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

Die beste Hash-Funktion gibt 26 verschiedene Werte zwischen 0 und 50, aber ich habe einen anderen verwendet, mit 1 Duplikat, aber einem kleineren Bereich.

Prüfung

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


Vielleicht möchten Sie erwähnen , dass es nur auf Chrome funktioniert , weil der Implementierung abhängig Annäherungen in parseInt().
Arnauld

@Arnauld danke, ich wusste es nicht.
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;}

Gleicher Ansatz wie die Antwort von KSab . C bietet keine String- hashFunktion wie Python. Oder doch?

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

Probieren Sie es online!

hGibt einen zurück, intdessen Werte die ASCII-Codes für sind A .. Z.


2

Javascript, 98 Bytes

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

Ich fand heraus, dass die Kombination des 2. und 4. Zeichens der Namen für jeden von ihnen einzigartig ist.

Deshalb erstelle ich eine Zeichenkette mit den Kombinationen name[4] + name[2], nicht name[2] + name[4]oder ich hätte eine Wiederholung der Zeichengruppe ehdes Vornamens Aretha Franklin ehund wenn Smokey Robinson und Johnny Cash oehnverkettet sind.

Ich könnte Johnny Cash einfach an eine andere Position des Strings verschieben und eine andere Zuordnung erhalten, aber die Verkettung des 4. und 2. Zeichens in dieser Reihenfolge vermeidet die Kollision und lässt die Datensatzreihenfolge intakt, ohne der Lösung mehr Länge hinzuzufügen. Also habe ich beschlossen, diesen Weg zu gehen (es ist nur eine persönliche Präferenz)

Ich suche die Position der Verkettung des 4. und 2. Buchstabens des angegebenen Parameters in der Zeichenfolge und dividiere sie durch 2, sodass ich eine Zahl zwischen 0 und 25 erhalte. Dann addiere ich 10 und konvertiere sie von Basis 36 in Zeichenfolge. wo 10 entspricht aund 35 zuz

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


sehr hackmesser die kombination die du gefunden hast!
Joyal

aaah ja natürlich. Ich habe etwas ganz ähnliches, aber anstatt das Zeichen in der Zeichenfolge zurückzugeben, könnte die Position des Vorkommens 25 Zeichen sparen. Klug!
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/

Probieren Sie es online!

231 Bytes nach dem Entfernen der Zeilenumbrüche.

Das ist sehr lang, aber /// kann nicht generisch mit verschiedenen Zeichen umgehen. Mit anderen Worten, /// unterstützt Regex nicht.


0

Excel, 96 Bytes

Nachdem Sie zu viel Zeit damit verbracht haben, andere Ansätze auszuprobieren, haben Sie den Ansatz von @Eduardo Paez implementiert:

=CHAR(FIND(MID(A1,5,1)&MID(A1,3,1),"her DbMbdvsv tdeicsm hnhltirac c i uCyrbOyCmeoie nMn")/2+65)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.