Palindrome Golf

2019-01-30 05:37发布

问题:

The goal: Any language. The smallest function which will return whether a string is a palindrome. Here is mine in Python:

R=lambda s:all(a==b for a,b in zip(s,reversed(s)))

50 characters.

The accepted answer will be the current smallest one - this will change as smaller ones are found. Please specify the language your code is in.

回答1:

7 characters in J: Not sure if this is the best way, I'm somewhat new to J :)

p=:-:|.

explanation: |. reverses the input. -: compares. the operands are implicit.

p 'radar'
1

p 'moose'
0


回答2:

Here's mine; it's written in a domain-specific language I invented, called 'palindrome'.

p

Edit: Less flippant version (i386 asm, AT&T syntax)

xor %eax, %eax
mov %esi, %edi
#cld    not necessary, assume DF=0 as per x86 ABI
repne scasb
scan:
    dec %edi
    cmpsb
    .byte 0x75, 6    #jnz (short) done
    dec %edi
    cmp %esi, %edi
    .byte 0x72, -9    #jb (short) scan
inc %eax
done:

16 bytes, string pointer goes in ESI, result is in EAX.



回答3:

Sadly, I'm unable to get under a thousand words...

(LabVIEW. Yeah, they'll let just about any hobo post here ;)



回答4:

Haskell, 15 chars:

p=ap(==)reverse

More readable version, 16 chars:

p x=x==reverse x


回答5:

Another python version that is rather shorter (21 chars):

R=lambda s:s==s[::-1]


回答6:

At the risk of getting down votes, most all of these just call a command reverse of some sort that hides all the real programming logic.

I wonder what the shortest manual way to do this is in each of these languages.



回答7:

With C# and LINQ operators:

public bool IsPalindrome(string s)
{
    return s.Reverse().SequenceEqual(s);
}

If you consider Reverse as cheating, you can do the entire thing with a reduction:

public bool IsPalindrome(string s)
{
    return s.Aggregate(new StringBuilder(),
                       (sb, c) => sb.Insert(0, c),
                       (sb) => sb.ToString() == s);
}


回答8:

Perl (27 chars):

sub p{$_[0]eq reverse$_[0]}

Ruby (24 chars):

def p(a)a==a.reverse end


回答9:

73 clean, readable, chars written in java

boolean p(String s){return s.equals(""+new StringBuffer(s).reverse());}

peace :)



回答10:

Pointless Haskell version (15 chars, though doesn't really work unless you include Control.Arrow and Control.Monad and ignore the monomorphism restriction):

p=ap(==)reverse


回答11:

Lua aims more at readability than conciseness, yet does an honest 37 chars:

function p(s)return s==s:reverse()end

variant, just for fun (same size):

p=function(s)return s==s:reverse''end

The JavaScript version is more verbose (55 chars), because it doesn't has a string reverse function:

function p(s){return s==s.split('').reverse().join('')}


回答12:

(equal p (reverse p))

lisp. 18 characters.

ok, this is a special case. This would work if typed directly into a lisp interpreter and p was already defined.

otherwise, this would be necessary:

(defun g () (equal p (reverse p)))

28 characters.



回答13:

I'll take it a little bit further: full c code, compile and go.

90 characters

main(int n,char**v){char*b,*e;b=e=v[1];while(*++e);for(e--;*b==*e&&b++<e--;);return b>e;}


回答14:

F# (a lot like the C# example)

let p s=let i=0;let l=s.Length;while(++i<l)if(s[i]!=[l-i-1]) 0; 1;;


回答15:

PHP:

function p($s){return $s==strrev($s);} // 38 chars

or, just

$s==strrev($s); // 15 chars


回答16:

Isn't using the reverse function in your language kind of cheating a bit? I mean, looking at the Ruby solution give as

def p(a)a==a.reverse end

you could easily rewrite that as

def p(a)a==a.r end

and just say that you made an extension method in your code so that "r" called reverse. I'd like to see people post solutions that don't contain calls to other functions. Of course, the string length function should be permitted.

Ruby without reverse - 41 characters

def m(a)a==a.split('').inject{|r,l|l+r}end

VB.Net - 173 Chars

Function P(ByVal S As String) As Boolean
    For i As Integer = 0 To S.Length - 1
        If S(i) <> S(S.Length - i - 1) Then
            Return False
        End If
    Next
    Return True
End Function


回答17:

Golfscript, 5 char

.-1%=

$ echo -n abacaba | ruby golfscript.rb palindrome.gs
1

$ echo -n deadbeef | ruby golfscript.rb palindrome.gs
0


回答18:

Common Lisp, short-and-cheating version (23 chars):

#L(equal !1(reverse !1))

#L is a reader macro character implemented by SHARPL-READER in the iterate package. It's basically equivalent to (lambda (!1) ...).

Common Lisp, long version using only primitives (137 including whitespace, compressible down to 108):

(defun p (s)
  (let ((l (1- (length s))))
    (iter (for i from l downto (/ l 2))
          (always (equal (elt s i) (elt s (- l i)))))))

Again, it uses iterate, which is basically a cleaner version of the builtin LOOP facility, so I tend to treat it as being in the core language.



回答19:

Not the shortest, and very after-the-fact, but I couldn't help giving it a try in MATLAB:

R=@(s)all(s==fliplr(s));

24 chars.



回答20:

C# Without Reverse Function 84 chars

int p(char[]s){int i=0,l=s.Length,t=1;while(++i<l)if(s[i]!=s[l-i-1])t&=0;return t;} 

C# Without Reverse Function 86 chars

int p(char[]s){int i=0;int l=s.Length;while(++i<l)if(s[i]!=s[l-i-1])return 0;return 1;}

VBScript 41 chars

function p:p=s=strreverse(s):end function


回答21:

18 character perl regex

/^(.?|(.)(?1)\2)$/


回答22:

52 characters in C, with the caveat that up to half the string will be overwritten:

p(char*s){return!*s||!(s[strlen(s)-1]-=*s)&&p(++s);}

Without library calls it's 64 characters:

p(char*s){char*e=s;while(*e)++e;return!*s||!(*--e-=*s)&&p(++s);}



回答23:

Inspired by previous post, 69 characters

p(char*a){char*b=a,q=0;while(*++b);while(*a)q|=*a++!=*--b;return!q;}

EDIT: Down one char:

p(char*a){char*b=a,q=0;while(*++b);while(*a)q|=*a++%*--b;return!q;}

EDIT2: 65 chars:

p(char*a){char*b=a;while(*b)b++;while(*a&&*a++==*--b);return!*a;}


回答24:

Haskell, 28 chars, needs Control.Arrow imported.

p=uncurry(==).(id&&&reverse)


回答25:

Straightforward implementation in C using standard library functions, inspired by the strlen in the other C answer.

Number of characters: 57

p(char*s){char*r=strdup(s);strrev(r);return strcmp(r,s);}

Confession: I'm being the bad guy by not freeing r here. My current attempt at being good:

p(char*s){char*r=strdup(s);s[0]=strcmp(strrev(r),s);free(r);return s[0];}

brings it to 73 characters; I'm thinking of any ways to do it shorter.



回答26:

Clojure using 37 characters:

user=> (defn p[s](=(seq s)(reverse(seq s))))
#'user/p
user=> (p "radar")
true
user=> (p "moose")
false


回答27:

24 characters in Perl.

sub p{$_[0]eq+reverse@_}


回答28:

Groovy 17B:

p={it==it[-1..0]}

Downside is that it doesn't work with emptry string.

On second thought, throwing exception for empty string is reasonable since you can't tell if nothing is palindrome or not.



回答29:

Without using any library functions (because you should really add in the #include cost as well), here's a C++ version in 96:

int p(char*a,char*b=0,char*c=0){return c?b<a||p(a+1,--b,c)&&*a==*b:b&&*b?p(a,b+1):p(a,b?b:a,b);}


回答30:

My attempt in C (70 chars):

P(char*s){char*e=s+strlen(s)-1;while(s<e&&*s==*e)s++,e--;return s>=e;}

[Edit] Now actually working
[Edit 2] Reduced from 74 to 70 by using default int return

In response to some of the comments: I'm not sure if that preprocessor abuse counts - you could just define the whole thing on the command line and make the function one character.