我是回文集。你是?


103

已经有几个先前 尝试问这个问题,但也符合本网站现代化标准。根据对Meta的讨论,我将其重新发布,以允许在我们现代规则集下进行公平竞争。

背景

是一个字符串,“读取相同的向前和向后”,即字符串的反向相同字符串本身。我们在这里不是在谈论“方便回文”,而是严格的逐字符反转。例如,()()不是回文,而是())(

任务

编写一个程序或函数,该程序或函数将字符串S(或您所用语言的适当等价形式)作为输入,并具有一个输出Q(您选择的类型)。您可以使用任何合理的方式获取输入并提供输出。

  • 当输入S是回文时,输出Q应该具有值A(对于任何回文S而言都是相同的)。
  • 当输入S不是回文时,输出Q应该具有值B(对于任何非回文S而言都是相同的)。
  • AB必须彼此不同。

换句话说,将所有回文映射到一个值,将所有非回文映射到另一个值。

另外,您编写的程序或函数本身必须是回文式(即其源代码必须是回文式),这成为源代码挑战。

澄清说明

  • 尽管truefalseAB的明显选择,但是您可以对“是回文”和“不是回文”输出使用任意两个不同的值,而不必是布尔值。
  • 我们在这里在字符级别定义字符串反转;éé不管程序是以UTF-8还是Latin-1编码,它都是回文,即使它不是UTF-8编码后的八位字节回文序列。
  • 但是,即使您的程序包含非ASCII字符,它也只需要用于ASCII输入即可。具体来说,输入S将仅包含可打印的ASCII字符(包括空格,但不包括换行符)。除其他外,这意味着,如果将输入视为字节序列而不是字符序列,则程序仍可能符合规范(除非您语言的I / O编码奇怪)。因此,仅在检查程序具有正确的形式时,前一项目符号中回文的定义才真正重要。
  • 将程序隐藏在注释或字符串文字中的一半是合法的,尽管这是不合法的。您的评分是根据长度而不是创造力进行的,因此请随意使用“无聊”的方法来确保您的程序是回文。当然,由于您的评分很长,因此程序中什么都不做的部分会使您的成绩更差,因此,如果可以管理程序,则可以同时使用程序的两半。
  • 由于胜利标准是以字节为单位的,因此您需要指定编写程序的编码,以便能够对其进行评分(尽管在许多情况下,很明显您正在使用哪种编码)。

胜利标准

即使该程序需要在字符级别上成为回文,但我们仍使用字节来查看谁获胜。具体来说,程序越短(以字节为单位)越好;这是一个挑战。为了允许比较提交(尤其是使用相同语言的提交),请将程序的字节数放在提交的标头中(如果字符数与字节数不同,则加上字符数)。


12
有人可以解释一下为什么()()不是回文吗?
Emilio M Bumachar '17

58
@EmilioMBumachar尝试更换(a)b。是abab回文吗?不,它一定是abba。那()()也不是回文。一定是())(
DLosc

7
那些完全使用注释使程序回文的解决方案对我来说似乎是一个漏洞:(
kennytm

15
@kennytm禁止使用它们会更糟,因为没有令人满意的方法以与语言无关的方式客观地做到这一点。(有什么评论?如何将未使用的一半放入丢弃的字符串文字中?关于2D语言,在那里您可以拥有根本无法获得的完美可执行代码?)
Martin Ender

9
()() is not a palindrome, but ())( is. 恭喜,您已加入reddit!
numbermaniac

Answers:


137

Brachylog(2),在Brachylog的代码页中为3个字节

I↔I

在线尝试!

这是一个完整的程序,通过标准输入(使用Brachylog的常量语法,即字符串用双引号引起来)进行输入,并通过标准输出进行输出。输出true.用于回文输入和false.非回文输入。

该程序不仅是回文的,而且还具有左右对称(并且可能在某些字体上/下)的镜像对称性。

说明

在Brachylog中,大写字母标记程序中具有相同值的点;它几乎像电路一样用于将信息从程序的一部分传送到另一部分。这样的结果是,如果将命令括在同一对大写字母之间,则实际上是在断言该命令的输入和输出是相同的。Brachylog隐式接受输入,因此在这种情况下,我们还断言命令的输入与程序的输入相同。在此程序中,我们使用命令,它会反转内容(在这种情况下为字符串)。因此该程序有效地断言输入的前后方向相同。

false.如果无法立即纠正true.程序中的所有断言,或者程序中的断言彼此兼容,则Brachylog中的完整程序(相对于函数)将返回一个布尔值。在这里,我们只有一个断言-反转输入不会改变输入-因此该程序充当回文检查器。


49
180度旋转对称,非常漂亮。
ATaco

7
...以及沿垂直和水平轴的对称性:-)
Luis Mendo

13
@SteakOverflow Brachylog使用自定义代码页,因此这些字符未以UTF-8编码
DJMcMayhem

4
我加入这个社区只是为了对该程序投票。哇。
比尔·米歇尔

4
@ATaco左/右和上/下对称性的组合意味着180度旋转对称性。;)
Eric Duminil 17/02/23

55

Pyth,3个字节

_I_

返回TrueFalse

在线尝试!

这个怎么运作

  _  Reverse the input.
_I   Invariant-reverse; test if the reversed input is equal to its reverse.

1
为什么需要决赛_
busukxuan

34
@busukxuan从问题“另外,您编写的程序或函数本身必须是回文式”
isaacg

1
为什么要这么多投票...这个答案似乎并不难...?
ghosts_in_the_code

1
大概吧。仍然似乎有点不公平。在某些问题上,一个人必须付出很多艰苦的工作来回答,而其他问题则容易得多。支出还是一样的。顺便说一句,我也赞成:P
ghosts_in_the_code

4
@ghosts_in_the_code我只有100个以上的答案实际上很难写,但是我花了几天的答案却很少得到支持。最后,一切都变得平坦了……
Dennis




23

Mathematica,23个字节

QemordnilaP;PalindromeQ

不是很有趣,但是为了完整起见...

上面是CompoundExpression评估为的PalindromeQ,它解决了挑战。QemordnilaP只是一个未定义的标识符,由于会被忽略;


21

Haskell,87 85 44 34字节

p=(==)<*>reverse--esrever>*<)==(=p

说明:((->) a)是Applicative的实例(感谢@faubiguy),<*>定义为

(<*>) f g x = f x (g x)

因此,通过代入论点,可以看到为什么这样做。


1
你能解释一下代码吗?
bli

1
@bli之后的所有内容--均为评论。
theonlygusti

3
@theonlygusti Haskell非常陌生,只有一半帮助。
Yakk

@Yakk这是某种形式的组合(==)reverse以及id功能(id是恒等函数)。
tbodt

您可以使用<*>代替<$>并删除<*>id
faubi

20

05AB1E,3个字节

码:

ÂQÂ

说明:

     # Bifurcate (duplicate and reverse the duplicate) implicit input
 Q    # Check if equal
  Â   # Bifurcate the result

使用CP-1252编码。在线尝试!


为什么不干脆ÂQ
尼尔A.

1
@NeilA。代码本身也必须是回文。
阿德南

17

PHP,55字节

<?=strrev($s=$_GET[s])==$s;#;s$==)]s[TEG_$=s$(verrts=?<

另外,语言的名称是回文,所以……加分!


鬼nea的解决方案。
Martijn

16

MATL,7个字节

tPX=XPt

在线尝试!

返回[1; 1]用于回文输入,[0; 0],否则。

t       % duplicate the input
P       % reverse the second string
X=      % check the two strings are exactly equal (returns 0 or 1)
XP      % flip array (does nothing)
t       % duplicate the answer, giving either [1;1] or [0;0]
        % (implicit) convert to string and display

15

12 11字节

现在无评论!

x:RVaQaVR:x

将输入作为命令行参数;1回文输出,0非回文输出。在线尝试!

我们要做的核心是RVaQareverse(a) string-equals a。该代码x:RVaQa计算该结果并将其分配给x。然后VR:x将的值分配x给变量VR。由于此赋值是程序中的最后一条语句,因此其值也将自动打印。瞧!

有关使用某些未定义行为的先前有趣版本,请参阅修订历史记录。



9

R,111103字节

all((s<-el(strsplit(scan(,"",,,"\n"),"")))==rev(s))#))s(ver==)))"",)"n\",,,"",(nacs(tilpsrts(le-<s((lla

不是最原始的答案。#R中的注释字符

取消高尔夫:

all((s<-el(strsplit(scan(,"",,,"\n"),"")))==rev(s))
#
))s(ver==)))"",)"n\",,,"",(nacs(tilpsrts(le-<s((lla

该功能将字符串from scan转换为原始字节charToRaw。将这些原始字节与rev()函数中的原始字节进行一对一比较,这将颠倒其参数的顺序。这部分的输出是TRUE和/或的向量FALSE
all函数然后输出TRUE如果所有这些元件是TRUE

在此,对于一个以上单词的输入,"\n"scan功能是必需的。

上一个答案(按字节),81个字节

function(s)all((s=charToRaw(s))==rev(s))#))s(ver==))s(waRoTr‌​ahc=s((lla)s(noitcnu‌​f

- 24个字节感谢@rturnbull


您可以通过charToRaw在分配给之前进行转换s并更改将sep参数设置为的方式来节省大量字节scanall((s<-charToRaw(scan(,"",,,"\n")))==rev(s))#))s(ver==)))"n\",,,"",(nacs(waRoTrahc-<s((lla
rturnbull

(此外,这种方法不适用于éé使用UTF-8编码的输入,但我认为这不会违反挑战规则。)
rturnbull

@rturnbull:谢谢您的投入!我确实éé使用latin1编码进行了测试。
弗雷德里克

由于必须按字符进行测试,因此我认为当前的程序违反了规则。
弗雷德里克

我不确定以前的版本是否违反规则。OP指出:“除其他事项外,这意味着如果将输入视为字节序列而不是字符序列,则程序仍可能符合规范(除非您语言的I / O编码很奇怪)。 ”
rturnbull

8

RProgN,11个字节

~]S.E E.S]~

前半部分完成了所有繁重的工作,而由于RProgN的方便,后半部分是No-op。

~]S.E E.S]~
~           # Treat the word as a Zero Space Segment
 ]          # Duplicate the top of the stack
  S.        # Reverse the top of the stack
    E       # Compare if these values are equal
      E.S]~ # A no-op, because the ~ is at the end of the word, not the start.

在线尝试!


8

视网膜,53字节

字节数假定为ISO 8859-1编码。

$
¶$`
O$^`\G.
»
D`
M$`^.+$
$+.^`$M
`D
»
.G\`^$O
`$¶
$

在线尝试!

我很确定这不是最佳选择(该»行似乎特别浪费,并且我有一个45字节的回文解决方案,除了一个字符外),但我想这是一个开始。


8

GNU sed64 59 +1(r标志)= 60字节UTF-8

花了我一段时间才得出一个sed答案,该答案不使用注释部分来使代码成为回文。取而代之的是,我使用的c命令将以相反的顺序打印代码的前半部分,只有在我确保未达到此指令的情况下。

:;s:^(.)(.*)\1$:\2:;t;/../c1
d
1c/../;t;:2\:$1\)*.().(^:s;:

1如果输入的字符串不是回文(如果认为有错误),则将打印脚本。如果字符串是回文,则不会给出任何输出(将其视为成功退出)。

运行示例:在线尝试!

me@LCARS:/PPCG$ sed -rf palindrome_source.sed <<< "level"
me@LCARS:/PPCG$ sed -rf palindrome_source.sed <<< "game"
1

说明:

:                              # start loop
s:^(.)(.*)\1$:\2:              # delete first and last char, if they are the same
t                              # repeat if 's' was successful
/../c1                         # if at least 2 chars are left, print 1. 'c' reads
                               #till EOL, so next command must be on a new line.
d                              # delete pattern space. This line must be a
                               #palindrome itself, and must end the script.
1c/../;t;:2\:$1\)*.().(^:s;:   # (skipped) print first half of code in reverse
                               #order. Everything after 'c' is treated as string.

1
TIO现在支持sed。-r不起作用,但是您可以将整个内容包装在BASH中。在线尝试!
莱利

@Riley很好,在TIO上使用了页眉和页脚。先前的解决方法是使用-e将代码移至参数列表,但是您的方法要好得多。我一直在等待解决该问题,但是我不需要这样做。
seshoumara

7

爱丽丝,19字节

/@.nzRoi\
\ioRzn.@/

在线尝试!

打印Jabberwocky回文,非回文则不打印。适用于任意UTF-8输入。

说明

由于这是字符串处理任务,因此Alice必须以Ordinal模式运行才能解决该问题。这又意味着指令指针必须沿对角线移动,因此我们至少需要两行,以便IP可以上下反弹。这样的程序中的换行符为放置回文的中间字符提供了一个很好的位置。这意味着第二行需要与第一行相反。但是,由于我们仅在每行上执行所有其他字符,因此,如果我们确保行长为奇数,则代码的反向将恰好适合其自身的间隙。唯一根本不使用的字符是反斜杠,但是由于它是任意的,因此我选择了它以使程序看起来不错且对称。

所以无论如何,实际的相关代码是这样的:

/ . z o
 i R n @

从左到右以锯齿形执行。

/   Reflect the IP southeast, enter Ordinal mode.
i   Read all input as a single string.
.   Duplicate the input.
R   Reverse the copy.
z   Pop the reverse Y and the original X. If X contains Y, drop everything
    up to its first occurrence. Since we know that X and Y are the same length,
    Y can only be contained in X if X=Y, which means that X is a palindrome.
    So this will result in an empty string for palindromes and in the non-empty
    input for non-palindromes.
n   Logical NOT. Replaces non-empty strings with "", and empty strings with
    "Jabberwocky", the "default" truthy string.
o   Output the result.
@   Terminate the program.

6

Haskell,34个字节

f=(==)=<<reverse--esrever<<=)==(=f

在线尝试!f "some string",返回True或致电False

=<<函数上的运算符的工作方式类似于f=<<g = \s -> f (g s) s,因此代码等同于f s=s==reverse s,正如我刚刚注意到的那样,这将导致相同的字节数。


没有注释的版本:(49个字节)

e x y=x/=y
p=e=<<reverse
esrever<<=e=p
y=/x=y x e

在线尝试!

致电p "some string"False如果给定的字符串回文,并且不是回文,True则输出。

说明:

我从注释版本开始并用新行替换了注释,从而找到了这个无注释回文。

p=(==)=<<reverse
esrever<<=)==(=p

第二行失败,因为括号不匹配,因此我们需要删除它们。如果我们有一个e检查相等性的函数,那么

p=e=<<reverse
esrever<<=e=p

与所述第二线限定缀操作者将两个编译<<=采用两个参数esrevere并返回功能p

要定义e为相等函数,通常可以编写e=(==),但)==(=e不会再次编译。相反,我们可以明确的两个参数,并将其传递到==e x y=x==y。现在,反向代码可以y==x=y x e编译但重新定义==运算符,这将导致定义e x y=x==y失败。但是,如果切换到不等式运算符/=,则相反的定义将变为y=/x=y x e并定义一个=/不会干扰原始/=运算符的运算符。


5

OIL,178字节

读取输入,将其爆炸,将其长度(通过递增和递减)缓慢添加到地址,以在字符串之后添加到该地址,跳转到代码的不同部分(在中间),反转带方向,将字符串内插再次检查是否与原始字符串相同。TL; DR:和往常一样,这很痛苦。

40如果字符串不是回文,0则输出。

5
0
12
0
40
1
40
2
1
40
34
10
2
3
22
16
9
2
8
35
6
11
6
37

3
4
4
27
26
0
1
10
1

40
13
2
31
04

1
01
1
0
62
72
4
4
3

73
6
11
6
53
8
2
9
61
22
3
2
01
43
04
1
2
04
1
04
0
21
0
5

2
语言整洁!:)
DLosc '17

5

Javascript,64个字节

f=s=>s==[...s].reverse().join``//``nioj.)(esrever.]s...[==s>=s=f

f带字符串的调用函数

f("abba") // returns true
f("abab") // returns false

您的源代码不是回文!
seshoumara

@seshoumara更新了代码
Prasanth Bendra,2017年

现在很好。如果字符串不是回文,则可能要提及返回值,仅出于完成目的。
seshoumara

@apsillers谢谢你我编辑了答案。
Prasanth Bendra'2

没有函数f,您的代码未将箭头函数分配给变量,因此无法调用
spex

5

Japt7 2字节

êê

运行

旧解决方案:

U¥UwU¥U

在线尝试!

说明

U¥UwU¥U
U¥        U is the input, ¥ is a shortcut for == 
  Uw      w is a reverse function.
    U¥U   This calculates U == U (always true), but the result is ignored
          because w does not look at its arguments.

除非达到封闭的括号(或空格),否则Japt不会转义函数。

这可以被改写:U¥Uw(U¥U)→交通U¥Uw→交通U==Uw。在Japt中,自动插入在函数开头和结尾处省略的括号。


这一切都是有道理的,除非w是一个不带参数的函数,它如何应用于U?是这样的U.reverse()吗?
DLosc '17

@DLosc正确。反转U的方式与相同U.reverse()
奥利弗·

4

Bash + Unix实用程序,49字节

[ "$1" = "`rev<<<$1`" ] # ] "`1$<<<ver`" = "1$" [

输入作为参数传递。

输出以结果代码返回-回文为0,非回文为1。

也许有人可以做得更好,而不仅仅是依靠注释使代码本身回文。

在线尝试!


[[ $1 = `rev<<<$1` ]]更短。(Bash [[语法,无需引用)
Arthur2e5

2
@ Arthur2e5我尝试了您的建议,但我认为rev<<<$1即使在[[...]]解决方案中也需要引号。使用输入字符串'[$]]$['(这是回文)对其进行测试。加上这些引号使它起作用,您的解决方案与我的解决方案长度相同。
米切尔·斯佩克托

很棒!我忘记了==in 的RHS [[将被解释为类似case模式。
Arthur2e5

我仍然认为@ Arthur2e5可能有一些聪明的方法可以缩短这个时间。
米切尔·史佩克特

如果输入中包含换行符,这仍然有效吗?我认为您需要的是rev | tac而不仅仅是rev。
b_jonas

4

> <>,​​11个字节

{=?!;
;!?={

在这里尝试!

在有效回文中返回“ \ n闻起来有鱼腥味...”,在无效回文中不输出。将回文放在堆栈上。


要求输入已经在堆栈上,这使它成为一个片段。这个挑战需要程序或功能,而不是代码片段。
pppery

4

爪哇- 171个 169 160字节

int q(String s){return s.equals(new StringBuffer(s).reverse().toString())?1:2;}//};2:1?))(gnirtSot.)(esrever.)s(reffuBgnirtS wen(slauqe.s nruter{)s gnirtS(q tni

最后的评论是使它成为回文。P(alindrome)当输入是回文,N(ot)而不是时返回。

非高尔夫版本:

int q(String s) {
    return s.equals(new StringBuffer(s).reverse().toString()) ? 'P' : 'N';
}//};'N':'P'?))(gnirtSot.)(esrever.)s(reffuBgnirtS wen(slauqe.s nruter{)s gnirtS(q tni

@DLosc节省了2个字节

感谢@OlivierGrégoire指出了不正确的字节数!现在固定


我相信您可以通过返回ints而不是chars 来节省一些字节。
DLosc

我不知道该怎么做检查您的字节数,但你有160个字节,而不是161
奥利维尔·格雷瓜尔

您可以通过为80 'P'和78 返回80来保存2个字节,'N'或者使用不同的字符来保存更多的字节。
Selim

1
您可以这样做new StringBuffer(s).reverse()+""来节省更多字节,而不是new StringBuffer(s).reverse().toString()
Selim

1
有什么原因要返回int而不是bool
CodesInChaos

4

Java 8,92 90字节

这是一个注释版本。如果字符串包含反向字符,则为回文(true),否则为(false)。

s->s.contains(new StringBuffer(s).reverse())//))(esrever.)s(reffuBgnirtS wen(sniatnoc.s>-s

在线尝试!

更新资料

  • -2 [18-04-05]切换到包含。感谢@Kevin Cruijssen
  • -2 [17-02-20]已删除;
  • -16 [17-02-22]自动转换

此代码不是lambda表达式。
雅各布

@Jakob我以为是。如果要使用lambda,则可能需要前导和尾随的换行符。(我添加了一个tio链接)
NonlinearFruit

是的,我的抱怨是,该行注释使提交的内容不仅仅是lambda表达式,因此不能作为lambda解决方案使用。现在不用担心。我可能最终会发表一个元文章来收集共识。
雅各布

@Jakob Lambda解决方案有时可能会有多余的代码,这就是为什么我认为它是有效的。但是,如果您不被出售,那么发布元信息也不会受到伤害。
NonlinearFruit17年

1
我知道已经有一段时间了,但是您可以通过将其更改为来打2个字节s->s.contains(new StringBuffer(s).reverse())//))(esrever.)s(reffuBgnirtS wen(sniatnoc.s>-s在线尝试90个字节
凯文·克鲁伊森

3

实际上,5个字节

;R=R;

在线尝试!

正确输出为[1]\n[1],而错误输出为[]\n[](在两个输出中均\n表示原义换行符)。

说明:

;R=R;
;R=    duplicate input, reverse one copy, test equality (the main palindrome-testing part)
   R   range(1, x+1) - if palindrome, this pushes [1], else it pushes []
    ;  duplicate

你为什么不只是做这个
Leaky Nun

1
@LeakyNun它必须是回
文集

3

C ++,154字节

int m(){std::string g,p="";g=p;std::reverse(p.begin(),p.end());return g==p;}//};p==g nruter;))(dne.p,)(nigeb.p(esrever::dts;p=g;""=p,g gnirts::dts{)(m tni

我不得不说,相反的声明代价很高,但是我无法想象要改变这一点。能够剪切出std ::符号可以为我节省大约10个字符,但是“使用命名空间std;” 还有很多。

我想C ++并不是为了简洁。


3

Prolog,44个字节

p-->[]|[_]|[E],p,[E].%.]E[,p,]E[|]_[|][>--p

这使用定句语法。它实际上是一个完全没有上下文的语法:

p -->
      []            % the empty string
   |                % or
      [_]           % a one character string
   |                % or
      [E],          % one character, followed by
      p,            % a palindrome, followed by
      [E].          % that same character

用法:

?- phrase(p,"reliefpfeiler").
true 

?- phrase(p,"re").
false.

2

CJam,13个字节

l_W%=e#e=%W_l

说明:

l_W%=e#e=%W_l
l_            e#Read input twice
  W%          e#Reverse one input
    =         e#Test for equality
     e#e=%W_l e#Comment to be a palindrome

例:

> l_W%=e#e=%W_l
l_W%=e#e=%W_l
1

> l_W%=e#e=%W_l
Hi
0

> l_W%=e#e=%W_l
hh
1

试试这个:l_W%#e#%W_l
aditsu

2

J,15个字节,15个字符

-:|.NB. .BN.|:-

如果回文,则返回1,否则返回0。

输出:

   f '())('
1
   f 'nope'
0

说明:

-:    NB. "Match" verb, checks for equality
|.    NB. Reverses the string
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.