Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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).

share|improve this question
3  
Would someone please explain why would ()() not be a palindrome?? – Emilio M Bumachar yesterday
12  
@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 ())(. – DLosc yesterday
4  
Those solutions entirely using comments to make the program palindromic looks like a loophole to me :( – kennytm yesterday
1  
@kennytm The OP himself allows it. – seshoumara yesterday
3  
@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?) – Martin Ender yesterday

31 Answers 31

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.

share|improve this answer
16  
And 180 degree rotational symmetry, It's beautiful. – ATaco yesterday
1  
... and symmetry along vertical and horizontal axes :-) – Luis Mendo yesterday
    
More like 5 bytes in UTF-8, isn't it? – SteakOverflow 18 hours ago
2  
@SteakOverflow Brachylog uses a custom code-page, so those characters are not encoded in UTF-8 – DJMcMayhem 12 hours ago

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.
share|improve this answer
    
Why do you need the final _? – busukxuan yesterday
10  
@busukxuan From the question, "Additionally, the program or function you write must be a palindrome itself" – isaacg yesterday

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.

share|improve this answer
    
Wow, thos (, ) were some good (and confusing) inputs :) – ABcDexter 5 hours ago

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!

share|improve this answer
    
wow, recent addition. – Jonathan Allan yesterday
    
Yep, only 18 hours old. – Dennis yesterday

Jelly, 5 bytes

⁼ṚaṚ⁼

Try it online!

Equals reverse and reverse equals.

Or the more efficient yet less aesthetically pleasing:

⁼Ṛ
Ṛ⁼

or

Ṛ⁼
⁼Ṛ
share|improve this answer

Haskell, 87 85 44 bytes

In the end, the stupid solution is the best:

p=(==)<$>reverse<*>id--di>*<esrever>$<)==(=p

But here's my old version which abused comments a bit less:

--looB>-])([::reverse                                                          
l=id                                                                            
p l=reverse                                                                     
 l==l                                                                           
esrever=l p                                                                     
di=l                                                                            
esrever::[()]->Bool--
share|improve this answer
1  
Can you explain the code? – bli yesterday
1  
@bli everything after the -- is a comment. – theonlygusti yesterday

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!

share|improve this answer

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
share|improve this answer

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!

share|improve this answer

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 indentifier, which is ignored because of the ;.

share|improve this answer

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.

share|improve this answer

Perl 6, 25 bytes/chars utf8

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

Try it

share|improve this answer

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.

share|improve this answer

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!

share|improve this answer

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.
share|improve this answer
1  
TIO has support for sed now. -r doesn't work, but you can just wrap the whole thing in BASH. Try it Online! – Riley 18 hours ago
    
@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. – seshoumara 18 hours ago

R, 105 91 bytes

all((s<-charToRaw(scan(,"",,,"\n")))==rev(s))#))s(ver==)))"n\",,,"",(nacs(waRoTrahc-<s((lla

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

Ungolfed:

all((s<-charToRaw(scan(,"",,,"\n")))==rev(s))
#
))s(ver==)))"n\",,,"",(nacs(waRoTrahc-<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.

- 14 bytes thanks to @rturnbull !

share|improve this answer
    
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(waRoTr‌​ahc-<s((lla – rturnbull 1 hour ago
    
(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.) – rturnbull 58 mins ago
    
@rturnbull : thanks for the inputs ! I indeed tested éé with a latin1 encoding. – Frédéric 11 mins ago
    
Since the test must be done character-wise, I think the current programm breaks the rules. – Frédéric 1 min ago

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
share|improve this answer
    
Your source code is not a palindrome! – seshoumara 22 hours ago
    
@seshoumara Updated the code – Prasanth Bendra 21 hours ago
    
Now it's fine. Maybe mention the return value if the string is not a palindrome, just for completion sake. – seshoumara 21 hours ago

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
13
40

1
10
1
0
26
27
4
4
3

37
6
11
6
35
8
2
9
16
22
3
2
10
34
40
1
2
40
1
40
0
12
0
5
share|improve this answer
1  
Neat language! :) – DLosc 6 hours ago

Japt, 7 bytes

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 line gets ignored because w is a function that does not take 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.

share|improve this answer
    
@DLosc Added an explanation. – obarakon 5 hours ago
    
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()? – DLosc 5 hours ago
    
@DLosc Correct. It reverses U in the same way as U.reverse(). – obarakon 4 hours ago

PHP, 55 bytes

<?=strrev($s=$_GET[s])==$s;#;s$==)]s[TEG_$=s$(verrts=?<
share|improve this answer

QBIC, 17 bytes

;?A=_fA|#|Af_=A?;

Uses a boring comment-like ttrick to make the code a palindrome. Explanation:

;         Get a string literal from the cmd prompt
?         Print -1 for true and 0 for false in the following comparison
A=        Is A equal to
_fA|      A reversed?

#         Start a 'silent' string literal: This only forces the creation of string B
          with the following text, but doesn't inject a reference to B$ here.
|Af_=A?;  Code, reversed, as a string literal.
share|improve this answer

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.

share|improve this answer

AppleScript, 146 bytes

clutch

set x to(display dialog""default answer"")'s characters--
x=reverse of x--x fo esrever=x
--sretcarahc s')""rewsna tluafed""golaid yalpsid(ot x tes

This should be fairly obvious.

share|improve this answer

Java 8, 110 108 bytes

This is a comment version. Simply compare the string to a reversed version of itself and return true or false.

s->s.equals(new StringBuffer(s).reverse().toString())//))(gnirtSot.)(esrever.)s(reffuBgnirtS wen(slauqe.s>-s

Update

  • -2 [17-02-20] Removed ;'s
share|improve this answer

Dyalog APL, 21 Bytes

I decided to avoid a comment-based solution, and ended up with something pretty ugly. Instead of commenting out the second half of my code, I keep it in and allow the resulting syntax error to be part of my output.

A←⍞⋄0∊A=⌽A⋄A⌽=A∊0⋄⍞←A

This prompts the user to enter a string, and prints

0
SYNTAX ERROR: The function requires a left argument
      A←⍞ ⋄ 0∊A=⌽A ⋄ A⌽=A∊0 ⋄ ⍞←A

If the input is a palindrome, and prints

1
SYNTAX ERROR: The function requires a left argument
      A←⍞ ⋄ 0∊A=⌽A ⋄ A⌽=A∊0 ⋄ ⍞←A

If the input is not a palindrome.

A simple comment based solution would be to replace the middle character () with the comment symbol ():

A←⍞⋄0∊A=⌽A⍝A⌽=A∊0⋄⍞←A

This does the same as above but doesn't include the syntax error in the output.

Here's an ungolfed version:

A←⍞          ⍝ prompt user for input, store in variable A
⋄             ⍝ statement separator 
0∊A=⌽A       ⍝ return '0' if A is equal to A reversed (`⌽A`). Otherwise return '1' 
⋄             ⍝ statement separator
A⌽=A∊0⋄⍞←A   ⍝ reverse of preceding code, throws a syntax error
share|improve this answer

CJam, 13 bytes

l_W%=e#e=%W_l

Explanation:

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

Example:

> 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
share|improve this answer

><>, 11 bytes

{=?!;
;!?={

Try it here!

Returns "\nsomething smells fishy..." upon a valid palindrome, no output upon an invalid palindrome. Place the palindrome on the stack.

share|improve this answer

Common Lisp, 104 bytes

(lambda(s)(format t"~:[F~;T~]"(equal(reverse s)s)));;)))s)s esrever(lauqe("]~T;~F[:~"t tamrof()s(adbmal(

Abusing idea for commenting out part of code from comments under question.

share|improve this answer

Java - 171 169 161 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

share|improve this answer
    
I believe you can save some bytes by returning ints instead of chars. – DLosc 6 hours ago

^ - 1 byte.

~

^ is my own language (which I've yet to write). In ^ the ~function reads an input string and outputs trueor falsedepending upon if the input is a palindrome.

share|improve this answer
    
Yes - this is tongue-in-cheek, but it's not too far removed from some of these other answers. There a language with a single-character function that outputs true or false depending upon if the input is a palindrome? Great, but not really in the spirit of the challenge. – Steve Ives 1 hour ago
    
Language functions (or whole languages) which are newer than the challenge are usually regarded as non-competing. – rturnbull 1 hour ago
    
@SteveIves Check the rules here: meta.codegolf.stackexchange.com/questions/1061/… – this is explicitly non-competing. – Ven 59 mins ago
    
I'm not sure there's much difference is writing a new language to answer a challenge in 1, 2 or 3 bytes; and setting a challenge that can be answered in an existing language in 1, 2 or 3 bytes. – Steve Ives 55 mins ago
1  
anyway, I'm trying to write a answer in IBM z/OS assembler... – Steve Ives 29 mins ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.