【问题标题】:Code Golf - Word Scrambler代码高尔夫 - 字扰码器
【发布时间】:2010-11-28 15:57:10
【问题描述】:

请按照我在下面给出的示例输入和输出,回答将任意明文转换为其相应密文的程序的最短源代码。使用最少的 CPU 时间或最少的内存可获得奖励积分*。

示例 1:

明文:敏捷的棕色狐狸跳过懒惰的狗。 Supercalifragilisticexpialidocious!

密文: eTh kiquc nobrw xfo smjup rvoe eth yalz .odg !uioiapeislgriarpSueclfaiitcxildcos

示例 2:

明文: 123 1234 12345 123456 1234567 12345678 123456789

密文: 312 4213 53124 642135 7531246 86421357 975312468

规则:

  1. 标点符号被定义为包含在最接近的单词中。
  2. 单词的中心定义为天花板((strlen(word)+1)/2)。
  3. 空白被忽略(或折叠)。
  4. 奇数字首先向右移动。连单词都先向左移动。

您可以将其视为向后读取每个其他字符(从单词末尾开始),然后向前读取其余字符。 Corporation => XoXpXrXtXoX => niaorCoprto.

感谢那些指出我的描述不一致的人。这让你们中的许多人走上了错误的道路,对此我深表歉意。规则 #4 应该把事情弄清楚。

*只有在 Jeff Atwood 决定这样做的情况下才会获得奖励积分。因为我没有和他核实过,所以机会很小。对不起。

【问题讨论】:

  • I/O,读/写变量、函数的独立代码?
  • “lazy”在密文示例中编码错误,应该是“zlay”,而不是“yalz”。
  • 我的第一个解决方案也输出 zlay。与规范比较后,我想也许我只是误解了规范,但也许你是对的。
  • @Dav - 我认为他的版本正好相反:quick => kiquc 首先以k 开头,然后是c 最后,然后是i,以此类推,而over => rvoe 以@ 开头首先是 987654326@,然后是 e,最后是 v,然后是倒数第二个 o。因此,一致性。
  • 我明白了。在这种情况下,问题陈述可能应该以不同的方式定义转换——即,它应该描述密文是如何生成的,而不是描述它是如何被阅读的(或者,根据每个单词的反向阅读来定义密文的阅读方式。 .).

标签: word puzzle code-golf encryption scramble


【解决方案1】:

Python,50 个字符

i中的输入:

' '.join(x[::-2]+x[len(x)%2::2]for x in i.split())

处理自己的 IO 的替代版本:

print ' '.join(x[::-2]+x[len(x)%2::2]for x in raw_input().split())

如果包括空格,则总共 66 个字符。 (从技术上讲,如果从命令行运行,print 可以省略,因为代码的评估值默认显示为输出。)


使用reduce的替代版本:

' '.join(reduce(lambda x,y:y+x[::-1],x) for x in i.split())

59 个字符。

i 中输入的原始版本(偶数和奇数都先右转):

' '.join(x[::2][::-1]+x[1::2]for x in i.split())

48 个字符,包括空格。

另一个替代版本(虽然稍长)效率稍高:

' '.join(x[len(x)%2-2::-2]+x[1::2]for x in i.split())

(53 个字符)

【讨论】:

  • 请贴出语言和字符数,遵循代码高尔夫的传统。 ;)
  • 我仍然需要稍微调整一下,有一两个错字。当我仔细检查时会发布字符数。 :)
  • 好了。更新后的版本似乎对整个测试字符串正常工作,包含 69 个字符(包括空格)。
  • len(x)%2and-1or-2 与 len(x)%2-2 相同
  • 是的,我在做其他事情时正在考虑这个问题。已修改。
【解决方案2】:

Bash - 133,假设输入在 $w 变量中

漂亮

for x in $w; do 
    z="";
    for l in `echo $x|sed 's/\(.\)/ \1/g'`; do
        if ((${#z}%2)); then
            z=$z$l;
        else
            z=$l$z;
        fi;
    done;
    echo -n "$z ";
done;
echo

压缩

for x in $w;do z="";for l in `echo $x|sed 's/\(.\)/ \1/g'`;do if ((${#z}%2));then z=$z$l;else z=$l$z;fi;done;echo -n "$z ";done;echo

好的,所以它输出一个尾随空格。

【讨论】:

    【解决方案3】:

    Lua

    130个char函数,147个char函数程序

    Lua 在代码高尔夫中没有得到足够的喜爱——也许是因为当你有像function/endif/then/end 这样的长关键字时,很难编写一个短程序。等等

    首先我以详细的方式编写函数并进行解释,然后将其重写为压缩的独立函数,然后在命令行指定的 single 参数上调用该函数。

    我不得不用 <pre></pre> 标签格式化代码,因为 Markdown 在格式化 Lua 方面做得很糟糕。

    从技术上讲,您可以通过内联函数获得更小的运行程序,但这种方式更加模块化:)

    t = "敏捷的棕色狐狸跳过懒狗。Supercalifragilisticexpialidocious!" T = t:gsub("%S+", -- 对于 t... 中的每个单词 function(w) -- 参数:t 中的当前单词 W = "" -- 初始化新字 for i = 1,#w do -- 遍历 word 中的每个字符 c = w:sub(i,i) -- 提取当前字符 -- 判断字母是在右端还是左端 W = (#w % 2 ~= i % 2) 和 W .. c 或 c .. W 结尾 return W -- 将 t 中的单词与倒置的单词交换 结尾) -- 代码高尔夫单元测试 断言(T ==“eTh kiquc nobrw xfo smjup rvoe eth yalz .odg !uioiapeislgriarpSueclfaiitcxildcos”) -- 需要赋值给一个变量并返回它, -- 因为 gsub 返回一对并且我们只想要第一个元素 f=function(s)c=s:gsub("%S+",function(w)W=""for i=1,#w do c=w:sub(i,i)W=(#w%2 ~=i%2)and W ..c or c ..W end return W end)return c end -- 1 2 3 4 5 6 7 8 9 10 11 12 13 --34567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 -- 130 个字符,压缩并写成一个适当的函数 打印(f(arg[1])) --34567890123456 -- 16 个(需要 +1 个空格)字符,使其成为一个正常运行的 Lua 程序, -- 在命令行参数上操作

    输出:

    $ lua insideout.lua '敏捷的棕色狐狸跳过了懒惰的狗。 Supercalifragilisticexpialidocious! eTh kiquc nobrw xfo smjup rvoe eth yalz .odg !uioiapeislgriarpSueclfaiitcxildcos

    我还是 Lua 的新手,所以我希望看到一个更短的解决方案(如果有的话)。


    对于标准输入的所有参数的最小密码,我们可以做 111 个字符: for _,w in ipairs(arg)do W=""for i=1,#w do c=w:sub(i,i)W=(#w%2~=i%2)and W ..c或 c ..W end io.write(W ..' ')end

    但这种方法确实会像其他一些解决方案一样输出尾随空格。

    【讨论】:

      【解决方案4】:

      C,140 个字符

      格式很好:

      main(c, v)
        char **v;
      {
        for( ; *++v; )
        {
          char *e = *v + strlen(*v), *x;
          for(x = e-1; x >= *v; x -= 2)
            putchar(*x);
          for(x = *v + (x < *v-1); x < e; x += 2)
            putchar(*x);
          putchar(' ');
        }
      }
      

      压缩:

      main(c,v)char**v;{for(;*++v;){char*e=*v+strlen(*v),*x;for(x=e-1;x>=*v;x-=2)putchar(*x);for(x=*v+(x<*v-1);x<e;x+=2)putchar(*x);putchar(32);}}
      

      【讨论】:

      • 不使用K&R风格的main()声明岂不是省了几个字符?
      • 试过了——除非你还添加int c,否则它不会编译,这总共多了几个字符。显然你不能使用混合风格的原型,这是相当明智的。
      • 你用什么编译它?我认为 GCC 会让它在所有警告关闭的情况下编译,因为它们应该被隐式输入到 int...
      • 我用 gcc-4.3.3、gcc-4.0.1 和 gcc-3.4.6 都试过了,都不喜欢main(c,char**v)
      • @Adam:您可以通过将x=x==s-1?s:s+1 更改为x=s+(x!=s-1) 来减少另外2 个字符。 gcc 4.3.3 没有给出警告,即使是-Wall
      【解决方案5】:

      TCL

      125 个字符

      set s set f foreach l {}
      $f w [gets stdin] {$s r {}
      $f c [split $w {}] {$s r $c[string reverse $r]}
      $s l "$l $r"}
      puts $l
      

      【讨论】:

        【解决方案6】:

        对于s中的输入:

        f=lambda t,r="":t and f(t[1:],len(t)&1and t[0]+r or r+t[0])or r
        " ".join(map(f,s.split()))
        

        Python,90 个字符,包括空格。

        【讨论】:

        • 你不计算空格吗?
        • 高尔夫中的常见做法是计算它。顺便说一句,您可以消除其中一些空间。就像每个不分隔两个字母的空格一样。
        • “或”前面还有一个空格,如果你实在想不爽,也可以把“&1”后面的空格去掉。
        • 我刚刚注意到or之前有多余的空格,但是删除1之后的空格失败(可能是因为e在浮点数中有效)。
        • ...但我可以在and 之前删除它。 :)
        【解决方案7】:

        Haskell,64 个字符

        unwords.map(map snd.sort.zip(zipWith(*)[0..]$cycle[-1,1])).words
        

        好吧,如果您添加必要的“import List”,则为 76。

        【讨论】:

          【解决方案8】:

          J,58 个字符

          >,&.>/({~(,~(>:@+:@i.@-@<.,+:@i.@>.)@-:)@<:@#)&.><;.2,&' '
          

          【讨论】:

          • 阅读了所有这些代码高尔夫球,我开始讨厌 J。知道有这种语言可以做很多事情,但事情却很少。我讨厌的是我不知道这意味着什么。在我看来,这就像一堆变异的表情符号:P
          • 我认为每个 SO 高尔夫球手都需要下载 J 解释器并验证这些 J 答案。有很多,我知道其中一些只是写笑脸的人。
          • 显然,它实际上并不是一个解决问题的程序,而是一个秘密编码的消息,它会嘲笑所有不认识 J 的人。显然。
          • 我实际上还没有看到任何不诚实的 J 答案。 (Chris 可能比我更活跃于 SO。)不过,确实没有多少人会仔细检查这些...
          • 嘿。这次 Python 的列表推导和切片符号正好派上用场了。
          【解决方案9】:

          Python - 69 个字符

          (包括空格和换行符)

          这会处理所有 I/O。

          for w in raw_input().split():
           o=""
           for c in w:o=c+o[::-1]
           print o,
          

          【讨论】:

            【解决方案10】:

            Perl,78 个字符

            用于$_ 中的输入。如果这不可接受,请在开头为 $_=&lt;&gt;;$_=$s; 添加六个字符。换行符只是为了便于阅读。

            for(split){$i=length;print substr$_,$i--,1,''while$i-->0;
            print"$_ ";}print $/
            

            【讨论】:

            • 我只想为 perl -ne'' 添加 10 个字符 - 不多,我们可以使用 5.10 减少一些字符(将 print $/ 更改为 say"" 或至少删除空格在print 和变量之间,也许重写以将两个-- 压缩为-=2 并查看是否不能将其缩小为一个字符,删除循环结束括号前的;
            • 另外,将 while() 循环更改为 C 风格的 for() 循环可能(可能)会减少一些字符。没试过。
            • 我没有在这方面付出最大的努力;我一直在研究一些真实世界的代码以进行更改。我不确定是否可以消除--,但是鉴于上面的讨论,我什至不确定我是否符合规范。如果你想要这个条目,继续编辑,你可以拥有它:)
            猜你喜欢
            • 2010-12-17
            • 1970-01-01
            • 1970-01-01
            • 2011-01-15
            • 1970-01-01
            • 2010-12-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多