Domanda

L'obiettivo: qualsiasi lingua. La funzione più piccola che restituirà se una stringa è un palindromo. Ecco il mio in Python :

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

50 caratteri.

La risposta accettata sarà la più piccola corrente - questo cambierà man mano che vengono trovate quelle più piccole. Specifica la lingua in cui si trova il tuo codice.

È stato utile?

Soluzione

7 personaggi in J: Non sono sicuro che sia il modo migliore, sono un po 'nuovo in J :)

p=:-:|.

spiegazione: |. inverte l'input. -: confronta. gli operandi sono impliciti.

p 'radar'
1

p 'moose'
0

Altri suggerimenti

Ecco il mio; è scritto in una lingua specifica del dominio che ho inventato, chiamato "palindrome".

p

Modifica: versione meno fluttuante (i386 asm, sintassi AT & amp; T)

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 byte, il puntatore di stringa va in ESI, il risultato è in EAX.

Purtroppo, non riesco a capire più di mille parole ...

alt text

(LabVIEW. Sì, lasceranno praticamente qualsiasi post hobo qui;)

Haskell, 15 caratteri:

p=ap(==)reverse

Versione più leggibile, 16 caratteri:

p x=x==reverse x

Un'altra versione di Python piuttosto corta (21 caratteri):

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

A rischio di ottenere voti bassi, la maggior parte di questi semplicemente chiama un comando reverse di qualche tipo che nasconde tutta la vera logica di programmazione.

Mi chiedo quale sia il modo manuale più breve per farlo in ciascuna di queste lingue.

Con operatori C # e LINQ:

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

Se consideri Reverse come un imbroglio, puoi fare tutto con una riduzione:

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

Perl (27 caratteri):

sub p{

Perl (27 caratteri):

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

Ruby (24 caratteri):

<*>[0]eq reverse

Perl (27 caratteri):

<*>

Ruby (24 caratteri):

<*>[0]}

Ruby (24 caratteri):

<*>

73 caratteri puliti, leggibili, scritti in java

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

pace :)

Versione inutile di Haskell (15 caratteri, anche se in realtà non funziona se non includi Control.Arrow e Control.Monad e ignori la limitazione del monomorfismo):

p=ap(==)reverse

Lua punta più alla leggibilità che alla concisione, eppure ha 37 caratteri onesti:

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

variante, solo per divertimento (stessa dimensione):

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

La versione JavaScript è più dettagliata (55 caratteri), perché non ha una funzione inversa stringa:

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

Lisp. 18 caratteri.

ok, questo è un caso speciale. Funzionerebbe se digitato direttamente in un interprete lisp e p fosse già definito.

altrimenti, ciò sarebbe necessario:

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

28 caratteri.

Lo porterò un po 'oltre: codice c completo, compilazione e via.

90 caratteri

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

F # (molto simile all'esempio C #)

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

PHP:

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

o, solo

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

Non stai usando un po 'la funzione inversa nella tua lingua? Voglio dire, guardando la soluzione di Ruby come

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

potresti facilmente riscriverlo come

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

e dì solo che hai creato un metodo di estensione nel tuo codice in modo che " r " chiamato reverse. Mi piacerebbe vedere le persone pubblicare soluzioni che non contengono chiamate ad altre funzioni. Naturalmente, la funzione di lunghezza della stringa dovrebbe essere consentita.

Rubino senza retromarcia - 41 caratteri

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

VB.Net - 173 caratteri

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

Golfscript, 5 caratteri

.-1%=

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

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

Lisp comune, versione abbreviata (23 caratteri):

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

#L è un carattere macro del lettore implementato da SHARPL-READER nel pacchetto iterato. È sostanzialmente equivalente a (lambda (! 1) ...).

Common Lisp, versione lunga che utilizza solo primitive (137 inclusi gli spazi bianchi, comprimibile fino a 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)))))))

Ancora una volta, utilizza iterate, che è fondamentalmente una versione più pulita della funzione LOOP integrata, quindi tendo a trattarlo come nel linguaggio principale.

Non il più breve e molto preciso, ma non ho potuto fare a meno di provarlo in MATLAB:

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

24 caratteri.

C # Senza funzione inversa 84 caratteri

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 # Senza funzione inversa 86 caratteri

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;}

Caratteri VBScript 41

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

18 caratteri perl regex

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

52 caratteri in C, con l'avvertenza che fino a metà della stringa verrà sovrascritta:

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

Senza chiamate in libreria ha 64 caratteri:

p (char * s) {char * e = s; mentre (* e) ++ e; ritorno * s || (* - e - = * s) & amp;!! & Amp; p (++ s);}

Ispirato al post precedente, 69 caratteri

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

EDIT: giù di un carattere:

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

EDIT2: 65 caratteri:

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

Haskell, 28 caratteri, necessita di Control.Arrow importato.

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

Implementazione semplice in C usando le funzioni standard delle librerie, ispirata alle restrizioni nell'altra risposta C.

Numero di caratteri: 57

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

Confessione: sto diventando il cattivo non liberando r qui. Il mio attuale tentativo di essere buono:

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

lo porta a 73 caratteri; Sto pensando a modi per farlo più breve.

Clojure usando 37 caratteri:

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

24 caratteri in Perl.

sub p{

24 caratteri in Perl.

<*>[0]eq+reverse@_}

Groovy 17B:

  

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

Il rovescio della medaglia è che non funziona con una stringa emptry.

Ripensandoci, è ragionevole gettare un'eccezione per stringa vuota poiché non si può dire se nulla è palindromo o meno.

Senza usare alcuna funzione di libreria (perché dovresti davvero aggiungere anche il costo #include ), ecco una versione C ++ 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);}

Il mio tentativo in C (70 caratteri):

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

[Modifica] Ora funziona davvero
[Modifica 2] Ridotto da 74 a 70 utilizzando int restituito di default

In risposta ad alcuni dei commenti: non sono sicuro che l'abuso del preprocessore conti: potresti semplicemente definire tutto sulla riga di comando e rendere la funzione un carattere.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top