Menerapkan Hash Panjang Variabel


10

Teman saya dan saya memiliki permainan ini yang kami mainkan dengan kata-kata. Ini adalah hiburan yang menyenangkan dan melibatkan "membatalkan" surat dalam kata sampai tidak ada yang tersisa. Saya benar-benar lelah dia menjadi jauh lebih cepat daripada saya dalam hal itu, jadi itu adalah tugas Anda untuk mengimplementasikannya dan biarkan saya akhirnya mengalahkannya. Jelas, karena saya harus membuat program semudah mungkin bersembunyi, itu harus sekecil mungkin.

Bagaimana cara kerja game ini?

Gim ini adalah algoritma yang cukup sederhana. Ini mengurangi string abjad sampai tidak dapat direduksi lebih jauh, sehingga membuatnya menjadi semacam hash. Game sebenarnya yang kita manusia lakukan sangat sulit untuk diterapkan, tetapi dapat disederhanakan menjadi algoritma berikut:

Anda mulai dengan melipat alfabet menjadi dua dan membariskan dua bagian seperti:

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

Kemudian, mulai dari tengah, Anda menetapkan bilangan bulat positif ke bagian atas dan negatif ke bawah:

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

Kemudian Anda mengambil string Anda (kami akan menggunakan hello world) dan mengabaikan karakter non-abjad, menerjemahkannya:

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

Kemudian Anda menjumlahkan nilai huruf. Yang berbaris di diagram sebelumnya (misalnya ddan w, ldan o) akan dibatalkan, sementara yang lain akan bertambah.

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

12 adalah nomor b, sehingga hash dari hello worldisb

Untuk sebuah kata yang benar-benar membatalkan (misalnya love), Anda output "0 karakter": -. Perhatikan bahwa dalam input, -masih akan diabaikan. Itu hanya masalah dalam output.

Jika besarnya angka lebih besar dari 13, maka Anda mulai menggandakan pada a'dan z' Anda pada dasarnya mengambil sebanyak aatau zcocok dengan angka dan mengambil apa pun yang tersisa ke dalam huruf terakhir seperti:

code golf: 43.

Sesuai dengan 3 adan tersisa 4:

aaa 4: j
result: aaaj

Petunjuk: Bagian ini pada dasarnya divmodkecuali bahwa itu membulat ke nol, bukan -infinity(misalnya -43 akan menjadi 3 zdan dan -4yang pbegitu zzzp).

Catatan: tanda hubung tidak datang jika sesuai aatau zsempurna, hanya jika tepat 0.

Klarifikasi:

  • Hash adalah case dalam sensitif
  • Celah Standar tidak diizinkan
  • I / O bisa dalam format apa pun yang tidak terlalu aneh, stdin, stdout, arg baris perintah, fungsi, dll.
  • Ini adalah sehingga ukuran terpendek dalam byte menang.

Contoh:

hello world  -->  b

love  -->  -

this is an example -->  aak

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

good bye --> ae

root users --> zzs

3
lovekosong ...
Justin

Jawaban:


4

CJam, 46 byte

Cobalah online , atau coba test suite online .

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

Penjelasan

Algoritma bekerja seperti yang Anda harapkan: membaca input, mengonversi menjadi huruf kecil, memetakan setiap karakter ke nilai, menjumlahkan nilai, dan mencetak karakter dan menyesuaikan jumlah sesuai hingga jumlahnya nol. Mungkin optimasi yang paling menarik (meskipun hanya menghemat dua byte) adalah bahwa pemetaan karakter yang dinegasikan digunakan sebagai gantinya, karena ini menghindari bertukar argumen pengurangan untuk memperbaiki tanda saat menghitung nilai yang dipetakan dan menghindari bertukar lagi ketika memetakan kembali ke huruf karena pemetaan pengurangan nilai yang dinegasikan diganti dengan penambahan.

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

Anda dapat menggunakan @Jzdaripada f}YJzMungkin ada lebih banyak, tetapi saya harus tidur sekarang. Semoga berhasil;)
FryAmTheEggman

@FryAmTheEggman Keren, saya tidak tahu persimpangan @!
orlp

2

Klip 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 byte

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

Ini harus menjadi kode R terburuk yang pernah ada. Saya pikir R mungkin menjadi pilihan yang layak karena memiliki vektor semua huruf "a" hingga "z" sebagai variabel global bawaan. Namun ternyata sisanya berantakan.

Penjelasan + tidak dikumpulkan:

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

Ini menciptakan objek fungsi tanpa nama yang menerima string sebagai input dan mengembalikan nilai hash terkait. Untuk menyebutnya, berikan nama, mis f=function(s){...}.

Contoh:

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

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

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

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

Cobalah online!

Pertanyaan? Saya akan dengan senang hati memberikan penjelasan lebih lanjut. Saran? Saran lebih dari diterima!


1

Haskell, 171 byte

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

Uji coba:

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

Cara kerjanya: ladalah tabel pencarian dari huruf ke nilai yang sesuai. Cari semua karakter dari string input dan buang yang tidak ditemukan. Jumlahkan daftar yang dihasilkan. Tergantung pada jumlah yang pdicetak -atau mungkin beberapa as atau zs dan akhirnya (terbalik) mencari surat dari 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, pasti lebih baik daripada jawaban R saya. Kerja bagus!
Alex A.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.