118
\$\begingroup\$

There have been a couple of previous attempts to ask this question, but neither conforms to modern standards on this site. Per discussion on Meta, I'm reposting it in a way that allows for fair competition under our modern rulesets.

Background

A is a string that "reads the same forwards and backwards", i.e. the reverse of the string is the same as the string itself. We're not talking about "convenient palindromes" here, but a strict character-by-character reversal; for example, ()() is not a palindrome, but ())( is.

The task

Write a program or function that takes a string S (or the appropriate equivalent in your language) as input, and has one output Q (of a type of your choice). You can use any reasonable means to take the input and provide the output.

  • When the input S is a palindrome, the output Q should have a value A (that is the same for any palindromic S).
  • When the input S is not a palindrome, the output Q should have a value B (that is the same for any non-palindromic S).
  • A and B must be distinct from each other.

Or in other words: map all palindromes to one value, and all non-palindromes to another.

Additionally, the program or function you write must be a palindrome itself (i.e. its source code must be palindromic), making this a challenge.

Clarifications

  • Although true and false are obvious choices for A and B, you can use any two distinct values for your "is a palindrome" and "isn't a palindrome" outputs, which need not be booleans.
  • We're defining string reversal at the character level here; éé is palindromic regardless of whether the program is encoded in UTF-8 or Latin-1, even though it's not a palindromic sequence of octets after UTF-8 encoding.
  • However, even if your program contains non-ASCII characters, it only needs to work for ASCII input. Specifically, the input S will only contain printable ASCII characters (including space, but not including newline). Among other things, this means that if you treat the input as a sequence of bytes rather than a sequence of characters, your program will still likely comply with the specification (unless your language's I/O encoding is very weird). As such, the definition of a palindrome in the previous bullet only really matters when checking that the program has a correct form.
  • Hiding half the program in a comment or string literal, while being uncreative, is legal; you're being scored on length, not creativity, so feel free to use "boring" methods to ensure your program is a palindrome. Of course, because you're being scored on length, parts of your program that don't do anything are going to worsen your score, so being able to use both halves of your program is likely going to be helpful if you can manage it.
  • Because the victory criterion is measured in bytes, you'll need to specify the encoding in which your program is written to be able to score it (although in many cases it will be obvious which encoding you're using).

Victory criterion

Even though the program needs to be a palindrome at the character level, we're using bytes to see who wins. Specifically, the shorter your program is, measured in bytes, the better; this is a challenge. In order to allow submissions (especially submissions in the same language) to be compared, place a byte count for your program in the header of your submission (plus a character count, if it differs from the number of bytes).

\$\endgroup\$
12
  • 13
    \$\begingroup\$ Would someone please explain why would ()() not be a palindrome?? \$\endgroup\$ Commented Feb 20, 2017 at 6:38
  • 67
    \$\begingroup\$ @EmilioMBumachar Try replacing ( with a and ) with b. Is abab a palindrome? No, it would have to be abba. Then ()() isn't a palindrome either; it would have to be ())(. \$\endgroup\$
    – DLosc
    Commented Feb 20, 2017 at 6:40
  • 7
    \$\begingroup\$ Those solutions entirely using comments to make the program palindromic looks like a loophole to me :( \$\endgroup\$
    – kennytm
    Commented Feb 20, 2017 at 8:26
  • 17
    \$\begingroup\$ @kennytm Disallowing them would be worse, because there's no satisfactory way to do that objectively in a language-agnostic way. (What's a comment? What about putting the unused half in a string literal that is discarded? What about 2D languages where you can have perfectly executable code that is simply never reached?) \$\endgroup\$ Commented Feb 20, 2017 at 9:08
  • 15
    \$\begingroup\$ ()() is not a palindrome, but ())( is. Congratulations, you made it onto reddit! \$\endgroup\$ Commented Feb 25, 2017 at 6:31

76 Answers 76

139
\$\begingroup\$

Brachylog (2), 3 bytes in Brachylog's codepage

I↔I

Try it online!

This is a full program that takes input via standard input (using Brachylog's syntax for constants, i.e. strings are enclosed in double quotes), and outputs via standard output. The outputs are true. for a palindromic input, and false. for a non-palindromic input.

Not only is this program palindromic, it also has left/right (and probably in some fonts up/down) mirror symmetry.

Explanation

In Brachylog, capital letters mark points in the program which have identical values; this is used almost like an electrical circuit to carry information from one part of the program to another. One consequence of this is that if you enclose a command between an identical pair of capital letters, you're effectively asserting that the command's input and output are the same. Brachylog implicitly takes input, so in this case we're also asserting that the input to the command is the same as the input to the program. In this program, we're using the command , which reverses things (in this case, strings); so the program effectively asserts that the input is the same forwards and backwards.

A full program (as opposed to a function) in Brachylog returns a boolean, false. if there's no way to make all the assertions in the program correct at once, or true. if the assertions in the program are all compatible with each other. We only have one assertion here – that reversing the input does not change it – so the program acts as a palindrome checker.

\$\endgroup\$
7
  • 51
    \$\begingroup\$ And 180 degree rotational symmetry, It's beautiful. \$\endgroup\$
    – ATaco
    Commented Feb 20, 2017 at 2:07
  • 7
    \$\begingroup\$ ... and symmetry along vertical and horizontal axes :-) \$\endgroup\$
    – Luis Mendo
    Commented Feb 20, 2017 at 9:56
  • 13
    \$\begingroup\$ @SteakOverflow Brachylog uses a custom code-page, so those characters are not encoded in UTF-8 \$\endgroup\$
    – DJMcMayhem
    Commented Feb 20, 2017 at 21:46
  • 4
    \$\begingroup\$ I joined this community just to up vote this program. Wow. \$\endgroup\$ Commented Feb 21, 2017 at 12:25
  • 4
    \$\begingroup\$ @ATaco The combination of left/right and up/down symmetries imply 180 degree rotational symmetry. ;) \$\endgroup\$ Commented Feb 23, 2017 at 21:52
57
\$\begingroup\$

Pyth, 3 bytes

_I_

Returns True or False.

Try it online!

How it works

  _  Reverse the input.
_I   Invariant-reverse; test if the reversed input is equal to its reverse.
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Why do you need the final _? \$\endgroup\$
    – busukxuan
    Commented Feb 20, 2017 at 7:30
  • 35
    \$\begingroup\$ @busukxuan From the question, "Additionally, the program or function you write must be a palindrome itself" \$\endgroup\$
    – isaacg
    Commented Feb 20, 2017 at 7:41
  • 1
    \$\begingroup\$ Why so many upvotes...This answer doesn't seem that hard to come up with...? \$\endgroup\$ Commented Feb 26, 2017 at 16:08
  • 2
    \$\begingroup\$ I guess so. Still it seems kind of unfair. On some questions, one must put a lot of hard work to answer, and others are much easier. Still the payout is the same. Btw I've also upvoted :P \$\endgroup\$ Commented Feb 26, 2017 at 16:13
  • 5
    \$\begingroup\$ @ghosts_in_the_code Only one of my answers with 100+ was actually challenging to write, yet there are answers I spent days on that only got a handful of upvotes. In the end, it all evens out... \$\endgroup\$
    – Dennis
    Commented Feb 26, 2017 at 16:20
50
\$\begingroup\$

Python, 39 bytes

lambda s:s[::-1]==s#s==]1-::[s:s adbmal

Try it online!

Boring, but if there is shorter in Python it will be impressive.

\$\endgroup\$
1
  • \$\begingroup\$ Wow, thos (, ) were some good (and confusing) inputs :) \$\endgroup\$
    – ABcDexter
    Commented Feb 21, 2017 at 5:39
35
\$\begingroup\$

Jelly, 5 bytes

ḂŒ
ŒḂ

Returns 1 or 0. The first line is an unexecuted helper link, the second line calls the palindrome test.

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ wow, recent addition. \$\endgroup\$ Commented Feb 20, 2017 at 2:21
  • 7
    \$\begingroup\$ Yep, only 18 hours old. \$\endgroup\$
    – Dennis
    Commented Feb 20, 2017 at 2:22
  • \$\begingroup\$ you didn't specify the encoding. I'm guessing UTF-8? \$\endgroup\$ Commented Feb 24, 2017 at 17:16
  • 1
    \$\begingroup\$ @BrianMinton No, this would be 11 bytes in UTF-8. Jelly uses this code page. \$\endgroup\$
    – Dennis
    Commented Feb 24, 2017 at 17:28
  • \$\begingroup\$ @Dennis, thanks for the info. \$\endgroup\$ Commented Feb 24, 2017 at 17:34
25
\$\begingroup\$

Jelly, 5 bytes

⁼ṚaṚ⁼

Try it online!

Equals reverse and reverse equals.

Or the more efficient yet less aesthetically pleasing:

⁼Ṛ
Ṛ⁼

or

Ṛ⁼
⁼Ṛ
\$\endgroup\$
0
24
\$\begingroup\$

Haskell, 87 85 44 34 bytes

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

Explanation: ((->) a) is an instance of Applicative (thanks @faubiguy), with <*> defined as

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

So by substituting in the arguments one can see why this works.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Can you explain the code? \$\endgroup\$
    – bli
    Commented Feb 20, 2017 at 6:48
  • 1
    \$\begingroup\$ @bli everything after the -- is a comment. \$\endgroup\$
    – user36219
    Commented Feb 20, 2017 at 9:05
  • 4
    \$\begingroup\$ @theonlygusti Haskell is sufficiently alien that that only half helps. \$\endgroup\$
    – Yakk
    Commented Feb 21, 2017 at 18:41
  • \$\begingroup\$ @Yakk It's some sort of combination of the (==), reverse, and id functions (id is the identity function). \$\endgroup\$
    – tbodt
    Commented Feb 21, 2017 at 22:08
  • 1
    \$\begingroup\$ You can save 10 bytes by using <*> instead of <$> and removing the <*>id \$\endgroup\$
    – faubi
    Commented Feb 22, 2017 at 2:36
23
\$\begingroup\$

05AB1E, 3 bytes

Code:

ÂQÂ

Explanation:

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

Uses the CP-1252 encoding. Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Why not just ÂQ \$\endgroup\$
    – Neil A.
    Commented May 22, 2017 at 0:20
  • 4
    \$\begingroup\$ @NeilA. The code itself needs to be a palindrome as well. \$\endgroup\$
    – Adnan
    Commented May 22, 2017 at 4:22
23
\$\begingroup\$

Mathematica, 23 bytes

QemordnilaP;PalindromeQ

Not very interesting, but for the sake of completeness...

The above is a CompoundExpression which evaluates to PalindromeQ, a built-in that solves the challenge. QemordnilaP is simply an undefined identifier, which is ignored because of the ;.

\$\endgroup\$
19
\$\begingroup\$

PHP, 55 bytes

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

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Sneaky solution. \$\endgroup\$
    – Martijn
    Commented Feb 21, 2017 at 15:02
17
\$\begingroup\$

MATL, 7 bytes

tPX=XPt

Try it online!

Returns [1; 1] for palindromic input and [0; 0] otherwise.

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
\$\endgroup\$
16
\$\begingroup\$

Pip, 12 11 bytes

Now comment-free!

x:RVaQaVR:x

Takes input as a command-line argument; outputs 1 for palindrome, 0 for non-palindrome. Try it online!

The core of what we want to do is RVaQa: reverse(a) string-equals a. The code x:RVaQa calculates this result and assigns it to x. Then VR:x assigns the value of x to the variable VR. Since this assignment is the last statement in the program, its value is also autoprinted. Voila!

For a previous interesting version using some undefined behavior, see the revision history.

\$\endgroup\$
13
\$\begingroup\$

Perl 6, 25 bytes/chars utf8

{.flip eq$_}#}_$qe pilf.{

Try it

\$\endgroup\$
10
\$\begingroup\$

GNU sed, 64 59 + 1(r flag) = 60 bytes UTF-8

Took me a while to come up with a sed answer that is not using a comment section to make the code a palindrome. Instead, I use the c command that would print the first half of the code in reverse order, only I make sure this instruction is not reached.

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

The script prints 1 if the input string is not a palindrome (think of it as giving an error). If the string is a palindrome, then no output is given (think of it as exiting successfully).

Run examples: or Try it online!

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

Explanation:

:                              # 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.
\$\endgroup\$
3
  • 1
    \$\begingroup\$ TIO has support for sed now. -r doesn't work, but you can just wrap the whole thing in BASH. Try it Online! \$\endgroup\$
    – Riley
    Commented Feb 20, 2017 at 15:56
  • \$\begingroup\$ @Riley Nice usage of header and footer on TIO, thanks. The previous workaround was to move the code to the argument list with -e, but your way is much nicer. I was waiting for that to be fixed, but this way I don't need to. \$\endgroup\$
    – seshoumara
    Commented Feb 20, 2017 at 16:17
  • \$\begingroup\$ Nice answer. I think you can -2 changing /../ to /./: Try it online! \$\endgroup\$
    – Jonah
    Commented Aug 19, 2022 at 3:17
10
\$\begingroup\$

R, 111 103 bytes

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

Not the most original answer. # is the comment character in R

Ungolfed:

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

The character string from scan is converted into raw bytes thanks to the charToRaw function. These raw bytes are compared one-by-one to their counterparts from the rev() function, which reverses the order of its argument. The output of this part is a vector of TRUE and/or FALSE.
The all function then outputs TRUE if all those elements are TRUE

Here, "\n" in the scan function is necessary for inputs with more than one word.

Previous answer (byte-wise), 81 bytes

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

with - 24 bytes thanks to @rturnbull.

\$\endgroup\$
11
  • \$\begingroup\$ You can save a good few bytes by doing the charToRaw conversion before assignment to s, and changing how you set the sep argument to scan: all((s<-charToRaw(scan(,"",,,"\n")))==rev(s))#))s(ver==)))"n\",,,"",(nacs(waRoTrahc-<s((lla \$\endgroup\$
    – rturnbull
    Commented Feb 21, 2017 at 9:41
  • \$\begingroup\$ (Also, this approach doesn't work for e.g. input éé under a UTF-8 encoding, but I don't think that breaks the rules of the challenge.) \$\endgroup\$
    – rturnbull
    Commented Feb 21, 2017 at 9:45
  • \$\begingroup\$ @rturnbull : thanks for the inputs ! I indeed tested éé with a latin1 encoding. \$\endgroup\$
    – Rudier
    Commented Feb 21, 2017 at 10:32
  • \$\begingroup\$ Since the test must be done character-wise, I think the current programm breaks the rules. \$\endgroup\$
    – Rudier
    Commented Feb 21, 2017 at 10:42
  • \$\begingroup\$ I'm not so sure the previous version does break the rules. OP states: "Among other things, this means that if you treat the input as a sequence of bytes rather than a sequence of characters, your program will still likely comply with the specification (unless your language's I/O encoding is very weird)." \$\endgroup\$
    – rturnbull
    Commented Feb 21, 2017 at 11:39
9
\$\begingroup\$

RProgN, 11 bytes

~]S.E E.S]~

The first half of this does all the heavy lifting, and by a convenience of RProgN, the second half is a 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.

Try it online!

\$\endgroup\$
9
\$\begingroup\$

Alice, 19 bytes

/@.nzRoi\
\ioRzn.@/

Try it online!

Prints Jabberwocky for palindromes and nothing for non-palindromes. Works for arbitrary UTF-8 input.

Explanation

Since this is a string processing task, Alice will have to operate in Ordinal mode to solve it. That in turn means that the instruction pointer has to move diagonally, and therefore we need at least two lines so that the IP can bounce up and down. The linefeed in such a program makes for a good position to place the middle character of the palindrome. That means the second line needs to be the reverse of the first. But since we're only executing every other character on each line, if we make sure that the line-length is odd, the reverse of the code will neatly fit into its own gaps. The only character that isn't used at all is the backslash, but since it was arbitrary I chose it to make the program look nice and symmetric.

So anyway, the actual relevant code is this:

/ . z o
 i R n @

Which is executed in a zigzag from left to right.

/   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.
\$\endgroup\$
8
\$\begingroup\$

Retina, 53 bytes

Byte count assumes ISO 8859-1 encoding.

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

Try it online!

I'm pretty sure this isn't optimal yet (the » line seems particularly wasteful, and I have a 45-byte solution that is palindromic except for one character), but I guess it's a start.

\$\endgroup\$
7
\$\begingroup\$

Haskell, 34 bytes

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

Try it online! Call with f "some string", returns True or False.

The =<< operator on functions works like f=<<g = \s -> f (g s) s, so the code is equivalent to f s=s==reverse s, which, as I just noticed, would result in the same byte count.


Version without comment: (49 bytes)

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

Try it online!

Call with p "some string". This outputs False if the given string is a palindrome, and True if it's not a palindrome.

Explanation:

I found this comment free palindrome by starting with the comment version and replacing the the comment with a new line:

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

The second line fails because the parenthesis do not match, so we need to get rid of them. If we had a function e which checks for equality, then

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

will both compile with the second line defining an infix-operator <<= which takes two arguments esrever and e and returns the function p.

To define e as the equality function one would normally write e=(==), but )==(=e will again not compile. Instead we could explicitly take two arguments and pass them to ==: e x y=x==y. Now the reversed code y==x=y x e compiles but redefines the == operator, which causes the definition e x y=x==y to fail. However if we switch to the inequality operator /=, the reversed definition becomes y=/x=y x e and defines a =/ operator which does not interferes with the original /= operator.

\$\endgroup\$
6
\$\begingroup\$

OIL, 178 bytes

Reads an input, explodes it, slowly adds its length (through incrementing and decrementing) to the address to know to the address after the string, jumps to a different part of code (in the middle), reverses the band direction, implodes the string again, and checks whether it's the same as the original string. TL;DR: It's a pain, as usual.

Outputs 40 if the string isn't a palindrome, 0 if it is.

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
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Neat language! :) \$\endgroup\$
    – DLosc
    Commented Feb 21, 2017 at 3:49
5
\$\begingroup\$

Java 8, 92 90 bytes

This is a comment version. If a string contains its reverse, then it is a palindrome (true) otherwise it is not (false).

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

Try it online!

Update

  • -2 [18-04-05] Switched to contains. Thanks to @Kevin Cruijssen!
  • -2 [17-02-20] Removed ;'s
  • -16 [17-02-22] Auto convert
\$\endgroup\$
6
  • \$\begingroup\$ This code is not a lambda expression. \$\endgroup\$
    – Jakob
    Commented Aug 30, 2017 at 0:21
  • \$\begingroup\$ @Jakob I thought it was. If you were to use the lambda, you would probably want a leading and trailing newline. (I added a tio link) \$\endgroup\$ Commented Sep 5, 2017 at 21:10
  • \$\begingroup\$ Yeah, my complaint was that the line comment makes the submission more than just a lambda expression, and thus not valid as a lambda solution. Don't worry about it for now; I'll probably eventually make a meta post to gather consensus. \$\endgroup\$
    – Jakob
    Commented Sep 6, 2017 at 1:11
  • \$\begingroup\$ @Jakob Lambda solutions can sometimes have extraneous code, which is why I think it is valid. But if you aren't sold, a meta post wouldn't hurt. \$\endgroup\$ Commented Sep 6, 2017 at 1:46
  • 2
    \$\begingroup\$ I know it's been a while, but you can golf 2 bytes by changing it to s->s.contains(new StringBuffer(s).reverse())//))(esrever.)s(reffuBgnirtS wen(sniatnoc.s>-s. Try it online 90 bytes. \$\endgroup\$ Commented Apr 3, 2018 at 8:14
5
\$\begingroup\$

Japt, 7 2 bytes

êê

Run it

Old solution:

U¥UwU¥U

Try it online!

Explanation

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 doesn't escape functions unless a closing parenthesis (or space) is reached.

This can be re-written: U¥Uw(U¥U)U¥UwU==Uw. In Japt, the parenthesis left out at the begining and end of a function is auto-inserted.

\$\endgroup\$
2
  • \$\begingroup\$ It all makes sense, except if w is a function that takes no arguments, how does it apply to U? Is it something like U.reverse()? \$\endgroup\$
    – DLosc
    Commented Feb 21, 2017 at 5:32
  • \$\begingroup\$ @DLosc Correct. It reverses U in the same way as U.reverse(). \$\endgroup\$
    – Oliver
    Commented Feb 21, 2017 at 5:45
5
\$\begingroup\$

Dyalog APL, 6 bytes

⌽≡⊢⊢≡⌽

Try it online!

\$\endgroup\$
1
  • 5
    \$\begingroup\$ This is the "correct" answer (as it works on all arrays), but for this particular challenge specification (argument is always a string), ⌷≡⌽⌽≡⌷ or +≡⌽⌽≡+ works too while also being visually palindromic. \$\endgroup\$
    – Adám
    Commented Feb 6, 2019 at 21:47
5
\$\begingroup\$

J, 9 bytes

[:-.|.-:[

Attempt This Online!

Lolwut. I was fiddling with various arrangements and adverb trains until I realized [: in trains is a thing, and -. (boolean negation) is perfectly OK thanks to the permissive output format. Returns 0 if the input is palindrome and 1 otherwise.

[: -. (|. -: [)
       |. -: [   Reverse matches identity (classic palindrome check)
[: -.            Boolean negation on the result

J, 11 bytes

]&.|:-:|.&]

Attempt This Online!

Wins against the existing comment abuse solution. Uses a similar trick to this answer to "I reverse the source, you reverse the input!".

Many of J's built-ins have inflections . and :, which are always treated as the suffix of a larger token. So the function above tokenizes as ] &. |: -: |. & ]. And &. and & are conjunctions, which consume two things on both sides to form a single verb. Finally, verb1 verb2 verb3 is a verb train; when given an argument y, it evaluates to (verb1 y) verb2 (verb3 y).

] &. |: -: |. & ]
] &. |:             Identity under transpose: returns the input unchanged
           |. & ]   Reverse over identity: returns the input reversed
        -:          Match: tests if the two sides are identical
\$\endgroup\$
1
  • 1
    \$\begingroup\$ This is beautiful \$\endgroup\$
    – Jonah
    Commented Aug 19, 2022 at 2:58
4
\$\begingroup\$

Bash + Unix utilities, 49 bytes

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

Input is passed as an argument.

Output is returned in the result code -- 0 for a palindrome, 1 for a non-palindrome.

Maybe someone can do better and not just rely on a comment to make the code itself palindromic.

Try it online!

\$\endgroup\$
7
  • \$\begingroup\$ [[ $1 = `rev<<<$1` ]] is shorter. (Bash [[ syntax, no quote needed) \$\endgroup\$ Commented Feb 24, 2017 at 2:03
  • 2
    \$\begingroup\$ @Arthur2e5 I tried out your suggestion, but I think the quotes around rev<<<$1 are needed even in the [[...]] solution. Test it with input string '[$]]$[' (which is a palindrome). With those quotes added in to make it work, your solution is the same length as my solution. \$\endgroup\$ Commented Feb 24, 2017 at 2:57
  • \$\begingroup\$ Great catch! I forgot that the RHS of == in [[ would be interpreted as a case-like pattern. \$\endgroup\$ Commented Feb 24, 2017 at 4:06
  • \$\begingroup\$ @Arthur2e5 I still think there's probably some clever way to make this shorter. \$\endgroup\$ Commented Feb 24, 2017 at 5:03
  • \$\begingroup\$ Will this still work if there are newlines in the input? I think you need rev|tac instead of just rev. \$\endgroup\$
    – b_jonas
    Commented Jun 13, 2017 at 20:00
4
\$\begingroup\$

Java - 171 169 160 bytes

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

The comment at the end is to make it a palindrome. Returns P(alindrome) when the input is palindrome and N(ot) when not.

Ungolfed version:

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

2 bytes saved thanks to @DLosc

Thanks to @Olivier Grégoire for pointing out the incorrect amount of bytes! Fixed now

\$\endgroup\$
6
  • \$\begingroup\$ I believe you can save some bytes by returning ints instead of chars. \$\endgroup\$
    – DLosc
    Commented Feb 21, 2017 at 3:53
  • \$\begingroup\$ I don't know how do check your byte count, but you have 160 bytes, not 161. \$\endgroup\$ Commented Feb 23, 2017 at 8:37
  • \$\begingroup\$ You can save 2 bytes by returning 80 for 'P' and 78 for 'N' or use different chars to save even more bytes. \$\endgroup\$
    – Selim
    Commented Feb 23, 2017 at 16:57
  • 1
    \$\begingroup\$ You can save even more bytes by doing new StringBuffer(s).reverse()+"" instead of new StringBuffer(s).reverse().toString() \$\endgroup\$
    – Selim
    Commented Feb 23, 2017 at 17:00
  • 1
    \$\begingroup\$ any reason you're returning an int instead of bool? \$\endgroup\$ Commented Feb 23, 2017 at 18:02
4
\$\begingroup\$

Javascript, 64 bytes

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

Call function f with string

f("abba") // returns true
f("abab") // returns false
\$\endgroup\$
9
  • \$\begingroup\$ Your source code is not a palindrome! \$\endgroup\$
    – seshoumara
    Commented Feb 20, 2017 at 12:39
  • \$\begingroup\$ @seshoumara Updated the code \$\endgroup\$ Commented Feb 20, 2017 at 12:53
  • \$\begingroup\$ Now it's fine. Maybe mention the return value if the string is not a palindrome, just for completion sake. \$\endgroup\$
    – seshoumara
    Commented Feb 20, 2017 at 13:12
  • \$\begingroup\$ @apsillers thank you I edited the answer. \$\endgroup\$ Commented Feb 23, 2017 at 9:32
  • \$\begingroup\$ There is no function f, your code doesn't assign your arrow function to a variable so it can't be called \$\endgroup\$
    – spex
    Commented Feb 26, 2017 at 21:24
4
\$\begingroup\$

Jelly, 4 bytes

ḂŒŒḂ

Try it online!

Although this loses to the modern UƑU, I figured it may be of historical interest to note that Dennis's solution could have been only 4 bytes. Thanks to a quirk of the parser, any undefined characters--such as Œ outside a valid digraph--act equivalent to two newlines; as such, removing the newline yields a functionally identical solution (if not particularly forward-compatible, should ŒŒ ever hypothetically be added).

\$\endgroup\$
3
\$\begingroup\$

Actually, 5 bytes

;R=R;

Try it online!

The truthy output is [1]\n[1], and the falsey output is []\n[] (in both outputs, \n represents a literal newline).

Explanation:

;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
\$\endgroup\$
2
  • \$\begingroup\$ Why don't you just do this? \$\endgroup\$
    – Leaky Nun
    Commented Apr 24, 2017 at 11:18
  • 1
    \$\begingroup\$ @LeakyNun it has to be a palindrome \$\endgroup\$ Commented Apr 24, 2017 at 20:23
3
\$\begingroup\$

C++, 154 Bytes

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

I have to say, the reverse statement was costly, but I can't imagine much I can do to change that. Being able to cut out the std:: symbols would save me around 10 characters, but "using namespace std;" is quite a few more.

I suppose C++ wasn't really meant for brevity.

\$\endgroup\$
0
3
\$\begingroup\$

Prolog, 44 bytes

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

This uses definite clause grammars. It is actually a full context free grammar:

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

Usage:

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

?- phrase(p,"re").
false.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.