Golf Palindrome
-
04-07-2019 - |
Question
L'objectif: n'importe quelle langue. La plus petite fonction qui retournera si une chaîne est un palindrome. Voici le mien dans Python :
R=lambda s:all(a==b for a,b in zip(s,reversed(s)))
50 caractères.
La réponse acceptée sera la plus petite actuelle - elle changera à mesure que les plus petites seront trouvées. Spécifiez la langue de votre code.
La solution
7 caractères dans J: Pas sûr que ce soit la meilleure façon, je suis un peu nouveau dans J:)
p=:-:|.
explication: |. inverse l'entrée. -: compare. les opérandes sont implicites.
p 'radar'
1
p 'moose'
0
Autres conseils
Voici le mien; il est écrit dans un langage spécifique au domaine que j'ai inventé, appelé "palindrome".
p
Modifier: Version moins glissante (syntaxe asm, AT & 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 octets, le pointeur de chaîne passe dans ESI, le résultat est dans EAX.
Malheureusement, je suis incapable d'obtenir moins de mille mots ...
(LabVIEW. Ouais, ils laisseront à peu près n'importe quel post hobo ici;)
Haskell, 15 caractères:
p=ap(==)reverse
Version plus lisible, 16 caractères:
p x=x==reverse x
Une autre version python plutôt courte (21 caractères):
R=lambda s:s==s[::-1]
Au risque d'obtenir des votes négatifs, la plupart d'entre eux appellent simplement une commande reverse qui masque toute la logique de programmation réelle.
Je me demande quel est le moyen manuel le plus court de procéder dans chacune de ces langues.
Avec les opérateurs C # et LINQ:
public bool IsPalindrome(string s)
{
return s.Reverse().SequenceEqual(s);
}
Si vous considérez l'inverse comme de la triche, vous pouvez le faire entièrement avec une réduction:
public bool IsPalindrome(string s)
{
return s.Aggregate(new StringBuilder(),
(sb, c) => sb.Insert(0, c),
(sb) => sb.ToString() == s);
}
Perl (27 caractères):
sub p{ Perl (27 caractères):
def p(a)a==a.reverse end
Ruby (24 caractères):
<*>[0]eq reverse Perl (27 caractères):
<*>
Ruby (24 caractères):
<*>[0]}
Ruby (24 caractères):
<*>73 propres, lisibles, caractères écrits en java
boolean p(String s){return s.equals(""+new StringBuffer(s).reverse());}
paix :)
Version sans objet de Haskell (15 caractères, bien que cela ne fonctionne vraiment que si vous incluez Control.Arrow et Control.Monad et ignorez la restriction de monomorphisme):
p=ap(==)reverse
Lua vise plus la lisibilité que la concision, mais fait honnêtement 37 caractères:
function p(s)return s==s:reverse()end
variante, juste pour le plaisir (même taille):
p=function(s)return s==s:reverse''end
La version JavaScript est plus détaillée (55 caractères), car elle n’a pas de fonction inverse de chaîne:
function p(s){return s==s.split('').reverse().join('')}
(equal p (reverse p))
lisp. 18 caractères.
ok, c’est un cas spécial. Cela fonctionnerait si vous tapiez directement dans un interpréteur lisp et que p était déjà défini.
sinon, cela serait nécessaire:
(defun g () (equal p (reverse p)))
28 caractères.
Je vais aller un peu plus loin: code complet, compiler et continuer.
90 caractères
main(int n,char**v){char*b,*e;b=e=v[1];while(*++e);for(e--;*b==*e&&b++<e--;);return b>e;}
F # (un peu comme dans l'exemple 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
ou juste
$s==strrev($s); // 15 chars
L’utilisation de la fonction inverse dans votre langue n’est-elle pas un peu trompeuse? Je veux dire, en regardant la solution Ruby donner comme
def p(a)a==a.reverse end
vous pouvez facilement réécrire cela comme
def p(a)a==a.r end
et dites simplement que vous avez créé une méthode d’extension dans votre code afin que " r " appelé inverse. J'aimerais que les gens publient des solutions qui ne contiennent pas d'appels vers d'autres fonctions. Bien entendu, la fonction de longueur de chaîne devrait être autorisée.
Ruby sans inversion - 41 caractères
def m(a)a==a.split('').inject{|r,l|l+r}end
VB.Net - 173 caractères
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 caractères
.-1%=
$ echo -n abacaba | ruby golfscript.rb palindrome.gs
1
$ echo -n deadbeef | ruby golfscript.rb palindrome.gs
0
Common Lisp, version courte et trompeuse (23 caractères):
#L(equal !1(reverse !1))
#L est un caractère de macro lecteur implémenté par SHARPL-READER dans le package iterate. C'est fondamentalement équivalent à (lambda (! 1) ...).
Common Lisp, version longue utilisant uniquement des primitives (137, y compris les espaces, compressible jusqu’à 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)))))))
Encore une fois, il utilise iterate, qui est fondamentalement une version plus propre de la fonctionnalité LOOP intégrée, donc j'ai tendance à le traiter comme étant dans le langage principal.
Ce n'est pas le plus court, et très après-coup, mais je ne pouvais pas m'empêcher de l'essayer dans MATLAB:
R=@(s)all(s==fliplr(s));
24 caractères.
C # Sans fonction inverse : 84 caractères
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 # Sans fonction inverse , 86 caractères
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 caractères
function p:p=s=strreverse(s):end function
regex Perl à 18 caractères
/^(.?|(.)(?1)\2)$/
52 caractères en C, avec l'avertissement que jusqu'à la moitié de la chaîne sera écrasée:
p (car * s) {return! * s ||! (s [strlen (s) -1] - = * s) & amp; & amp; p (++ s);}
Sans appel de la bibliothèque, il comporte 64 caractères:
p (car * s) {car * e = s; tandis que (* e) ++ e; renvoyer! * s ||! (* - e - = * s) & amp; & amp; p (++ s);}
Inspiré du post précédent, 69 caractères
p(char*a){char*b=a,q=0;while(*++b);while(*a)q|=*a++!=*--b;return!q;}
EDIT: un caractère en bas:
p(char*a){char*b=a,q=0;while(*++b);while(*a)q|=*a++%*--b;return!q;}
EDIT2: 65 caractères:
p(char*a){char*b=a;while(*b)b++;while(*a&&*a++==*--b);return!*a;}
Haskell, 28 caractères, nécessite l’importation de Control.Arrow.
p=uncurry(==).(id&&&reverse)
Implémentation simple en C à l’aide de fonctions de bibliothèque standard, inspirée du strlen de l’autre réponse en C.
Nombre de caractères: 57
p(char*s){char*r=strdup(s);strrev(r);return strcmp(r,s);}
Confession: Je suis le méchant en ne libérant pas ici. Ma tentative actuelle d’être bonne:
p(char*s){char*r=strdup(s);s[0]=strcmp(strrev(r),s);free(r);return s[0];}
l'amène à 73 caractères; Je pense aux moyens de le faire plus court.
Clojure utilisant 37 caractères:
user=> (defn p[s](=(seq s)(reverse(seq s))))
#'user/p
user=> (p "radar")
true
user=> (p "moose")
false
24 caractères en Perl.
sub p{ 24 caractères en Perl.
<*>[0]eq+reverse@_}
Groovy 17B:
p = {it == ce [-1..0]}
L'inconvénient est qu'il ne fonctionne pas avec une chaîne emptry.
À bien y penser, il est raisonnable de faire une exception pour une chaîne vide, car vous ne pouvez pas savoir si rien n'est palindrome ou non.
Sans utiliser aucune fonction de bibliothèque (car vous devez également ajouter le coût #include
), voici une version C ++ dans 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);}
Ma tentative en C (70 caractères):
P(char*s){char*e=s+strlen(s)-1;while(s<e&&*s==*e)s++,e--;return s>=e;}
[Modifier] Maintenant en train de travailler
[Edit 2] Réduit de 74 à 70 en utilisant le retour int par défaut
En réponse à certains commentaires: je ne suis pas sûr que l'abus du préprocesseur compte - vous pouvez simplement définir le tout dans la ligne de commande et définir la fonction sur un caractère.