Write a program to test if a string is palindromic, with the added condition that the program be palindromic itself.

  • 1
    \$\begingroup\$ If the language has till-the-end-of-the-line comments this is trivial so I guess those should be disallowed. \$\endgroup\$
    – Joey
    Mar 26, 2011 at 14:05
  • 1
    \$\begingroup\$ @Joey I'd happily discourage use of such comments, but disallowing them after posing the question is harsh on those who have already answered. @Ventero's answer (the only one not using them) is way ahead on vote count, so everyone seems to agree. \$\endgroup\$
    – moinudin
    Mar 26, 2011 at 14:07
  • 1
    \$\begingroup\$ Well, to weed out such problems earlier (this also occurred in a similar task on SO) you could use the sandbox or the Puzzle lab ;-) \$\endgroup\$
    – Joey
    Mar 26, 2011 at 14:13
  • 1
    \$\begingroup\$ How about imposing that the program should be a palindromic quine itself evil grin ;-) \$\endgroup\$
    – Quixotic
    Mar 26, 2011 at 14:43
  • 4
    \$\begingroup\$ I know this is an old question, but I think it needs an arbitrary winning criterion, such as popularity contest or code-golf. The question specifies none. \$\endgroup\$
    – mbomb007
    Sep 13, 2015 at 21:41

13 Answers 13



z=gets;puts *z.reverse==z&&1||0||1&&z==esrever.z* stup;steg=z

Prints 1 if the input is a palindrome, 0 if it isn't. Input without linebreak.

Doesn't use any comments, instead it uses 2 tricks:

  • Short-circuiting: 0 is true-ish in Ruby (only nil and false evaluate to false), so 1&&z==esrever.z* stup isn't evaluated and thus can't raise a runtime exception
  • The splat/multiplication operator (*): To avoid a syntax error in z=esrever.z stup, we force the parser to parse this as z=esrever.z()*stup by adding a *. On the other side, the * is parsed as a splat operator, which in a function call splits an array in a series of parameters. If there's only one element instead of an array, it basically does nothing, so puts *foo is equivalent to puts foo.

Obvious solution using comments (prints true/false):

puts gets.reverse==$_#_$==esrever.steg stup
  • \$\begingroup\$ Can you explain how this works. I don't know ruby. \$\endgroup\$
    – mellamokb
    Mar 28, 2011 at 20:52
  • \$\begingroup\$ @mellamokb: I added a short explanation. Let me know if it's still not clear. \$\endgroup\$
    – Ventero
    Mar 30, 2011 at 12:23

Python without comment

"a\";w=]1-::[w trinp;)(tupni_war=w;";w=raw_input();print w[::-1]==w;"\a"

I'm surprised that no one found that trick yet, it should work in most languages!

  • 2
    \$\begingroup\$ Very Clever, I like the escaping quote. \$\endgroup\$ Aug 12, 2011 at 15:24
  • \$\begingroup\$ Nice solution, you could even drop the print statement and if you allow the input to specified enclosed in quotes raw_input() can be shortened to input(). Missing an extra '=' at the start. \$\endgroup\$
    – Willem
    May 10, 2014 at 7:06
  • \$\begingroup\$ removed trailing output after True or False: "a\"#;w==]1-::[w;)(tupni_war=w;";w=raw_input();w[::-1]==w;#"\a" \$\endgroup\$
    – Willem
    May 10, 2014 at 7:13
  • \$\begingroup\$ @Willem Replace ;# with != and you've got a comment-free solution again, assuming printable input. \$\endgroup\$
    – wizzwizz4
    Jan 2, 2021 at 20:14


perl -nle "$s=$_ eq+reverse;print$s;s$tnirp;esrever+qe _$=s$"

no comment tricks, just cleverly abusing the substitution operator (hey, perl variables start with a $ too, so what?)


Python 2.7



#include <stdio.h>                   //
#include <string.h>                  //
int main() {                         //
  char str[1024];                    //
  fgets(str, sizeof(str), stdin);    //
  int i = 0, j = strlen(str) - 2;    //
  for (; i < j; i++, j--)            //
    if (str[i] != str[j]) {          //
      printf("no\n");                //
      return 0;                      //
    }                                //
  printf("yes\n");                   //
}                                    //
//                                    }
//                   ;)"n\sey"(ftnirp  
//                                }    
//                      ;0 nruter      
//                ;)"n\on"(ftnirp      
//          { )]j[rts =! ]i[rts( fi    
//            )--j ,++i ;j < i ;( rof  
//    ;2 - )rts(nelrts = j ,0 = i tni  
//    ;)nidts ,)rts(foezis ,rts(stegf  
//                    ;]4201[rts rahc  
//                         { )(niam tni
//                  >h.gnirts< edulcni#
//                   >h.oidts< edulcni#

Running example:

$ gcc -std=c99 c.c && ./a.out 
  • \$\begingroup\$ won't win for brevity, but I'm impressed \$\endgroup\$ Aug 12, 2011 at 15:25
  • \$\begingroup\$ lol, clever-lvl 11/10. \$\endgroup\$
    – nymo
    Oct 12, 2015 at 4:16


  • just with comment trick
  • input without \n at the end
  • perform matching char by char (even for punctuation)
  • returns 1 for success, 0 for failure


echo strrev($z)==$z;#;z$==)z$(verrts ohce


  • $z string, the input string to check
  • $t boolean, TRUE if the input string $z is palindrome, FALSE otherwise
  • Using comments to help me make the code palindrome.
  • Outputs $t
  • Source itself is a palindrome

The reason why it will not be possible to implement palindromic palindrome checker in PHP it's because PHP variables are named starting with a $. You cannot end an identifier name with $ in PHP.



<?php eval/*/*/(';{$i=fgets(STDIN,2e9);};{$a="strrev";}{var_dump("{$i}"=="{$a($i)}");}/*}{*\{;("{(tupni$)a$}"=="{putni$}")ohce}{;"verrts"==a$};{;(9e2,NIDTS)stegf=i$);');/*\*\eval php?>

Uses some odd tricks to avoid the $ issue, technically isnt a palindrome as I had to sneak a ; in at the end.

 <?php $i = fgets(STDIN,2e9); echo $i == strrev($i);/*\;(i$)verrts == i$ ohce ;(9e2, NIDTS)stegf = $i php?>

This is a working one that uses PHP's /* */ comments and the fact that you don't need the end for them.

  • 2
    \$\begingroup\$ In the end first code, eval should be lave. \$\endgroup\$ Jan 29, 2014 at 18:48

Fuzzy Octo Guacamole, 17 bytes


Not exactly sure how the win is defined, but I put the byte count up top.

^ gets the input and pushes it to the first stack.

C copies the first stack to the second.

z reverse the top of the stack, so "as" becomes "sa".

. shifts the active stack, so the active stack has the input, and the inactive one has the reversed input.

= checks for equality, returning 0 for equality.

i inverts the ToS, so 0 becomes 1, and anything else pretty much becomes False.

_ pops and sets the temp variable which the ; then prints.

@ ends the program manually, so it doesn't hit the reversed part. This makes the palindrome.



I actually struggled with the reverse spellings of 'split', 'reverse' and 'join' :\



print args[0]==args[0].reverse()?1:0//0:1?)(esrever.]0[sgra==]0[sgra tnirp
  • \$\begingroup\$ You have used comments over here! \$\endgroup\$
    – Ant's
    Jun 20, 2011 at 5:31

Python 3, 55 bytes

Uses a comment, but is shorter than the other Python one that uses comments.



function a(b){return b==b.split('').reverse().join('')}//})''(nioj.)(esrever.)''(tilps.b==b nruter{)b(a noitcnuf

Hard to do it without comments...


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