Implementieren Sie einen Hash mit variabler Länge


10

Mein Freund und ich haben dieses Spiel, das wir mit Worten spielen. Es ist ein lustiger Zeitvertreib, bei dem Buchstaben in einem Wort "gelöscht" werden, bis nichts mehr übrig ist. Ich bin es wirklich leid, dass er so viel schneller ist als ich, also ist es deine Aufgabe, es umzusetzen und mich ihn endlich schlagen zu lassen. Da ich das Programm so einfach wie möglich ausblenden muss, muss es natürlich so klein wie möglich sein.

Wie funktioniert dieses Spiel?

Das Spiel ist ein ziemlich einfacher Algorithmus. Es reduziert eine alphabetische Zeichenfolge, bis sie nicht mehr weiter reduziert werden kann, wodurch es zu einer Art Hash wird. Das eigentliche Spiel, das wir Menschen machen, ist sehr schwer zu implementieren, aber es kann in den folgenden Algorithmus vereinfacht werden:

Sie beginnen damit, das Alphabet in zwei Hälften zu falten und die beiden Teile wie folgt auszurichten:

a b c d e f g h i j k l m
z y x w v u t s r p q o n

Ausgehend von der Mitte weisen Sie dann der oberen Hälfte die positiven Ganzzahlen und der unteren die negativen Ganzzahlen zu:

a  b  c  d  e f g h i j k l m
13 12 11 10 9 8 7 6 5 4 3 2 1

z   y   x   w   v  u  t  s  r  p  q  o  n
-13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1

Dann nehmen Sie Ihre Zeichenfolge (wir werden sie verwenden hello world) und ignorieren alle nicht alphabetischen Zeichen. Übersetzen Sie sie:

h e l l  o w   o  r  l d
6 9 2 2 -2 -10 -2 -5 2 10

Dann summieren Sie die Buchstabenwerte. Diejenigen, die im vorherigen Diagramm aufgereiht sind (z. B. dund w, lund o), werden aufgehoben, während sich die anderen summieren.

sum(6 9 2 2 -2 -10 -2 -5 2 10 )=12

12 ist die Zahl für b, so dass der Hash hello worldISTb

Für ein Wort, das vollständig gelöscht wird (z. B. love), geben Sie das "0-Zeichen" aus : -. Beachten Sie, dass in der Eingabe -weiterhin ignoriert wird. Es ist nur in der Ausgabe wichtig.

Wenn der Betrag der Zahl größer als 13 ist, dann beginnen zu verdoppeln Sie auf den nach oben aist und die z's nehmen Sie grundsätzlich so viele a‚s oder z‘ s fit in die Zahl und nehmen , was wie so in den letzten Brief gelassen wird:

code golf: 43.

Passend für 3 aund hat 4 übrig:

aaa 4: j
result: aaaj

Hinweis: Dieser Teil ist im Grunde genommen divmodaußer, dass er gegen Null rundet, nicht -infinity(z. B. -43 würde zu 3 zund und a, -4was pso ist zzzp).

Hinweis: Der Bindestrich kommt nicht, wenn das aoder zdie perfekt passen, nur wenn es genau ist 0.

Erläuterungen:

  • Der Hash ist Groß- und Kleinschreibung
  • Standardlücken sind nicht erlaubt
  • E / A kann in jedem Format vorliegen, das nicht zu ausgefallen, stdin, stdout, Befehlszeilenargument, Funktion usw. ist.
  • Dies ist so dass die kürzeste Größe in Bytes gewinnt.

Beispiele:

hello world  -->  b

love  -->  -

this is an example -->  aak

hello *&*(&(*&%& world  -->  b

good bye --> ae

root users --> zzs

3
loveist leer ...
Justin

Antworten:


4

CJam, 46 Bytes

Probieren Sie es online aus oder testen Sie die Testsuite online .

lel{'n-_W>+_zE<*}%:+{_De<C~e>___0>-'n+'-?o-}h;

Erläuterung

Der Algorithmus funktioniert wie erwartet: Lesen Sie die Eingabe, konvertieren Sie sie in Kleinbuchstaben, ordnen Sie jedes Zeichen einem Wert zu, summieren Sie die Werte und drucken Sie Zeichen und passen Sie die Summe entsprechend an, bis die Summe Null ist. Die wahrscheinlich interessanteste Optimierung (obwohl nur zwei Bytes eingespart werden) besteht darin, dass stattdessen negierte Zeichenzuordnungen verwendet werden, da dies das Austauschen von Subtraktionsargumenten zur Korrektur des Vorzeichens bei der Berechnung des zugeordneten Werts und das erneute Auswechseln beim erneuten Zuordnen zu einem Buchstaben aufgrund des Subtraktion eines negierten Wertes, der durch Addition ersetzt werden kann.

lel             "Read a line of input and convert all letters to lowercase.";
{               "Map each character:";
  'n-_W>+         "Map each character to its negated value by subtracting 'n'
                   and incrementing if the result is nonnegative.";
  _zE<*           "If the value is out of the letter range, use 0 instead.";
}%
:+              "Compute the sum of the mapped character values.";
{               "Do...";
  _De<C~e>        "Compute the sum clamped to the letter range.";
  __              "If the clamped sum is nonzero, ...";
  _0>-'n+         "... then produce the clamped sum mapped back to a letter by
                     decrementing if it is positive and adding 'n', ...";
  '-              "... else produce '-'.";
  ?
  o               "Output the character produced above.";
  -               "Subtract the clamped sum out of the sum.";
}h              "... while the sum is nonzero.";
;               "Clean up.";

4

Pyth, 79 78 77 65 61 58

J+\-GK+0fTr13_14=ZsX@JzJKMe,pk*G/H13%H13@JxK?g\aZ>Z0_g\z_Z

Sie können @Jzanstelle von f}YJzEs gibt wahrscheinlich mehr, aber ich muss jetzt schlafen. Viel Glück;)
FryAmTheEggman

@FryAmTheEggman Cool, ich war mir der Kreuzung von nicht bewusst @!
Orlp

2

Clip 10 , 87

Fr+`m[y?cAyg#Ay-v,-RRZ]0]}m.U`[Fx?x?<x0,:-/xR'z*m'm%xR!!%xR],:/xR'a*m'n%xR!!%xR]]'-[R13

1

R, 258 Bytes

function(s){a=13;r=data.frame;z=strsplit(gsub("[^a-z]","",tolower(s)),"")[[1]];d=r(l=rev(letters),h=c(-1*a:1,1:a));m=merge(r(l=z),d);n=sum(m$h);q=abs(n);v=rep(ifelse(n>0,"a","z"),q%/%a);paste0(paste(v,collapse=""),d$l[d$h==sign(n)*q%%a],ifelse(n==0,"-",""))}

Dies muss der gröbste R-Code aller Zeiten sein. Ich dachte, R könnte eine anständige Wahl sein, da es einen Vektor aller Buchstaben "a" bis "z" als eingebaute globale Variable hat. Aber es stellt sich heraus, dass der Rest ein Chaos ist.

Ungolfed + Erklärung:

function(s) {
    a <- 13              # Store the value associated with a
    r <- data.frame      # Store the `data.frame` function

    # Split the input into a vector, ignoring case and non-letters
    z <- strsplit(gsub("[^a-z]", "", tolower(s)), "")[[1]]

    # Create a data frame where the first column is the letters
    # z through a and the second is the associated scores
    d <- data.frame(l=reverse(letters), h=c(-1*a:1, 1:a))

    # Merge the split vector with the data frame of scores
    m <- merge(data.frame(l=z), d)

    # Get the total score for the input
    n <- sum(m$h)
    q <- abs(n)

    # Pad the output with a or z as necessary
    v <- rep(ifelse(n > 0, "a", "z"), q %/% a)

    # Collapse the vector of a's or z's into a string
    out1 <- paste(v, collapse="")

    # Look up the letter associated with remainder
    out2 <- d$l[d$h == sign(n)*q%%a]

    # If n = 0, we still want a dash
    out3 <- ifelse(n == 0, "-", "")

    # Return the concatenation of all pieces of the output
    paste0(out1, out2, out3)
}

Dadurch wird ein unbenanntes Funktionsobjekt erstellt, das eine Zeichenfolge als Eingabe akzeptiert und den zugehörigen Hashwert zurückgibt. Um es zu nennen, geben Sie ihm einen Namen, z f=function(s){...}.

Beispiele:

> f("this is an example")
[1] "aak"

> f("root users")
[1] "zzs"

> f("love")
[1] "-"

> f("People like grapes.")
[1] "aaag"

Probieren Sie es online aus!

Fragen? Ich werde gerne weitere Erklärungen abgeben. Vorschläge? Vorschläge sind mehr als willkommen!


1

Haskell, 171 Bytes

import Data.Char
m=13
l=zip['a'..'z'][-i|i<-[-m..m],i/=0]
p 0="-"
p n|n>m='a':p(n-m)|n<(-m)='z':p(n+m)|1<2=[c|(c,i)<-l,i==n]
f n=p$sum[y|Just y<-[lookup(toLower x)l|x<-n]]

Testlauf:

> map f ["hello world", "love", "this is an example", "hello *&*(&(*&%& world", "good bye", "root users"]
["b","-","aak","b","ae","zzs"]

So funktioniert es: list eine Nachschlagetabelle von Buchstaben zum entsprechenden Wert. Suchen Sie alle Zeichen in der Eingabezeichenfolge und verwerfen Sie die nicht gefundenen. Summiere die resultierende Liste. Abhängig von der Summe pdruckt -oder vielleicht zuerst einige as oder zs und schließlich (umgekehrt) den Brief von l.


1

R - 200

function(s){l=letters
N=setNames
x=strsplit(tolower(s),'')[[1]]
n=(13:-13)[-14]
v=sum(N(n,l)[x[x%in%l]])
o=''
while(v){d=min(max(v,-13),13)
o=paste0(o,N(l,n)[as.character(d)])
v=v-d}
if(o=='')o='-'
o}

+1, definitiv besser als meine R-Antwort. Gute Arbeit!
Alex A.
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.