Palindrome Golf
-
04-07-2019 - |
Pregunta
El objetivo: cualquier idioma. La función más pequeña que devolverá si una cadena es un palíndromo. Aquí está el mío en Python :
R=lambda s:all(a==b for a,b in zip(s,reversed(s)))
50 caracteres.
La respuesta aceptada será la más pequeña actual, esto cambiará a medida que se encuentren las más pequeñas. Especifique el idioma en el que se encuentra su código.
Solución
7 caracteres en J: no estoy seguro de si esta es la mejor manera, soy algo nuevo en J :)
p=:-:|.
explicación: |. invierte la entrada. -: compara. los operandos son implícitos.
p 'radar'
1
p 'moose'
0
Otros consejos
Aquí está el mío; está escrito en un lenguaje específico del dominio que inventé, llamado 'palíndromo'.
p
Editar: Versión menos fluida (i386 asm, sintaxis 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 bytes, el puntero de cadena va en ESI, el resultado está en EAX.
Lamentablemente, no puedo entender menos de mil palabras ...
(LabVIEW. Sí, dejarán que casi cualquier vagabundo publique aquí)
Haskell, 15 caracteres:
p=ap(==)reverse
Versión más legible, 16 caracteres:
p x=x==reverse x
Otra versión de python que es bastante más corta (21 caracteres):
R=lambda s:s==s[::-1]
A riesgo de obtener votos a la baja, la mayoría de estos solo llaman un comando reversa de algún tipo que oculta toda la lógica de programación real.
Me pregunto cuál es la forma manual más corta de hacerlo en cada uno de estos idiomas.
Con los operadores C # y LINQ:
public bool IsPalindrome(string s)
{
return s.Reverse().SequenceEqual(s);
}
Si considera Invertir como trampa, puede hacer todo esto con una reducción:
public bool IsPalindrome(string s)
{
return s.Aggregate(new StringBuilder(),
(sb, c) => sb.Insert(0, c),
(sb) => sb.ToString() == s);
}
Perl (27 caracteres):
sub p{ Perl (27 caracteres):
def p(a)a==a.reverse end
Ruby (24 caracteres):
<*>[0]eq reverse Perl (27 caracteres):
<*>
Ruby (24 caracteres):
<*>[0]}
Ruby (24 caracteres):
<*>73 caracteres limpios y legibles, escritos en java
boolean p(String s){return s.equals(""+new StringBuffer(s).reverse());}
paz :)
Versión de Haskell sin sentido (15 caracteres, aunque en realidad no funciona a menos que incluya Control.Arrow y Control.Monad e ignore la restricción de monomorfismo):
p=ap(==)reverse
Lua apunta más a la legibilidad que a la concisión, pero hace 37 caracteres honestos:
function p(s)return s==s:reverse()end
variante, solo por diversión (mismo tamaño):
p=function(s)return s==s:reverse''end
La versión de JavaScript es más detallada (55 caracteres), porque no tiene una función de cadena inversa:
function p(s){return s==s.split('').reverse().join('')}
(equal p (reverse p))
lisp. 18 caracteres.
ok, este es un caso especial. Esto funcionaría si se escribiera directamente en un intérprete lisp y p ya estuviera definido.
de lo contrario, esto sería necesario:
(defun g () (equal p (reverse p)))
28 caracteres.
Lo llevaré un poco más lejos: código c completo, compilar y listo.
90 caracteres
main(int n,char**v){char*b,*e;b=e=v[1];while(*++e);for(e--;*b==*e&&b++<e--;);return b>e;}
F # (muy parecido al ejemplo de 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, simplemente
$s==strrev($s); // 15 chars
¿No está utilizando un poco la función de reversa en su idioma? Quiero decir, mirando la solución de Ruby da como
def p(a)a==a.reverse end
podría reescribirlo fácilmente como
def p(a)a==a.r end
y simplemente diga que creó un método de extensión en su código para que " r " llamada reversa. Me gustaría ver que las personas publiquen soluciones que no contengan llamadas a otras funciones. Por supuesto, la función de longitud de cadena debe estar permitida.
Ruby sin reversa - 41 caracteres
def m(a)a==a.split('').inject{|r,l|l+r}end
VB.Net - 173 caracteres
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 char
.-1%=
$ echo -n abacaba | ruby golfscript.rb palindrome.gs
1
$ echo -n deadbeef | ruby golfscript.rb palindrome.gs
0
Common Lisp, versión corta y engañosa (23 caracteres):
#L(equal !1(reverse !1))
#L es un carácter macro de lector implementado por SHARPL-READER en el paquete iterado. Es básicamente equivalente a (lambda (! 1) ...).
Common Lisp, versión larga que usa solo primitivos (137 incluyendo espacios en blanco, comprimibles hasta 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)))))))
Una vez más, usa iterar, que es básicamente una versión más limpia de la función LOOP integrada, por lo que tiendo a tratarla como si estuviera en el lenguaje principal.
No es el más corto, y muy posterior al hecho, pero no pude evitar intentarlo en MATLAB:
R=@(s)all(s==fliplr(s));
24 caracteres.
C # Sin función inversa 84 caracteres
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 # Sin función inversa 86 caracteres
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 caracteres
function p:p=s=strreverse(s):end function
Regex de Perl de 18 caracteres
/^(.?|(.)(?1)\2)$/
52 caracteres en C, con la advertencia de que hasta la mitad de la cadena se sobrescribirá:
p (char * s) {return! * s ||! (s [strlen (s) -1] - = * s) & amp; & amp; p (++ s);}
Sin llamadas de la biblioteca son 64 caracteres:
p (char * s) {char * e = s; while (* e) ++ e; return! * s ||! (* - e - = * s) & amp; & amp; p (++ s);}
Inspirado en la publicación anterior, 69 caracteres
p(char*a){char*b=a,q=0;while(*++b);while(*a)q|=*a++!=*--b;return!q;}
EDITAR: Abajo un personaje:
p(char*a){char*b=a,q=0;while(*++b);while(*a)q|=*a++%*--b;return!q;}
EDIT2: 65 caracteres:
p(char*a){char*b=a;while(*b)b++;while(*a&&*a++==*--b);return!*a;}
Haskell, 28 caracteres, necesita ser importada Control.Rrow.
p=uncurry(==).(id&&&reverse)
Implementación directa en C mediante funciones de biblioteca estándar, inspiradas en el strlen en la otra respuesta en C
Número de caracteres: 57
p(char*s){char*r=strdup(s);strrev(r);return strcmp(r,s);}
Confesión: estoy siendo el chico malo al no liberar a r aquí. Mi intento actual de ser bueno:
p(char*s){char*r=strdup(s);s[0]=strcmp(strrev(r),s);free(r);return s[0];}
lo lleva a 73 caracteres; Estoy pensando en alguna forma de hacerlo más corto.
Clojure usando 37 caracteres:
user=> (defn p[s](=(seq s)(reverse(seq s))))
#'user/p
user=> (p "radar")
true
user=> (p "moose")
false
24 caracteres en Perl.
sub p{ 24 caracteres en Perl.
<*>[0]eq+reverse@_}
Groovy 17B:
p={it==it[-1..0?}
El inconveniente es que no funciona con una cadena de caracteres.
Pensándolo bien, lanzar una excepción para una cadena vacía es razonable, ya que no se puede saber si nada es palíndromo o no.
Sin usar ninguna función de la biblioteca (porque también debería agregar el costo de #include
), aquí hay una versión de C ++ en 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);}
Mi intento en C (70 caracteres):
P(char*s){char*e=s+strlen(s)-1;while(s<e&&*s==*e)s++,e--;return s>=e;}
[Editar] Ahora realmente funciona
[Edición 2] Reducido de 74 a 70 mediante el uso de int int predeterminado
En respuesta a algunos de los comentarios: no estoy seguro de si ese abuso del preprocesador cuenta, simplemente puede definirlo todo en la línea de comandos y hacer que la función sea de un solo carácter.