实施可变长度哈希


10

我和我的朋友有我们用文字玩的游戏。这是一个有趣的消遣,它涉及单词中的“删除”字母,直到没有剩余为止。我真的很讨厌他比我快很多,所以实施它并让我最终击败他是您的工作。显然,由于我必须使程序尽可能容易地隐藏,因此它必须尽可能小。

这个游戏如何运作?

游戏是一个非常简单的算法。它减少了字母字符串,直到无法进一步减少为止,从而使其成为一种哈希。我们人类所做的实际游戏很难实现,但可以简化为以下算法:

首先将字母对折,然后将两部分对齐,如下所示:

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

然后,从中间开始,将正整数分配给上半部,将负整数分配给下半部:

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

然后,您将您的字符串(我们将使用hello world)并忽略任何非字母字符,将其翻译为:

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

然后,您求和字母值。在前面的图中排列的那些(例如dwlo)将被抵消,而其他的将相加。

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

12是的数字b,因此的哈希hello worldb

对于完全抵消的单词(例如love),您输出“ 0字符”:-。注意,在输入中,-仍将被忽略。仅在输出中重要。

如果数字的幅度大于13,那么你就开始对翻倍a的和z是你基本上是采取尽可能多a的或z的配入数量,并采取一切留到像这样的最后一封信:

code golf: 43.

适合3 a,剩余4:

aaa 4: j
result: aaaj

提示:这部分是基本上divmod不同的是其四舍五入朝向零,而不是-infinity(例如-43将成为3 z的与和-4其是p如此zzzp)。

注意:如果az完全适合,则破折号不会出现,仅当它恰好是时才行0

说明:

  • 哈希是区分敏感
  • 不允许使用标准漏洞
  • I / O可以采用不太奇怪的任何格式,stdin,stdout,命令行arg,函数等。
  • 这是因此以字节为单位的最短大小会获胜。

例子:

hello world  -->  b

love  -->  -

this is an example -->  aak

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

good bye --> ae

root users --> zzs

3
love是空的...
贾斯汀

Answers:


4

CJam,46个字节

在线试用,或在线试用测试套件

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

说明

该算法可以满足您的期望:读取输入,将其转换为小写字母,将每个字符映射为一个值,对这些值求和,然后打印字符并相应地调整总和,直到总和为零。可能最有趣的优化方法(尽管它仅节省两个字节)是改用负字符映射,因为这样可以避免在计算映射值时交换减法参数以更正符号,并且避免了在重新映射到字母时由于减去负值可以用加法替换。

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

您可以使用@Jz代替,f}YJz可能还有更多,但是我现在必须睡觉。祝您好运;)
FryAmTheEggman 2015年

@FryAmTheEggman酷,我不知道@
orlp 2015年

2

片段 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个字节

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

这必须是有史以来最粗糙的R代码。我认为R可能是一个不错的选择,因为它具有一个由所有字母“ a”到“ z”的向量作为内置全局变量。但是事实证明,其余的都是一团糟。

取消+说明:

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

这将创建一个未命名的函数对象,该对象接受字符串作为输入并返回关联的哈希值。要给它起个名字,例如f=function(s){...}

例子:

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

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

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

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

在线尝试!

有什么问题吗 我会很乐意提供进一步的解释。有什么建议吗?欢迎提出建议!


1

Haskell,171字节

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

测试运行:

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

工作原理:l是一个从字母到相应值的查找表。从输入字符串中查找所有字符,并丢弃未找到的字符。对结果列表求和。根据p打印的总和,-或者首先是一些as或zs,最后是(反向)查找来自的字母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,绝对比我的R答案好。干得好!
Alex A.
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.