“便捷回文”检查器


39

如果您曾经尝试编写回文代码,那么您会知道会遇到多少括号。()()是不是回文,即使它还挺看起来像它应该的,而())(()(都是回文和两个非常愚蠢的期待。如果不是这样的话,会不会很方便?

如果一个字符串等于其所有括号(),方括号()和花括号()颠倒时所得到的字符串,则该字符串很容易回文。没有其他特殊字符需要翻转。(有时会配对,但通常不会配对,因此被忽略了。)()[]{}<>

您的任务是用您的语言编写一个程序(接受STDIN的输入)或一个函数(接受单个字符串参数),该程序(a)当其参数为回文形式且给出不同的,一致的false时,给出一致的真值* (b)本身很方便回文。

例如,以下输入通常是回文的:

racecar
(a)(bb)(a)
void main(int argc, *char[] argv) {} (vgra []rahc* ,cgra tni)niam diov

并且以下不是:

non-palindrome
A nut for a jar of tuna?
(old [style] parens) )snerap ]elyts[ dlo(
ingirumimusnocte)etconsumimurigni

除了解释器/编译器标志之外,您不得依赖任何外部状态(特定的文件名,目录结构,其他用户输入,Web访问等)。

另外,您不得使用“注释技巧”来注释掉或通过利用语言的注释功能来渲染未使用的某些代码。例如,不允许以下所有操作,因为它们包含可以安全地移除或销毁的非功能性部件(以失去回文性为代价):

{some code} // {edoc emos}
{some code} NB.BN {edoc emos}
"n\" ;{edoc emos} ;"; {some code}; "\n"

显然,这可能无法涵盖所有​​此类情况,但是这里面临的挑战的精神是不要使用注释和未解析的**代码来实现回文,而要使用更正的括号和括号。我在看着你,LISP,Brainfuck。

这是一个,因此最短的代码获胜,但是欢迎所有长度的代码。

* 通过一致的true和false值,我的意思是,您可以返回一对值中的一个,例如1true和0false,或者Falsetrue和"no"false,只要这些值彼此不同并且不更改程序的运行。使用任何可以节省字符的内容。

** 不要与未执行混淆:有效且可能做奇怪的事情但从未调用过的代码是好的。


诸如此类的东西if(false){some code}或未使用的变量呢?他们被允许吗?
ace_HongKong独立

@ace如果您的语言以某种方式解析或检查了未执行的代码是否具有类型一致性或语法正确性,那就很好。如果它等同于注释,因为您的语言没有检查该块的内部,则如果它会引发语法错误,那就不好了。我认为,如果您可以找到的有效用途(eslaf)fi,就可以使用if(false)
algorithmhark

58
我花了很长时间才弄清楚为什么()()不是回文
恢复莫妮卡

代码是否必须与多行输入一起使用?
Ventero 2014年

@Ventero换行符和回车符是字符,它们没有任何可翻转的对,因此我想说它们算作普通字符。
algorithmhark

Answers:


13

J(60)

(|.-:'())([]][{}}{'&charsub) :: (busrahc&'}{{}][[])(()':-.|)

这是一个带有参数的函数:

   (|.-:'())([]][{}}{'&charsub) :: (busrahc&'}{{}][[])(()':-.|) 'ingirumimusnocte)etconsumimurigni'
0
   (|.-:'())([]][{}}{'&charsub) :: (busrahc&'}{{}][[])(()':-.|) '(a)(bb)(a)'
1

说明:

  • f :: gf在输入上运行该函数,如果返回没有错误,则返回结果。如果f失败,它将运行g

  • f(|.-:'())([]][{}}{'&charsub),它可以完成实际工作:

    • |.:反向
    • -::等于
    • '())([]][{}}{'&charsub:用相对的支架替换每个支架
  • g函数是(busrahc&'}{{}][[])(()':-.|),这是无意义的,但在语法上是有效的。busrahc未定义,但这无关紧要,因为它仅在运行时才解决(并且不会运行)。

你可以把你的保存字符f :: gg@-@fg等价于该钩子,(-.|)因为:这样输出分别为-1和空列表(分别用于方便回文)和不用于回文。
algorithmhark

34

GolfScript,107 91

.4:ab-1:ba=;1
%ba%{...fi@@=
c43.=;)('"([{
}])"'~?~'"([{
}])"')(;=.34c
=@@if...}%ab%
1;=ab:1-ba:4.

换行符是艺术性的。fic43c是noops,但执行整个代码。

打印-3-1-1方便的回文,-4-1-1否则。在线尝试!

备用版本,155个字节

以64个字节为代价,可以在以下方面进行改进:

0!*1{!}\;:);0:f;0:i;-1:ab;9:ba;
...=;1%ab%{....i@f@@fi@@=@.=@\)
+""'"([{}])"'~+?+~'"([{}])"'""+
(\@=.@=@@if@@f@i....}%ba%1;=...
;ab:9;ba:1-;i:0;f:0;(:;\{!}1*!0

和以前一样,将执行整个代码,并且每个字节都会影响输出。

打印010方便的回文,-100否则。在线尝试!

测试与范例

$ base64 > palindrome.gs -d <<< LjQ6YWItMTpiYT07MSViYSV7Li4uZmlAQD1jNDMuPTspKCciKFt7fV0pIid+P34nIihbe31dKSInKSg7PS4zNGM9QEBpZi4uLn0lYWIlMTs9YWI6MS1iYTo0Lg==
$ wc -c palindrome.gs
91 palindrome.gs
$ rev palindrome.gs | tr '([{}])' ')]}{[(' | diff - palindrome.gs
$ echo -n 'r(a[c{"e"}c]a)r' | golfscript palindrome.gs
-3-1-1
$ echo -n 'totallynotapalindrome' | golfscript palindrome.gs
-4-1-1
$
$ base64 > pal.gs -d <<< MCEqMXshfVw7Oik7MDpmOzA6aTstMTphYjs5OmJhOy4uLj07MSVhYiV7Li4uLmlAZkBAZmlAQD1ALj1AXCkrIiInIihbe31dKSInfis/K34nIihbe31dKSInIiIrKFxAPS5APUBAaWZAQGZAaS4uLi59JWJhJTE7PS4uLjthYjo5O2JhOjEtO2k6MDtmOjA7KDo7XHshfTEqITA=
$ wc -c pal.gs
155 pal.gs
$ rev pal.gs | tr '([{}])' ')]}{[(' | diff - pal.gs
$ echo -n 'r(a[c{"e"}c]a)r' | golfscript pal.gs
010
$ echo -n 'totallynotapalindrome' | golfscript pal.gs
-100
$ for i in {1..154}; do head -c $i pal.gs > tmp.gs; tail -c +$[i+2] pal.gs >> tmp.gs
> [ "$(echo -n 'r(a[c{"e"}c]a)r' | golfscript tmp.gs 2> /dev/null)" = "010" ] && echo $i
> done; rm tmp.gs
1
for i in {1..154}; do head -c $i pal.gs > tmp.gs; tail -c +$[i+2] pal.gs >> tmp.gs
>  [ "$(echo -n '42' | golfscript tmp.gs 2> /dev/null)" = "-100" ] && echo $i
> done | grep '^1$'; rm tmp.gs

这个怎么运作

.             # Duplicate the input string.
4:ab-1:ba     # Save 4 in “ab” and -1 in “ba”.
=;            # Compare 4 to -1 and discard the result.
1%            # Save every element from the input string in a new string.
ab%           # Reverse the input string.
{             # For each character in the input string:
  ...         # Duplicate the character thrice.
  fi          # Variable “fi” is undefined; this does nothing.
  @@=         # Verify that the character is equal to itself; push 1.
  c43         # Variable “c43” is undefined; this does nothing.
  .=;         # Verify that 1 is equal to itself and discard the result.
  )(          # Increment and decrement the character.
  '"([{}])"'~ # Push that string and evaluate it. Result: '([{}])'
  ?           # Retrieve the character's position in '([{}])'. -1 means not found.
  ~           # Negate the position.. Examples: -1 -> 0    0 -> -1    2 -> -3
  '"([{}])"') # Push that string and pop its last element. Result: '"([{}])' 34
  (;          # Decrement 34 (the ASCII code of a double quote) and discard.
  =           # Retrieve the corresponding character.
  .34         # Duplicate the character and push 34.
  c           # Variable “c” is undefined; this does nothing.
  =           # If the character is a double quote, the index was -1.
  @@if        # In that case, replace the double quote with the original character.
  ...         # Duplicate the new character thrice.
}%            #
ab%           # Save every fourth element in a new string to discard dummy values.
1;            # Push 1 and discard.
=             # Push 1 if the modified string matches the original, 0 otherwise.
ab:1-         # Save 4 in “1” and subtract.
ba:4.         # Save -1 in “4” and duplicate.

0!*           # Pop and push the input string.
1{!}\;:);     # Make “)” an alias for “!”.
0:f;0:i;      # Variables.
-1:ab;9:ba;   # Moar variables.
...=;         # Duplicate the input string.
1%ab%         # Reverse the copy.
{             # For each character in the input string:
  ....        # Duplicate the character four times.
  i@          # Push 0 and rotate a string copy on top of it.
  f@@fi@@     # Push 0 and rotate 0 on top of it.
  =@          # Push 1 and rotate a string copy on top of it.
  .=@         # Push 1 and rotate 1 on top of it.
  \)+         # Negate a 1 and add. Result: 1
  ""          # Push that string.
  '"([{}])"'  # Push that string.
   ~+         # Evaluate the second string and concatenate. Result: '([{}])'
   ?          # Retrieve the characters position in '([{}])'. -1 means not found.
   +~         # Add 1 to the position and negate. Ex.: -1 -> -1 | 0 -> -2 | 1 -> -3
  '"([{}])"'  # Push that string.
  ""          # Push that string.
  +           # Concatenate. Result: '"([{}])"' 
  (\          # Pop the first double quote and swap it with the rest of the string.
  @=.         # Retrieve the corresponding character and duplicate it.
  @=          # If the character is a double quote, the index was -1.
  @@if        # In that case, replace the double quote with the original character.
  @@          # Rotate the modified character to the bottom.
  f@i....     # Push dummy values.
  }%          #
  ba%         # Save every ninth element in a new string to discard dummy values.
  1;          # Push 1 and discard.
  =           # Push 1 if the modified string matches the original, 0 otherwise.
  ...;        # Duplicate thrice and discard the last copy.
  ab:9;ba:1-; # Variables.
  i:0;f:0;    # Moar variables.
  (:;\        # Negate, override “;” and swap.
  {!}1*!0     # Negate twice and push 0.

13

露比110

(z=gets;r=z.tr *["([{}])",")]}{[("];p *z==r.reverse;1)||(1;esrever.r==z* p;[")]}{[(","([{}])"]* rt.z=r;steg=z)

true如果输入是方便的回文,false则打印,如果不是。请注意,此解决方案假定输入未以换行符终止,因此请使用进行测试echo -n

echo -n '(a)(bb)(a)' | ruby convpal.rb
true

echo -n '(a)(bb()a(' | ruby convpal.rb
false

# note that for this to work, the file must not contain a newline
# to remove a trailing newline, pipe it through tr -d $'\n'
cat convpal.rb | ruby convpal.rb
true

这是对“ 回文回文检查器”的回答的一个简单直观的解释(到目前为止,还没有真正打过高尔夫球)。使用的主要技巧是,第一个带括号的表达式始终返回1,因此从不评估布尔表达式的后半部分(但会对其进行解析)。

适应此问题的唯一困难是弄清楚如何添加呼叫,z.tr以便其“方便的反向”在语法上也有效-但我可以简单地使用已经使用过的puts相同的技巧:*,在上半部分被解析为splat运算符(将数组内容用作函数参数),下半部分用作数组乘法(或重排)运算符。

红宝石157 297,所有执行的代码

w=tsoh=gets p
o=rt=esrever=Gem
q=tsoh.tr *["([{}])",")]}{[("]
q==esrever.host=w=tsoh.reverse==q
[")]}{[(","([{}])"]* rt.host=q
meG=reverse=tr=o
p steg=host=w

此版本(略长)执行所有代码,除两行外,所有行均会影响输出,该输出在最后一行中显示-但所有行均已解析并执行,没有任何错误。此版本将任何尾随的换行符解释为输入的一部分,因此请使用它echo -n进行测试,或在输入之前添加换行符。true如果输入是方便的回文,则打印,false否则打印。

说明

# Read the input by calling gets(nil), which is achieved by passing the return
# value of a call to Kernel#p (which returns nil if no argument is supplied) to
# gets.
w=tsoh=gets p
# Assign the global Gem module to three variables.
# The variable names are the reversed names of methods we have to call later.
# This doesn't necessarily have to be the Gem module, any global module/variable
# (or class that allows object creation through a call to the module itself,
# e.g. Hash or GC) with a writable property would do, but Gem#host was
# the shortest one I could find. This is necessary because Ruby doesn't
# allow setting previously undefined properties through the dot syntax.
o=rt=esrever=Gem
# Replace the parentheses with the corresponding flipped one.
# sserts is the reverse of the property name we're going to use later.
q=tsoh.tr *["([{}])",")]}{[("]
# Do the convinient palindrome check and assign its result to a few variables
# and Gem's host property.
q==esrever.host=w=tsoh.reverse==q
# Here, the * is parsed as array join operator.
[")]}{[(","([{}])"]* rt.host=q
# Nothing special here.
meG=reverse=tr=o
# Print the result of the palindrome check, which was stored in w.
p steg=host=w

9

GolfScript,61个字符

好的,这是GolfScript中的基准解决方案。我相信它可以进一步改善:

{.-1%{"([{}])".2$?~@[.]@+=}%=}~{=%{=+@[.]@~?$2."([{}])"}%1-.}

与GolfScript一样,该程序从stdin读取其输入。它输出:

1{=%{=+@[.]@~?$2."([{}])"}%1-.}

如果输入是如上挑战中所定义的方便回文,并且:

0{=%{=+@[.]@~?$2."([{}])"}%1-.}

如果不是这样。

说明:该程序在很大程度上取决于未执行代码可以解析的裁决。它由两个代码块组成,两个代码块之间用花括号({ })分隔,它们是彼此的镜像。

第一个代码块由其后的代码执行~,并检查输入是否为方便的回文,输出1是否为便利的回文0。第二个代码块执行,因此仅保留在堆栈中,直到程序结束,并且GolfScript解释程序自动将堆栈中的所有内容进行字符串化和打印。

应当指出的是,GolfScript解释确实非常少的语法检查在分析时(或曾经为此事); GolfScript代码块文字几乎可以包含任何内容,即使在执行时可能崩溃。仍然有一些语法错误,例如未终止的字符串文字,即使在未执行的代码中也确实会引发错误,因此,我认为这种解决方案(勉强)属于规则之内。

附言 查看实际执行的代码,它包含一些方便的回文元素@[.]@,例如字符串文字"([{}])",甚至是loop %{ ... }%。这提供了一个诱人的建议,即实际上可能会实现“本性回文” GolfScript解决方案,在该解决方案中将执行完整的回文程序并发挥作用。由于我还没有自己制作一个人,因此我向第一个设法提出自己建议的人提供+100 rep赏金


3
等等,您的代码本身就是回文吗?:O
Fabricio 2014年

我倾向于将这种解决方案更像"n\";X;";X;"\n"是评论的方式,但是我会带给您疑问的好处。但是,我确实在寻找这样的“本性回文”解决方案,或者至少是那些不执行区块的人比较不满意的解决方案。
algorithmhark

我的答案是noop(未定义的变量)和一些无法完成的部分(例如1;)。那仍然算是功能齐全吗?
丹尼斯2014年

@丹尼斯:是的,我认为是的。恭喜,这肯定令人印象深刻。这个问题似乎已经足够新了,我尚无法发布赏金,但几天后您就会收到。
Ilmari Karonen 2014年

1
输出格式leeway abuuuse :-)
John Dvorak

4

JavaScript(ES6),245个字节

我想要一个可以在浏览器中运行的JS答案,就在这里。

eurt=>eurt==(("",eurt))["split"||"nioj"]("")["map"||"esrever"](x=>({'{':'}','}':'{','[':']',']':'[','(':')',')':'('})[x]||x||[x]({')':'(','(':')',']':'[','[':']','}':'{','{':'}'})>=x)["reverse"||"pam"]("")["join"||"tilps"]((true,""))==true>=true

删除所有从未真正运行过的代码,我们得到以下信息:

eurt=>eurt==(("",eurt))["split"||"nioj"]("")["map"||"esrever"](x=>({'{':'}','}':'{','[':']',']':'[','(':')',')':'('})[x]||x||[x]({')':'(','(':')',']':'[','[':']','}':'{','{':'}'})>=x)["reverse"||"pam"]("")["join"||"tilps"]((true,""))==true>=true
eurt=>eurt==(("",eurt))["split"        ]("")["map"           ](x=>({'{':'}','}':'{','[':']',']':'[','(':')',')':'('})[x]||x                                                           )["reverse"       ]("")["join"         ]((true,""))==true>=true

可以简化为:

eurt=>eurt==eurt.split("").map(x=>({'{':'}','}':'{','[':']',']':'[','(':')',')':'('})[x]||x).reverse("").join("")

您可以使用n1 / 1n代替true / eurt,在某些地方用逗号代替||,并摆弄括号切换器来节省60个字节:n1=>n1==(('',n1))['nioj','split']``['esrever','map'](c=>`()[]{}`[`()[]{}`['indexOf'](c)^1]||c||[1^(c)['fOxedni']`{}[]()`]`{}[]()`>=c)['pam','reverse']``['tilps','join']((1n,''))==1n>=1n(185字节)
Yair Rand

3

Javascript(ES6)288

Spidermonkey命令行shell中运行。从STDIN读取一行并输出,true或者false取决于输入是否是方便的回文。

((print)((eval)('r=readline()')==([0]['map']['call'](r,x=>({'{':'}','}':'{','[':']',']':'[','(':')',')':'('})[x]||x)['reverse']()['join']('')))&&((('')['nioj']()['esrever'](x||[x]({')':'(','(':')',']':'[','[':']','}':'{','{':'}'})>=x,r)['llac']['pam'][0])==('()enildaer=r')(lave))(tnirp))

该代码在语法上是有效的,但&&由于该print函数返回falsey值,因此之后的所有内容均不执行。

您可以在Firefox的控制台中运行此代码,方法是先运行此填充程序以模拟readlineprint功能。readline根据需要在内部编辑输入:

readline = function(){ 
    return "void main(int argc, *char[] argv) {} (vgra []rahc* ,cgra tni)niam diov"; 
}, print = console.log.bind(console);

这是输出的一个简单示例:

命令行示例


趁着&&真的很聪明,我赞扬你(但它似乎有点cheaty)
MayorMonty

2

05AB1E,35字节

"{[()]}"DRr‡`rJ¹Q,Q¹Jr`‡rRD"{[()]}"

在线尝试!

说明:

                     # Implicit input
 "{[()]}"            # Push "{[()]}" onto the stack
         DR          # Pushes a reversed copy onto the stack
           r         # Reverse the order of the stack
            ‡        # Transliterate
             `       # Flatten array on stack
              r      # Reverse order of stack
               J     # Join stack
                ¹Q   # Check equality with first input
                  ,  # Print
                     # Everything after is still syntactically correct, but just does not print anything.

我认为这无济于事,因为答案无效,但"()[]{}"您不能这样做žu„<>-
acrolith

@daHugLenny现在有效
奥利弗·倪

程序的其余部分是否q至少经过语法语法分析?如果没有,我认为这相当于注释掉代码的后半部分。
algorithmhark

@algorithmshark固定。
奥利弗·尼

1

CJam,38个字节

Q~"=re%W_@%W_q"`{[()]}`"q_W%@_W%er="~Q

"=re%W_@%W_q"1如果输入是回文,"=re%W_@%W_q"0则打印。

CJam解释器中在线尝试。

这个怎么运作

Q~                                     e# Evaluate an empty string.
  "=re%W_@%W_q"                        e# Push that string.
               `                       e# Inspect. Pushes "\"=re%W_@%W_q\"".
                {[()]}                 e# Push that block.
                      `                e# Inspect. Pushes "{[()]}".
                       "           "~  e# Push and evaluate.
                        q              e# Read from STDIN.
                         _W%           e# Push a reversed copy.
                            @          e# Rotate "{[()]}" on top of the stack.
                             _W%       e# Push a reversed copy.
                                er     e# Perform transliteration.
                                  =    e# Compare to the input string.
                                     Q e# Push an empty string.

执行完程序后,CJam自动将所有三个项目打印在堆栈上:检查的字符串,字符串比较中的布尔值和空字符串。


0

Perl,83 + 2 = 85字节

与运行 -nl

say$_~~reverse y-"({[]})"-")}][{("-r;exit;tixe;r-")}][{("-"({[]})"-y esrever~~_$yas

代码在打印输入的真实性后退出。分号后的所有内容都会被解释(如果脚本未到达分号,它将在到达该点时崩溃exit),但不会执行。如果我exit;tixe;不使用代码,它在崩溃前仍会正确打印结果。

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.