A palindrome is some string that is spelled the same way both backwards and forwards. For instance, 'Eva, can I stab bats in a cave?' is a palindrome (EVACANISTAB | BATSINACAVE)
For this code golf, using the language of your choice, determine if a given string is a palindrome or not.
Edge Cases:
- Punctuation is not counted towards palindrominess.
- Control characters are not counted towards palindrominess.
- Whitespace is not counted towards palindrominess.
- Numbers are counted towards palindrominess.
- Case in this challenge is not counted towards palindrominess.
- There is no limit to the length of strings to evaluate, except for what is imposed by your language of choice.
- For this challenge, limit yourself to the ASCII character set.
Technical Requirements:
- Only method bodies are needed; additional things like method signatures, data structure declarations, etc. do not count towards the victory requirement.
- Code must compile or interpret without compile-time errors or exceptions.
- Code must not throw any unhandled exceptions or crash. (Almost needless to say. Almost.)
- Code must return some value indicating palindrominess. The data type depends on the language you use (e.g. a C# user might use a
bool
, whereas a JavaScript user could use avar
.) - You may not write your own interpreter that performs this task as a 'native' capability so you can 'golf' a near-winning score. (Hopefully needless to say.)
Victory Condition:
- The shortest code in characters wins.
Current Leader: tmartin (k, 25 characters)
...Want the magic green check mark by your answer? Beat this guy's answer!
-
1\$\begingroup\$ Is I/O a part of the challenge, or a function body will do? \$\endgroup\$John Dvorak– John Dvorak2013年04月08日 18:43:29 +00:00Commented Apr 8, 2013 at 18:43
-
1\$\begingroup\$ The "breadcrumbs" for showing how the work is refined are available site-wide in all answers via revision history. There's no need to have a full history visible in the current version of the answer. \$\endgroup\$Peter Taylor– Peter Taylor2013年04月08日 20:27:31 +00:00Commented Apr 8, 2013 at 20:27
-
1\$\begingroup\$ @WernerCD I'm sure the OP will change who gets the green tick when he comes back to check on the new responses. \$\endgroup\$Gareth– Gareth2013年04月09日 07:15:52 +00:00Commented Apr 9, 2013 at 7:15
-
3\$\begingroup\$ Not specifying a language really trivialises this challenge for me. As seen below, interpreted languages with a focus on high order text manipulation functions always get the shortest results. What is to stop me throwing together my own interpreter with a single function, ip(). My compete algorithm is now 'ip:i'. 4 characters. done. \$\endgroup\$Gusdor– Gusdor2013年04月09日 08:11:19 +00:00Commented Apr 9, 2013 at 8:11
-
3\$\begingroup\$ @Gusdor see J and GolfScript suck all the enjoyment out of Code Golf and Language Handicap and related questions on this site's meta. \$\endgroup\$AakashM– AakashM2013年04月09日 08:25:20 +00:00Commented Apr 9, 2013 at 8:25
53 Answers 53
K, 25
{x~|x:_x@&x in,/.Q`a`A`n}
.
k){x~|x:_x@&x in,/.Q`a`A`n}"Eva, can I stab bats in a cave?"
1b
-
\$\begingroup\$ Looks like a mixture of Q and k :P \$\endgroup\$skeevey– skeevey2013年04月09日 12:29:24 +00:00Commented Apr 9, 2013 at 12:29
-
\$\begingroup\$ Well, I wouldn't exactly call .Q.A etc q. They're just string wrappers, there's no real k code underneath them. Now, if I said .q.inter I'd be in trouble. \$\endgroup\$tmartin– tmartin2013年04月09日 12:45:35 +00:00Commented Apr 9, 2013 at 12:45
-
\$\begingroup\$ I guess it's a case of quibbling over semantics but they are defined in q.k \$\endgroup\$skeevey– skeevey2013年04月09日 12:54:20 +00:00Commented Apr 9, 2013 at 12:54
-
\$\begingroup\$ Could just say Q for 31:
{x~(|)x:(_)x inter(,/).Q`a`A`n}
\$\endgroup\$tmartin– tmartin2013年04月09日 13:03:09 +00:00Commented Apr 9, 2013 at 13:03 -
1\$\begingroup\$ i know this is very old but... you can save 1 byte with
{#|:\_x@&x in,/.Q`a`A`n}
, where 1 is true and 2 is false \$\endgroup\$scrawl– scrawl2019年10月24日 14:14:06 +00:00Commented Oct 24, 2019 at 14:14
Perl, 26 char
s/_|\W//g;uc eq reverse uc
Evaluates to 1 when $_
is a palindrome, ""
(one of Perl's false values) when it is not.
Sample usage:
sub palin {
s/_|\W//g;uc eq reverse uc
}
while (<DATA>) {
chomp;
print "$_ => ",palin()?"yes":"no","\n";
}
__DATA__
Eva, can I stab bats in a cave?
A man, a plan, a canal. Panama!
Madam, I'm Adam Carolla.
757
Boeing 757
A man, a plan, a big shovel, a canal. Panama!
A man, a plan, a canoe, pasta, heros, rajahs, a coloratura, maps, snipe, percale, macaroni, a gag, a banana bag, a tan, a tag, a banana bag again (or a camel), a crepe, pins, Spam, a rut, a Rolo, cash, a jar, sore hats, a peon, a canal >> __Panama__
output:
Eva, can I stab bats in a cave? => yes
A man, a plan, a canal. Panama! => yes
Madam, I'm Adam Carolla. => no
757 => yes
Boeing 757 => no
A man, a plan, a big shovel, a canal. Panama! => no
A man, a plan, a canoe, pasta, heros, rajahs, a coloratura, maps, snipe, percale, macaroni, a gag, a banana bag, a tan, a tag, a banana bag again (or a camel), a crepe, pins, Spam, a rut, a Rolo, cash, a jar, sore hats, a peon, a canal >> __Panama__ => yes
-
\$\begingroup\$ Damn, you beat me to it. Though this won't work properly if there's a
_
in the string will it? And it doesn't take any input so won't you need to use the-p
option? \$\endgroup\$Gareth– Gareth2013年04月08日 22:35:50 +00:00Commented Apr 8, 2013 at 22:35 -
\$\begingroup\$
\W
in regexes excludes underscore. I'm afraid you'll need[^a-z\d]
in your regex. I'm afraid I'm beaten anyways. \$\endgroup\$John Dvorak– John Dvorak2013年04月08日 22:37:14 +00:00Commented Apr 8, 2013 at 22:37 -
3\$\begingroup\$ Save one with
_|\W
instead of[_\W]
. \$\endgroup\$Howard– Howard2013年04月09日 09:20:20 +00:00Commented Apr 9, 2013 at 9:20 -
1\$\begingroup\$ You can shorten
_|\W
to\Pl
: ideone.com/0ufdaQ . Should be just the Unicode letters. \$\endgroup\$Kobi– Kobi2013年04月10日 07:13:48 +00:00Commented Apr 10, 2013 at 7:13 -
\$\begingroup\$ Actually, thinking again -
\Pl
would not match digits, so I guess_|\W
is the best you could do. \$\endgroup\$Kobi– Kobi2013年04月10日 09:59:42 +00:00Commented Apr 10, 2013 at 9:59
C# 82 only :)
var x=s.ToLower().Where(char.IsLetterOrDigit);return x.SequenceEqual(x.Reverse());
Couldn't resist the temptation of writing a boilerplate-free program in my favorite language.
A test is available here: http://ideone.com/8bwz7z
-
\$\begingroup\$ Simple...but elegant! \$\endgroup\$Andrew Gray– Andrew Gray2013年04月08日 20:21:22 +00:00Commented Apr 8, 2013 at 20:21
-
\$\begingroup\$ @AndrewGray thank you for the comment and for the permissive Technical Requirements. C# boilerplate adds seriously to the char count, making it impractical for golf otherwise. \$\endgroup\$Cristian Lupascu– Cristian Lupascu2013年04月08日 20:31:03 +00:00Commented Apr 8, 2013 at 20:31
-
2\$\begingroup\$ No prob. I'm a fellow C# dev, and I like writing concise, efficient code. It's a shame there's so much boilerplate in the language... \$\endgroup\$Andrew Gray– Andrew Gray2013年04月08日 21:13:08 +00:00Commented Apr 8, 2013 at 21:13
GolfScript, (削除) 36 34 31 (削除ここまで) 30 characters
{0"0:A[a{"@{>^}+/},{32|}%.-1%=
Similar algorithm to my previous (Javascript) solution.
0"0:A[a{"@{>^}+/
-- Optimised by Peter Taylor and Howard. My version was "/9@Z"{1$<},,2%\;
. Howard donated function concatenation and Peter Taylor donated XOR for modulo-2. It's basically a generic method of comparing if the value is in a sequence of ranges.
{.96>32*-}%
(11 characters) is not really an improvement over Javascript's .toUpperCase()
(14 characters), especially since it mangles some weird punctuation that follows z
in the ASCII table (which doesn't matter here).
as Peter Taylor's suggested, however, if we filter out alphanumerics first, we can convert to lowercase and digits just by setting one bit in each character: {32|}
.-1%=
does all the palindromic heavy lifting. One part I'm not really fond of is how long it took me to find out how to reverse an array. I should have read the docs. The other two characters perform stack management and comparison.
Further, if I can assume that none of the following control characters are present: (Data link escape, device control 1-4, negative acknowledge, synchronous idle, end of transmission block, cancel, end of medium) (we all agree these are all pretty obscure) or if I can treat them as uppercase versions of the digits 0-9, we can save another two characters:
GolfScript, 28 characters
{32|}%{0"0:a{"@{>^}+/},.-1%=
-
2\$\begingroup\$ You can get rid of the clean up and save two chars:
{"0:A["\{>}+,,2%},
\$\endgroup\$Howard– Howard2013年04月08日 21:01:42 +00:00Commented Apr 8, 2013 at 21:01 -
\$\begingroup\$ @Howard Thanks. I think I misunderstood
+
on blocks. That's a cool trick. \$\endgroup\$John Dvorak– John Dvorak2013年04月08日 21:08:50 +00:00Commented Apr 8, 2013 at 21:08 -
1\$\begingroup\$ You can save three chars by reversing the filter and the case standardisation. You have to add
a{
to the filter's list of characters to include the lower-case letters, but you can then upper-case with just{32|}%
. The end result is{"0:A[a{"\{>}+,,2%},{32|}%.-1%=
\$\endgroup\$Peter Taylor– Peter Taylor2013年04月10日 23:09:06 +00:00Commented Apr 10, 2013 at 23:09 -
\$\begingroup\$ There also another saving to be made on the filter. Counting modulo 2 is xor, so
0"0:A[a{"@{>^}+/
does the job. \$\endgroup\$Peter Taylor– Peter Taylor2013年04月11日 08:13:11 +00:00Commented Apr 11, 2013 at 8:13 -
\$\begingroup\$ @PeterTaylor If I don't come up with another optimisation myself soon, I probably should convert to community wiki. Thanks again :-) \$\endgroup\$John Dvorak– John Dvorak2013年04月11日 08:36:52 +00:00Commented Apr 11, 2013 at 8:36
Javascript, 53 characters:
(x=x.toLowerCase().match(/[a-z\d]/g))+""==x.reverse()
is a javascript expression that evaluates to true if x
is a palindrome, to false if it isn't. It assumes x
is a string. If that's not guaranteed, prepend x+="",
Here's a breadcrumb: Due to how reverse()
works,
(x=x.toLowerCase().match(/[a-z\d]/g))==""+x.reverse()
fails. However,
""+(x=x.toLowerCase().match(/[a-z\d]/g))==x.reverse()
is perfectly fine.
-
\$\begingroup\$ Nice tidbit on concatenating a null string! Points for good infoz! \$\endgroup\$Andrew Gray– Andrew Gray2013年04月08日 19:35:47 +00:00Commented Apr 8, 2013 at 19:35
-
3\$\begingroup\$ Hints:
+""
casts to a string,+
casts to a number,|0
and~~
cast to an integer,!!
casts to a boolean. \$\endgroup\$John Dvorak– John Dvorak2013年04月08日 19:37:28 +00:00Commented Apr 8, 2013 at 19:37 -
\$\begingroup\$ Is a char shorter with regex
/[^\W_]/g
\$\endgroup\$SuperPrograman– SuperPrograman2015年12月06日 21:36:37 +00:00Commented Dec 6, 2015 at 21:36
Bash: (削除) 52 (削除ここまで) (削除) 48 (削除ここまで) 46 characters
s=${1,,};s=${s//[^a-z0-9]};[ $s = `rev<<<$s` ]
This takes the sting to check as first parameter and sets the exit code to 0 for palindrome and 1 for not.
Sample run:
bash-4.2$ p() { s=${1,,};s=${s//[^a-z0-9]};[ $s = `rev<<<$s` ]; }
bash-4.2$ p 'Eva, can I stab bats in a cave?'; echo $?
0
bash-4.2$ p 'A man, a plan, a canal. Panama!'; echo $?
0
bash-4.2$ p "Madam, I'm Adam Corolla."; echo $?
1
bash-4.2$ p '757'; echo $?
0
bash-4.2$ p 'Boeing 757'; echo $?
1
bash-4.2$ p 'A man, a plan, a shovel, a canal. Panama!'; echo $?
1
bash-4.2$ p 'A_man,_a_plan, a_caremer, a canal:_Panama!'; echo $?
0
Python 2: 49 (without counting the method signature)
def f(s):
s=filter(str.isalnum,s.upper())
return s==s[::-1]
A complete program, with input and output can be writte in 74 characters.
import sys
s=filter(str.isalnum,sys.stdin.read().upper())
print s==s[::-1]
Example usage:
$echo 'Eva,can I stab bats in a cave?' | python palindrome.py
True
$ cat huge_palindrome.txt | python palindrome.py
True
$echo 'Able was I ere i SaW elBa' | python palindrome.py
True
(huge_palindrome.txt
contains this 17,826 word palindrome)
This solution can be adapted to python 3 adding some characters:
Python 3: 55
def f(s):
s=list(filter(str.isalnum,s.upper()))
return s==s[::-1]
-
\$\begingroup\$
sys.stdin.read
is basically the same asraw_input
\$\endgroup\$CalculatorFeline– CalculatorFeline2016年03月27日 15:47:55 +00:00Commented Mar 27, 2016 at 15:47 -
\$\begingroup\$ In Python 3.8 you can shorten this to 58 bytes \$\endgroup\$MilkyWay90– MilkyWay902019年03月16日 21:55:15 +00:00Commented Mar 16, 2019 at 21:55
-
\$\begingroup\$ Also, your Python 2 & 3 solution is 61 bytes and 67 bytes, respectively. \$\endgroup\$MilkyWay90– MilkyWay902019年03月16日 22:00:50 +00:00Commented Mar 16, 2019 at 22:00
-
\$\begingroup\$ @MilkyWay90 You probably missed the without counting the method signature. In 2013 it was customary to not include it. In other solution in this question in other languages they simply omitted it and assumed you have the input in an
s
variable. I decided to provide the complete definition but, as customary in 2013, do not include the method signature in the length \$\endgroup\$Bakuriu– Bakuriu2019年03月17日 16:25:15 +00:00Commented Mar 17, 2019 at 16:25 -
\$\begingroup\$ @Bakuriu Ah, I see. I've only been here a few months, so I don't know customs from 2013 \$\endgroup\$MilkyWay90– MilkyWay902019年03月17日 16:33:02 +00:00Commented Mar 17, 2019 at 16:33
R: 66
w=grep("[a-z0-9]",strsplit(tolower(s),"")[[1]],v=T);all(w==rev(w))
Usage:
f=function(s){w=grep("[a-z0-9]",strsplit(tolower(s),"")[[1]],v=T);all(w==rev(w))}
f("Eva, can I stab bats in a cave?")
[1] TRUE
JAVA (or the most verbose language ever), (削除) 102 (削除ここまで) (削除) 96 (削除ここまで) 95 char
s=s.replaceAll("\\W|_","");return s.equalsIgnoreCase(new StringBuffer(s).reverse().toString());
Usage (with ungolfed code):
static boolean q(String s) {
s=s.replaceAll("\\W|_","");
return s.equalsIgnoreCase(new StringBuffer(s).reverse().toString());
}
public static void main(String[] args) {
System.out.println(q("'A man, a plan, a canal - Panama!'"));
}
Shortened with the help of the commenter below
-
1\$\begingroup\$ While I don't know Java (I'm a C# guy, funny enough), couldn't you save 1 character by taking out the curly braces on the if? E.G.:
if(s==null) return 1==0;
? Or does Java enforce curlies onif
statements? \$\endgroup\$Andrew Gray– Andrew Gray2013年04月09日 14:14:11 +00:00Commented Apr 9, 2013 at 14:14 -
3\$\begingroup\$ You are absolutely right, I took that out thank you!!... I haven't notice they were there, I guess I'm a Java developer that doesn't C#? \$\endgroup\$jsedano– jsedano2013年04月09日 14:17:44 +00:00Commented Apr 9, 2013 at 14:17
-
4\$\begingroup\$ 1) Checking whether the parameter is
null
is a good habit, but not practiced in CodeGolf. As I can tell, nobody else did it in this question. Skip it. 2) The space between arguments helps readability, but not golfing. Remove it; 3) Instead of explicitlytoLowerCase()
the string useequalsIgnoreCase()
later instead ofequals()
. This way you have to adjust the regular expression, but still 1 character shorter. pastebin.com/s7H84faj \$\endgroup\$manatwork– manatwork2013年04月09日 14:22:34 +00:00Commented Apr 9, 2013 at 14:22 -
1\$\begingroup\$
replaceAll("[^A-Za-z0-9]","")
=>replaceAll("\\W","")
\$\endgroup\$assylias– assylias2013年04月10日 11:21:43 +00:00Commented Apr 10, 2013 at 11:21 -
1\$\begingroup\$ I know this has been answered more than three years ago, but you can golf two more things:
.toString()
can be+""
, and you can make it a one-lined to save another byte like this:return(s=s.replaceAll("\\W|_","")).equalsIgnoreCase(new StringBuffer(s).reverse()+"");
(86 bytes) \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2016年11月04日 10:02:23 +00:00Commented Nov 4, 2016 at 10:02
Mathematica (削除) 54 (削除ここまで) 53
One byte saved thanks to CatsAreFluffy:
PalindromeQ@StringCases[ToUpperCase@#,WordCharacter]&
For those with version 10.2 or earlier:
#==Reverse@#&@StringCases[ToUpperCase@#,WordCharacter]&
Example
PalindromeQ@StringCases[ToUpperCase@#, WordCharacter]&["Eva,can I stab bats in a cave?"]
True
-
\$\begingroup\$
PalindromeQ
is 1 byte shorter than#==Reverse@#&
\$\endgroup\$CalculatorFeline– CalculatorFeline2016年03月18日 03:27:48 +00:00Commented Mar 18, 2016 at 3:27 -
\$\begingroup\$ I wondered why I had never seen it. Version 10.3! \$\endgroup\$DavidC– DavidC2016年03月18日 12:55:02 +00:00Commented Mar 18, 2016 at 12:55
-
\$\begingroup\$
PalindromeQ= #==Reverse@#&
\$\endgroup\$CalculatorFeline– CalculatorFeline2016年03月18日 15:39:21 +00:00Commented Mar 18, 2016 at 15:39 -
\$\begingroup\$ Yes, I downloaded v. 10.4 to try it out. \$\endgroup\$DavidC– DavidC2016年03月18日 21:28:26 +00:00Commented Mar 18, 2016 at 21:28
-
\$\begingroup\$ That's out? OHNO \$\endgroup\$CalculatorFeline– CalculatorFeline2016年03月18日 21:42:01 +00:00Commented Mar 18, 2016 at 21:42
J, 30 characters
*/(=|.)tolower(#~'[^_\W]'rxE])
Usage:
*/(=|.)tolower(#~'[^_\W]'rxE])'A man, a plan, a canal - Panama!'
1
*/(=|.)tolower(#~'[^_\W]'rxE])'Doc, note: I dissent. A fast never prevents a fatness. I diet on cod'
1
k ((削除) 50 48 45 (削除ここまで) 38 chars)
Suppresses all errors, returning a default of 0b
(false).
{X~|X@:&(X:_:x)in 10h$(48+!10),97+!26}
Example:
k){X~|X@:&(X:_:x)in 10h$(48+!10),97+!26} "Eva, can I stab bats in a cave?"
1b
edit: shaved three more character by avoiding intermediate variable. H/T, CS. -7: No need to suppress errors.
-
1\$\begingroup\$ interesting that at just 3 characters more, my code is much more readable :-) \$\endgroup\$John Dvorak– John Dvorak2013年04月08日 19:38:11 +00:00Commented Apr 8, 2013 at 19:38
-
\$\begingroup\$ An extra char slipped in, I have removed it. \$\endgroup\$skeevey– skeevey2013年04月08日 19:42:04 +00:00Commented Apr 8, 2013 at 19:42
Ruby: (削除) 43 (削除ここまで) 38 characters
s=s.upcase.tr'^A-Z0-9','';s==s.reverse
Sample run:
irb(main):001:0> p=->s{s=s.upcase.tr'^A-Z0-9','';s==s.reverse}
=> #<Proc:0x854592c@(irb):1 (lambda)>
irb(main):002:0> p['Eva, can I stab bats in a cave?']
=> true
irb(main):003:0> p['A man, a plan, a canal. Panama!']
=> true
irb(main):004:0> p["Madam, I'm Adam Corolla."]
=> false
irb(main):005:0> p['757']
=> true
irb(main):006:0> p['Boeing 757']
=> false
irb(main):007:0> p['A man, a plan, a shovel, a canal. Panama!']
=> false
irb(main):009:0> p['A_man,_a_plan, a_caremer, a canal:_Panama!']
=> true
-
1\$\begingroup\$ You can even write
s.tr!('^A-Za-z0-9','').upcase!.reverse==s
\$\endgroup\$Howard– Howard2013年04月09日 09:19:43 +00:00Commented Apr 9, 2013 at 9:19 -
\$\begingroup\$ Man, how long I combined around the use of the
!
methods! You keep amazing me @Howard with your tricks. \$\endgroup\$manatwork– manatwork2013年04月09日 09:41:52 +00:00Commented Apr 9, 2013 at 9:41 -
\$\begingroup\$ Small problem though, @Howard.
tr
andtr!
seems to behave different when they have nothing to transliterate: pastebin.com/4YThW2qN That makes thep['757']
test to crash with "NoMethodError: undefined method `upcase!' for nil:NilClass" error. \$\endgroup\$manatwork– manatwork2013年04月09日 09:53:39 +00:00Commented Apr 9, 2013 at 9:53 -
\$\begingroup\$ Oops, sorry. Didn't think about that case. \$\endgroup\$Howard– Howard2013年04月09日 11:24:00 +00:00Commented Apr 9, 2013 at 11:24
-
1\$\begingroup\$ can be shortened further:
s=s.upcase.tr('^A-Z0-9','');s==s.reverse
\$\endgroup\$Cristian Lupascu– Cristian Lupascu2013年04月09日 12:12:29 +00:00Commented Apr 9, 2013 at 12:12
C++, (削除) 107 (削除ここまで) (miscounted), (削除) 100 (削除ここまで) (miscounted), 81
string s;for(int c:t)if(isalnum(c))s+=c|32;return s==string(s.rbegin(),s.rend());
- Exploits ASCII bit patterns.
- Relies on an evil
using namespace std;
. - Uses bitwise AND and OR instead of the logical operators.
Uses
int
because it's shorter thanchar
orauto
.#include <string> using namespace std; bool IsPalindrome(const string & t) { string s;for(int c:t)if(isalnum(c))s+=c|32;return s==string(s.rbegin(),s.rend()); } #include <cassert> int main() { assert(!IsPalindrome("gorilla")); // simple failure assert( IsPalindrome("racecar")); // simple success assert( IsPalindrome("Hannah")); // case blind assert(!IsPalindrome("1999")); // digit failure assert( IsPalindrome("2002")); // digit success // Ignore spacing, punctuation, and case: assert( IsPalindrome(" \t09AZ/:@[`{za90")); // boundaries assert( IsPalindrome("A man, a plan, a canal: Panama.")); assert( IsPalindrome("Eva, can I stab bats in a cave?")); assert( IsPalindrome("")); // empty string return 0; }
Lua, 56
a=io.read"*l":lower():gsub("%W","")print(a:reverse()==a)
-
\$\begingroup\$ If
%W
is anything like\W
in regex, it also excludes characters like underscore. This is unwanted. \$\endgroup\$John Dvorak– John Dvorak2013年04月08日 19:35:18 +00:00Commented Apr 8, 2013 at 19:35 -
\$\begingroup\$ i checked,
%w
doesn't include_
(%W
obviously includes it, then) \$\endgroup\$mniip– mniip2013年04月08日 19:48:43 +00:00Commented Apr 8, 2013 at 19:48 -
1\$\begingroup\$ Only function body is needed.
s=s:lower():gsub('%W','')return s:reverse()==s
46 chars \$\endgroup\$Egor Skriptunoff– Egor Skriptunoff2013年04月09日 00:16:54 +00:00Commented Apr 9, 2013 at 0:16 -
\$\begingroup\$ but what about
function(s)
\$\endgroup\$mniip– mniip2013年04月09日 04:40:21 +00:00Commented Apr 9, 2013 at 4:40
Python 3/2 59 chars:
def pld(i):
p=[c for c in i.lower() if c.isalnum()]
return(p == p[::-1])
Haskell, 43
Using the standard libraries Control.Monad
, Control.Monad.Instances
, and Data.Char
:
ap(==)reverse.map toLower.filter isAlphaNum
-
\$\begingroup\$ I can't make this to work in ghci.
import Data.Char
import Control.Monad
ap(==)reverse.map toLower.filter isAlphaNum
neither does it with adding spaces or such, sorry I'm not too keen with Haskell :) \$\endgroup\$SlimJim– SlimJim2013年04月12日 07:48:21 +00:00Commented Apr 12, 2013 at 7:48 -
1\$\begingroup\$ @SlimJim: Oops, you need
Control.Monad.Instances
as well. (I’m using the Reader monad instance withap
, but that instance isn’t exported byControl.Monad
.) \$\endgroup\$Jon Purdy– Jon Purdy2013年04月12日 19:11:47 +00:00Commented Apr 12, 2013 at 19:11
PHP 60 characters.
First try on codegolf.
//thank you manatwork
echo($x=preg_replace('/\W/','',strtolower($c)))==strrev($x);
Example:
$c='Eva, can I stab bats in a cave?';
echo($x=preg_replace('/\W/','',strtolower($c)))==strrev($x);
//prints 1
-
\$\begingroup\$ The parenthesis around the ternary operator's first operand are not needed. Actually neither the ternary operator is needed – just output true or false in your language's representation. And by avoiding the separate statement for the assignment to $x 1 more character can be shortened:
echo($x=preg_replace('/\W/','',strtolower($c)))==strrev($x);
. \$\endgroup\$manatwork– manatwork2013年11月27日 12:44:33 +00:00Commented Nov 27, 2013 at 12:44
Python 2 64 Charecters:
i =''.join(re.findall('[a-z0-9]+',i.lower()))
return i==i[::-1]
-
\$\begingroup\$ @manatwork If you replace all the identifiers with one character identifiers you obtain a
77
characters version. No idea why abhiram posted the ungolfed version though. \$\endgroup\$Bakuriu– Bakuriu2013年04月09日 07:04:21 +00:00Commented Apr 9, 2013 at 7:04 -
\$\begingroup\$ @Bakuriu, never mind, I missed one statement in the question: "Only method bodies are needed". Though lines 2 and 3 gives me only 73 characters. Regarding further length reduction, no need for raw string and the capture group, making the
re.findall('[a-z0-9]+',input.lower())
part 3 characters shorter. \$\endgroup\$manatwork– manatwork2013年04月09日 07:16:14 +00:00Commented Apr 9, 2013 at 7:16 -
\$\begingroup\$ @manatwork, I edited the post and changed the variables a little. That brought it down to 66. Yes, the raw string attribute is of no use here. \$\endgroup\$abhiram– abhiram2013年04月09日 08:39:25 +00:00Commented Apr 9, 2013 at 8:39
-
\$\begingroup\$ Ok, but why you insist on the capturing group in the regular expression? Works correctly without: pastebin.com/JzpNRRZU \$\endgroup\$manatwork– manatwork2013年04月09日 08:45:01 +00:00Commented Apr 9, 2013 at 8:45
-
\$\begingroup\$ I think it caught on with me after my recent python project involving re's :) Thanks for pointing it out. \$\endgroup\$abhiram– abhiram2013年04月09日 10:18:49 +00:00Commented Apr 9, 2013 at 10:18
Haskell 48
(\x->x==reverse x).map toLower.filter isAlphaNum
used like this:
(\x->x==reverse x).map toLower.filter isAlphaNum$"Eva, can I stab bats in a cave?"
Smalltalk, Squeak/Pharo flavour
116 chars using traditional formatting with tabs
You add two methods to String:
selffles
^self = self reverse
isPalindrome
^(self asUppercase asDecomposedUnicode select: #isAlphaNumeric) selffles
We could of course eliminate some spaces, or use shorter method names, but let's not betray the spirit of Smalltalk.
More over, this will handle French palindromes, like in http://fr.wikipedia.org/wiki/Liste_de_palindromes_fran%C3%A7ais, not many answers in this page can.
['Léon a trop par rapport à Noël' isPalindrome] assert.
-
\$\begingroup\$ Clever and useful answer! \$\endgroup\$Andrew Gray– Andrew Gray2013年04月17日 18:31:43 +00:00Commented Apr 17, 2013 at 18:31
Python 3 (51 char)
and may be Python 2
based on abhiram solution (with more agressive golfing)
from re import findall
def palindrome(i):
i=findall('[a-z\d]',i.lower())
return i==i[::-1]
print(palindrome(input('Phrase: ')))
may be shortened to 46 chars, using RE '\w'
and variant with extremely shortened function body (27 chars)
import re
l=str.lower
f=re.compile('[a-z\d]').findall
def palindrome(i):i=f(l(i));return i==i[::-1]
print(palindrome(input('Phrase: ')))
Julia 1.0, 63 bytes
~s=((x=filter(in(['0':'9';'A':'Z']),uppercase(s)))==reverse(x))
Since punctuation is filtered out, "5,000 0.005"
is considered a palindrome.
Windows PowerShell, (削除) 56 (削除ここまで) (削除) 47 (削除ここまで) 45 chars
Updated (see comments), and can remove the brackets around the regex:
($s=$s-replace'\W')-eq(-join$s[$s.length..0])
Original (56)
$s=$s-replace'[^\w]','';$s-eq($s[-1..-$s.length]-join'')
Original Un-golfed:
$s = "Eva, can I stab bats in a cave?"
$s = $s -replace '[^\w]', ''
$rev = $s[-1..-$s.length] -join ''
$s -eq $rev
-
\$\begingroup\$ You can golf this down to 47 chars like this:
($s=$s-replace'[\W]')-eq(-join$s[$s.length..0])
\$\endgroup\$SpellingD– SpellingD2013年11月26日 22:47:48 +00:00Commented Nov 26, 2013 at 22:47 -
\$\begingroup\$ @SpellingD: Nice! I'm new at code golfing, thanks for the improvement \$\endgroup\$goric– goric2013年11月27日 12:59:59 +00:00Commented Nov 27, 2013 at 12:59
-
\$\begingroup\$ you can remove the right parenthesis also:
($s=$s-replace'\W')-eq-join$s[$s.length..0]
. \$\endgroup\$mazzy– mazzy2018年12月10日 13:47:28 +00:00Commented Dec 10, 2018 at 13:47
Pylongolf2, 24 bytes
c╨2"[^a-zA-Z]"-_╨1=~
c
takes the input, ╨2
to convert to lower case.
I then push a regex onto the stack and use -
to remove all non-alphabetical characters in the input.
_
duplicates the input.
╨1
reverses it and =
then compares them.
~
prints the stack in the end which prints either true
or false
.
-
\$\begingroup\$ Does this ignore the punctuation, whitespace and control characters? \$\endgroup\$MickyT– MickyT2016年03月31日 19:05:10 +00:00Commented Mar 31, 2016 at 19:05
-
\$\begingroup\$ My bad, this version does not. I will fix it. \$\endgroup\$user47018– user470182016年03月31日 20:06:17 +00:00Commented Mar 31, 2016 at 20:06
-
\$\begingroup\$ Fixed the problem. \$\endgroup\$user47018– user470182016年03月31日 20:08:03 +00:00Commented Mar 31, 2016 at 20:08
C++, 74 bytes
This code is actually really elegant, and easy to understand (when formatted correctly). I don't believe it's possible to get any shorter in C++, and it doesn't use any standard library functions.
p(auto c){auto e=c;while(*e)++e;--e;while(*e==*c&e>c)--e,++c;return e<=c;}
Example usage:
p("Hello"); //Outputs 0
p(""); //Outputs 1
p("a"); //Outputs 1
p("HellolleH"); //Outputs 1
Nicely formatted version:
p(auto c)
{
auto e=c;
while(*e) ++e;
--e;
while(*e==*c & e>c)--e,++c;
return e<=c;
}
-
1\$\begingroup\$
error: ISO C++ forbids declaration of ‘p’ with no type
your function should have a return type. \$\endgroup\$Karl Napf– Karl Napf2016年11月23日 17:09:05 +00:00Commented Nov 23, 2016 at 17:09 -
\$\begingroup\$ I bet this does not ignore case, whitespace and control characters. \$\endgroup\$Titus– Titus2017年04月04日 23:53:36 +00:00Commented Apr 4, 2017 at 23:53
-
\$\begingroup\$ You can save a character with
while(*++e);
instead ofwhile(*e)++e;
. But as Titus mentioned this answer is invalid. \$\endgroup\$Nick Matteo– Nick Matteo2017年04月25日 17:04:08 +00:00Commented Apr 25, 2017 at 17:04
PHP, (削除) 26 84 80 78 62 (削除ここまで) 63 bytes
<?=strrev($s=strtolower(preg_replace("#\W#","",$argv[1])))==$s;
takes input from first command line argument; prints 1
for truthy, empty string for falsy.
I18n is a littly expansive, as there is no multibyte alternative for strrev
(110 bytes; run with -r
):
preg_match_all("#.#us",$s=strtolower(preg_replace("#\W#u","",$argv[1])),$m);echo$s==join(array_reverse($m[0]);
utf8_strrev blatantly stolen from the PHP manual. You might also want to take a look at this blog post.
-
\$\begingroup\$ Come on Titus... This fails the spec. \$\endgroup\$Christoph– Christoph2017年04月04日 08:04:22 +00:00Commented Apr 4, 2017 at 8:04
-
1\$\begingroup\$ @Christoph Yeah I sometimes should fully read that. Fixed. \$\endgroup\$Titus– Titus2017年04月04日 12:54:59 +00:00Commented Apr 4, 2017 at 12:54
-
\$\begingroup\$ Hm
-R
would cause problems with line breaks in the string to test wouldn't it? From the spec " -R <code> Run PHP <code> for every input line". Moreover<?=strrev($s=strtolower(preg_replace("#\W#","",$argn)))==$s;
would be shorter. \$\endgroup\$Christoph– Christoph2017年04月04日 13:42:56 +00:00Commented Apr 4, 2017 at 13:42 -
1\$\begingroup\$ @Christoph Nice idea, but there is no
$argn
without-R
. \$\endgroup\$Titus– Titus2017年04月04日 14:06:16 +00:00Commented Apr 4, 2017 at 14:06 -
\$\begingroup\$
$argv[1]="O Genie, der Herr ehre dein Ego!"; # :D
\$\endgroup\$Titus– Titus2017年04月05日 00:24:01 +00:00Commented Apr 5, 2017 at 0:24
K (ngn/k), 18 bytes
#|:\(2!"0:a{"')__:
Uses @scrawl's suggestion here to return 1
for palindromes and 2
for non-palindromes. If 1
and 0
are required, the solution can be adjusted by prefixing 1=
.
_:
lowercase the (implicit) input(...)_
filter out values where the code in(...)
returns a non-0 value2!"0:a{"'
do a bins lookup, then mod the result by two; returns0
if the input is within"a"-"z"
or"0"-"9"
and1
otherwise
|:\
set up a converge-scan, reversing the input until the original input is returned. on palindromes, returns a one-item list; on non-palindromes, a two-item list#
take the count of the result from above. As noted, if a strict1
and0
output are required for palindrome/non-palindrome, prefix1=
for two bytes
Ruby, 48
p((g=gets.upcase.gsub /[^A-Z\d]/,'')==g.reverse)
Quite simple, and hastily made so not golfed too much. I shall golf it more later.
PowerShell, (削除) 194 (削除ここまで) 190 bytes
A recursive implementation to show how an unnamed PowerShell scriptblock can call itself.
$P={param([string]$s)$s=($s-replace'[^a-z]').tolower();if(!$s){return $true};if($s.length-lt4){return $s[0]-eq$s[-1]};$s[0]-eq$s[-1]-and(&$MyInvocation.MyCommand.ScriptBlock $s.trim($s[0]))}
ungolfed:
$P={
param([string]$s)
$s=($s-replace'[^a-z]').tolower();
if(!$s){return $true};
if($s.length-lt4){return $s[0]-eq$s[-1]};
$s[0]-eq$s[-1]-and(&$MyInvocation.MyCommand.ScriptBlock $s.trim($s[0]))
}
tests:
&$P "Eva, can I stab bats in a cave?"
&$P "Eva, can I stab cats in a cave?"
&$P "A man, a plan, a canal. Panama!"
&$P "A man, a plan, a big shovel, a canal. Panama!"
&$P "Madam, I'm Adam."
&$P "Madam, I'm Adam Corolla."
&$P "757"
&$P "Boeing 757"
-
\$\begingroup\$ Shouldn´t that be
[^a-z0-9]
? \$\endgroup\$Titus– Titus2017年04月04日 23:56:47 +00:00Commented Apr 4, 2017 at 23:56
Explore related questions
See similar questions with these tags.