Palindrome Golf
-
04-07-2019 - |
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.
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 ...
(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.