【问题标题】:Code Golf: Pig Latin代码高尔夫:猪拉丁
【发布时间】:2015-04-04 00:45:42
【问题描述】:

挑战:

输入任意长度的句子并将该句子中的所有单词转换为猪拉丁语。如果您不知道什么是猪拉丁语,请阅读Wikipedia: Pig Latin

规格:

  1. 假设所有单词都以空格分隔,并且所有句子都以感叹号、问号或句点结尾。

  2. 不要使用维基百科中提到的元音变体。

  3. 对于诸如面包和测验之类的词,完全可以使用 readbay、uizqay 而不是 eadbray 和 izquay。

  4. 函数或方法是完全可以接受的。换句话说,您不需要接受用户输入,但您必须显示用户输出。

  5. 假设没有输入包含复合词。

例子:

Input: I am a happy man.
Output: Iway amway away appyhay anmay.

如何获胜:

获胜者是能够编写程序以最少的字符完成挑战的人。

【问题讨论】:

  • @Byron Whitlock:获胜的满足感。如果你赢了,你的答案会打一个绿色的复选标记。 :P
  • 我们应该正确地将大写单词大写吗?我们可以忽略整个单词大写的情况吗?
  • @trinithis:没关系。无论哪种方式都可以。
  • 好的,谁投票决定关闭这个主题是离题?请那个人提供他/她决定这样做的理由吗?
  • @MtnViewMark:是的,你需要保持标点符号。

标签: language-agnostic code-golf rosetta-stone


【解决方案1】:

sed - 53/55 45/47 个字符

使用 -r 选项 (2+43):

s/\b[aeiou]\w*/w&/gi;s/\b(\w)(\w*)/\2\1ay/g

没有 -r 选项 (47):

s/\b[aeiou]\w*/w&/gi;s/\b\(\w\)\(\w*\)/\2\1ay/g

【讨论】:

    【解决方案2】:

    C# 257 96 个字符

    可读版本:

    string.Join(" ",
        args.Select(y =>
            ("aeiouAEIOU".Contains(y[0])
            ? y + "way"
            : y.Substring(1) + y[0] + "ay")
        )
    );
    

    精简

    string.Join(" ",args.Select(y=>("aeiouAEIOU".Contains(y[0])?y+"way":y.Substring(1)+y[0]+"ay")));
    

    输入:

    LINQ 帮助我写出好的高尔夫答案

    输出:

    INQLay elpshay emay riteway oodgay olfgay 答案

    【讨论】:

    • 使用 LINQ 减少了大约 2/3 的解决方案。
    • 哇,我从来没有在 C# 中见过这么短的高尔夫。 +1
    • @Maulrus:那是因为这个人错过了使它成为程序的一切。即你需要把class A{static void Main(string[]a){放在前面(当然,用“a”替换“args”。为什么他们使用多字母变量名实际上超出了我的理解。
    • @Johannes:哦,这很有道理。如果这不是一个完整的计划,我将撤回我的投票。
    • @mickey OP 的第 3 条规则规定忽略音节并仅在第一个字母上打断是可以接受的(尽管我同意你的观点,但它应该在音节上)。
    【解决方案3】:

    GolfScript - 60 53 52 51 49 46 个字符

    )](' '/{1/(."AEIOUaeiou"-!{\119}*"ay "}%));+\+
    

    【讨论】:

    • -1。示例输入给出了Iway amway away appyhay an.mayman. 转换不正确。
    • @KennyTM 输入以“!”结尾的规范“?”或者 ”。”。它并没有说它们可以以“.\n”结尾
    【解决方案4】:

    Ruby 1.9+:63 62 个字符

    只是一个简单的答案,可能可以缩短更多

    p gets.gsub(/\w+/){|e|"#{e=~/^(qu|[^aeiou]+)/i?$'+$&:e+?w}ay"}
    

    它处理qu (question => estionquay) 的情况,并使用双引号打印。 3 个字节来摆脱它们(我说没有关于这个的规范)

    编辑 1:如果使用 Ruby 1.9 保存一个字符 (?w),让我们使用它。

    【讨论】:

      【解决方案5】:

      Perl 87, 56, 47 个字符

      使用标点符号。

      感谢 mobrule。

      s/\b[aeiou]\w*/w$&/gi;s/\b(\w)(\w*)/\2\1ay/g
      

      用法:

      echo 'I, am; a: happy! man.' | perl -p piglatin.pl
      

      输出:

      Iway, amway; away: appyhay! anmay.
      

      【讨论】:

      • 不错的背负式解决方案!不错的演出。我喜欢看到 Perl 做它的事。
      • perl -p ... 运行,您可以再删除 12 个字符(减去额外命令行开关的 3 个字符)
      • 根据代码高尔夫的“规则”,您需要给自己一个 3 个字符的惩罚才能使用-p 开关。
      【解决方案6】:

      Groovy,117 100 91 85 83 79 个字符

      print args[0].replaceAll(/(?i)\b(\w*?)([aeiou]\w*)/,{a,b,c->c+(b?b:'w')+"ay"})
      

      可读版本:

      print args[0]
      .replaceAll(
          /(?i)\b(\w*?)([aeiou]\w*)/ ,
          {
              a, b, c ->
              c + ( b ? b : 'w' ) + "ay" 
          })
      

      【讨论】:

        【解决方案7】:

        Haskell:244 199 222 214 个字符

        解决方案在原始大写的基础上对转换后的单词进行合理的大写。现在可以正确处理前导辅音簇。注意:最后一行末尾不包含换行符。

        import Data.Char
        import Data.List
        q(x:y,z)|w x=x%(z++toLower x:y++"ay")|0<1=x:y++z
        q(_,z)=z++"way"
        x%(y:z)|isUpper x=toUpper y:z|0<1=y:z
        w=isAlpha
        main=interact$(>>=q.break(`elem`"aeiouAEIOU")).groupBy((.w).(==).w)
        

        测试输入:

        Did the strapping man say: "I am Doctor X!"?
        

        测试输出:

        Idday ethay appingstray anmay aysay: "Iway amway Octorday Xay!"?
        

        【讨论】:

          【解决方案8】:

          VB.NET:106 个字符

          假设“s”是输入,也是Imports System.Text.RegularExpressions(有趣的是,由于需要 @ 字符串字面量前缀和尾随分号,这个 VB.NET 版本比 C# 版本高出 3 个字符。)

          Return Regex.Replace(Regex.Replace(s, "(?i)\b([aeiou]\S*)", "$1way"), "(?i)\b([^aeiou\s])(\S*)", "$2$1ay")
          

          【讨论】:

          • 一句夸赞就放下:)
          • 它周围仍然需要一个程序
          • @Johannes - 不一定。它总是可以通过类似这样的 (tirania.org/blog/archive/2008/Sep-08.html) 或任何这些 (stackoverflow.com/questions/2058715/…) 运行。没有理由过度夸大现有的代码高尔夫对动态语言的偏见。他们可以坚持自己的优点:)
          • @matt:在这种情况下,我可以假设输入由函数 i 给出,而不是使用迭代器 $input 来缩短我的许多 PowerShell 打高尔夫球,这也缩短了很多时间(至少它可以决定是否击败 Ruby)。
          • 另外,如果它在 REPL 中,您可以删除 Return
          【解决方案9】:

          Python 3 — 107 106 个字符

          不保留大小写,正如评论中所允许的那样。但标点符号被保留。添加空格和换行符只是为了便于阅读(因此;import re 之后)。

          import re;
          print(re.sub('(?i)\\b(qu|[^aeiou\W]*)(\w*)',
                       lambda m:m.group(2)+(m.group(1)or'w')+'ay',
                       input()))
          

          如果我们不处理“qu”字,可以删除 3 个字符 (qu|)。

          示例用法:

          $ python3.1 x.py
          The "quick brown fox" jumps over: the lazy dog.
          eThay "ickquay ownbray oxfay" umpsjay overway: ethay azylay ogday.
          

          【讨论】:

            【解决方案10】:

            Python 3 - 100 103 106 个字符

            (类似于 KennyTM 的;正则表达式在这里有所不同。)

            import re;print(re.sub('(?i)(y|qu|\w*?)([aeiouy]\w*)',lambda m:m.group(2)+(m.group(1)or'w')+'ay',input()))
            

            注意:从 100 个字符变为 103 个字符是因为修改了正则表达式以解释“qu”。

            注意 2:当“y”用于元音时,103 字符版本会失败。呜呜。 (另一方面,当“y”用于元音时,KennyTM 的 106 字符版本也会失败,所以无论如何。)

            【讨论】:

              【解决方案11】:

              嘘 (.NET):91 个字符

              与 VB.NET 答案相同的概念,只是使用 Boo 来节省一些击键。

              print /(?i)\b([^aeiou\s])(\S*)/.Replace(/(?i)\b([aeiou]\S*)/.Replace(s, "$1way"), "$2$1ay")
              

              糟糕...我刚刚注意到这不能处理结尾标点符号。或者真的是任何标点符号。哦,好吧 - 许多其他解决方案也没有。

              【讨论】:

                【解决方案12】:

                Lua,109 个字符

                print((io.read():gsub("(%A*)([^AEIOUaeiou]*)(%a+)",function(a,b,c)return a..c..b..(#b<1 and"way"or"ay")end)))
                

                输入:

                To be honest, I would say "No!" to that question.
                

                输出:

                oTay ebay onesthay, Iway ouldway aysay "oNay!" otay atthay uestionqay.
                

                【讨论】:

                  【解决方案13】:

                  Perl,70 个字符

                  让球滚动:

                  while(<>){for(split){s/^([^aeiou]+)(.*)/$2$1ay / or $_.='way ';print}}
                  

                  我相信它可以在某个地方进行改进。

                  【讨论】:

                  • 你可以通过 perl -pe '...' 来砍掉一些,而不是自己在代码中的 while/print 位。
                  • 使用示例输入会生成不正确的输出Iay amway away appyhay an.may。它应该是Iway(包括不区分大小写的标志)和anmay.(忽略非单词字符)。
                  【解决方案14】:

                  Python - 107 个字符

                  i=raw_input()
                  print" ".join(w+"way"if w[0]in"aeiouyAEIOUY"else w[1:]+w[0]+"ay"for w in i[:-1].split())+i[-1]
                  

                  【讨论】:

                  • 有很多单词使用首字母Y作为辅音,但很少使用首字母Y作为元音。此版本适用于YggdrasilYttrium,但似乎忽略了更常见的yesyodelyoung。它给出了yeswayyodelwayyoungway
                  【解决方案15】:

                  PHP 102 字节

                  <?foreach(split(~ß,SENTENCE)as$a)echo($b++?~ß:'').(strpos(' aeuio',$a[0])?$a.w:substr($a,1).$a[0]).ay;
                  

                  使用 preg 80 字节的 PHP

                  <?=preg_filter('#\b(([aioue]\w*)|(\w)(\w*))\b#ie','"$2"?$2way:$4$3ay',SENTENCE);
                  

                  【讨论】:

                    猜你喜欢
                    • 2011-01-24
                    • 2010-12-17
                    • 1970-01-01
                    • 1970-01-01
                    • 2010-12-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多