Tuve la idea espontánea de hacer una serie de desafíos de usuarios que han ayudado y continúan ayudando a la comunidad PPCG a ser un lugar agradable para todos, o tal vez solo específicamente para mí. :PAGS
Si convierte el nombre de Dennis en una matriz de 1
sys 0
donde está cada consonante 1
y cada vocal es 0
, la matriz es [1, 0, 1, 1, 0, 1]
, que es simétrica. Por lo tanto, su desafío es determinar qué otros nombres son así.
Desafío
Dada una cadena ASCII, elimine todos los caracteres que no sean letras y determine si la configuración de vocales y consonantes es simétrica. y
No es una vocal.
Tenga en cuenta que su programa no tiene que ser este tipo de cadena en sí.
Casos de prueba
Dennis -> truthy
Martin -> truthy
Martin Ender -> truthy
Alex -> falsy
Alex A. -> truthy
Doorknob -> falsy
Mego -> falsy
Implementación de referencia
Este código de Python 3 dará el resultado correcto dado un caso de prueba. Es tan poco gélido como podría hacerlo sin ser ridículo.
Python 3
s = input()
l = []
for c in s:
if c in 'AEIOUaeiou':
l.append(0)
elif c in 'BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz':
l.append(1)
print(l == list(reversed(l)), end = '')
fuente
Respuestas:
05AB1E , 9 bytes
Pruébalo en línea!
-2 gracias a Adnan .
Esto ataca el punto de dolor de Jelly exactamente. Utiliza
l
yA
, equivalentes de 1 byte para Jelly'sŒl
yØa
respectivamente.fuente
AÃ
porá
y pocoDR
a pocoÂ
.á
, no sabía lo queÂ
hace, gracias!00
queFF
a esos 256 caracteres, véase la respuesta de jaleaJalea , 11 bytes
Pruébalo en línea!
Versiones alternativas:
Por supuesto, un desafío para apreciar a Dennis debe tener una respuesta en un idioma suyo.
fuente
x86 función de código de máquina de 32 bits,
4241 bytesActualmente, la respuesta más corta en lenguaje no relacionado con el golf, 1B más corta que @ streetster's q / kdb + .
Con 0 para verdadero y no cero para falso:
4140 bytes. (en general, guarda 1 byte para 32 bits, 2 bytes para 64 bits).Con cadenas de longitud implícita (estilo C con terminación 0):
4544 bytesCódigo de máquina x86-64 (con punteros de 32 bits, como el x32 ABI):
4443 bytes .x86-64 con cadenas de longitud implícita, todavía 46 bytes (la estrategia de mapa de bits de desplazamiento / máscara es equilibrada ahora).
Esta es una función con C firma
_Bool dennis_like(size_t ecx, const char *esi)
. La convención de llamada es ligeramente no estándar, cercana a MS vectorcall / fastcall pero con diferentes registros arg: cadena en ESI y la longitud en ECX. Solo registra sus argumentos arg y EDX. AL contiene el valor de retorno, con los bytes altos que contienen basura (según lo permitido por las ABI S86 x86 y x32. IDK lo que dicen las ABI de MS sobre la basura alta al devolver bool o enteros estrechos).Explicación del algoritmo. :
Pase por la cadena de entrada, filtre y clasifique en una matriz booleana en la pila: para cada byte, verifique si es un carácter alfabético (si no, continúe con el siguiente carácter) y transfórmelo en un entero de 0-25 (AZ) . Use ese entero 0-25 para verificar un mapa de bits de vocal = 0 / consonante = 1. (El mapa de bits se carga en un registro como una constante inmediata de 32 bits). Empuje 0 o 0xFF en la pila de acuerdo con el resultado del mapa de bits (en realidad en el byte bajo de un elemento de 32 bits, que puede tener basura en los 3 bytes superiores).
El primer bucle produce una matriz de 0 o 0xFF (en elementos dword rellenados con basura). Realice la comprobación de palíndromo habitual con un segundo bucle que se detiene cuando los punteros se cruzan en el medio (o cuando ambos apuntan al mismo elemento si hubiera un número impar de caracteres alfabéticos). El puntero que se mueve hacia arriba es el puntero de la pila, y usamos POP para cargar + incrementar. En lugar de comparar / establecer cc en este bucle, podemos usar XOR para detectar lo mismo / diferente ya que solo hay dos valores posibles. Podríamos acumular (con OR) si encontramos elementos que no coinciden, pero una ramificación temprana en las banderas establecidas por XOR es al menos igual de buena.
Observe que el segundo bucle usa
byte
el tamaño de operando, por lo que no le importa qué basura deja el primer bucle fuera del byte bajo de cada elemento de la matriz.Utiliza la instrucción no documentada
salc
para establecer AL desde CF, de la misma manera que losbb al,al
haría. Es compatible con todas las CPU Intel (excepto en el modo de 64 bits), ¡incluso Knight's Landing! Agner Fog enumera los tiempos para ello en todas las CPU AMD (incluida Ryzen), por lo que si los proveedores de x86 insisten en vincular ese byte de espacio de código de operación desde 8086, también podríamos aprovecharlo.Trucos interesantes:
bt
, inspirado en una buena salida del compilador paraswitch
.stosb
.cmp
/salc
no es una opción, porquesalc
solo funciona para CF, y 0xFF-0 no establece CF.sete
es de 3 bytes, pero evitaría elinc
exterior del bucle, por un costo neto de 2 bytes (1 en modo de 64 bits )) vs.xor en el bucle y arreglarlo con inc.Esta es probablemente también una de las respuestas más rápidas, ya que ninguno de los juegos de golf realmente duele demasiado, al menos para cadenas de menos de unos pocos miles de caracteres donde el uso de memoria 4x no causa muchos errores de caché. (También puede ser que pierda a las respuestas que tienen un temprano de salida para la no-Dennis como cuerdas antes de bucle sobre todos los caracteres.)
salc
Es más lenta quesetcc
en muchas CPU (por ejemplo, 3 uops vs 1 en Skylake), pero con un control de mapa de bitsbt/salc
sigue siendo más rápido que una búsqueda de cadenas o una coincidencia de expresiones regulares. Y no hay gastos generales de inicio, por lo que es extremadamente barato para cadenas cortas.Hacerlo de una vez sobre la marcha significaría repetir el código de clasificación para las direcciones arriba y abajo. Eso sería más rápido pero de mayor tamaño de código. (Por supuesto, si quiere rápido, puede hacer 16 o 32 caracteres a la vez con SSE2 o AVX2, aún utilizando el truco de comparación cambiando de rango al final del rango firmado).
Probar el programa (para ia32 o x32 Linux) para llamar a esta función con un cmdline arg, y salir con status = valor de retorno.
strlen
implementación de int80h.org .Se podría usar una versión de 64 bits de esta función
sbb eax,eax
, que es solo 2 bytes en lugar de 3 parasetc al
. También necesitaría un byte adicional paradec
onot
al final (porque solo 32 bits tiene 1 byte inc / dec r32). Usando el x32 ABI (punteros de 32 bits en modo largo), aún podemos evitar los prefijos REX a pesar de que copiamos y comparamos punteros.setc [rdi]
puede escribir directamente en la memoria, pero reservar bytes ECX de espacio de pila cuesta más tamaño de código que el que ahorra. (Y tenemos que movernos a través de la matriz de salida.[rdi+rcx]
Toma un byte adicional para el modo de direccionamiento, pero realmente necesitamos un contador que no se actualice para los caracteres filtrados, por lo que será peor que eso).Esta es la fuente YASM / NASM con
%if
condicionales. Se puede construir con-felf32
(código de 32 bits) o-felfx32
( código de 64 bits con x32 ABI), y con una longitud implícita o explícita . He probado las 4 versiones. Vea esta respuesta para un script para construir un binario estático a partir de la fuente NASM / YASM.Para probar la versión de 64 bits en una máquina sin soporte para el x32 ABI, puede cambiar los registros del puntero a 64 bits. (Luego, simplemente reste el número de prefijos REX.W = 1 (0x48 bytes) del recuento. En este caso, 4 instrucciones necesitan prefijos REX para operar en registros de 64 bits). O simplemente llámelo con el
rsp
puntero de entrada y en el bajo 4G del espacio de direcciones.Miré a jugar con DF (la bandera de dirección que controla
lodsd
/scasd
y así sucesivamente), pero simplemente no parecía ser una victoria. Las ABI habituales requieren que el DF se borre al entrar y salir de la función. Suponiendo que esté despejado en la entrada, pero dejarlo configurado en la salida sería una trampa, en mi opinión. Sería bueno usar LODSD / SCASD para evitar los 3 bytessub esi, 4
, especialmente en el caso de que no haya mucha basura.Estrategia de mapa de bits alternativa (para cadenas de longitud implícita x86-64)
Resulta que esto no guarda ningún byte, porque
bt r32,r32
aún funciona con mucha basura en el índice de bits. Simplemente no está documentado comoshr
está.En lugar de
bt / sbb
obtener el bit dentro / fuera de CF, use un desplazamiento / máscara para aislar el bit que queremos del mapa de bits.Como esto produce 0/1 en AL al final (en lugar de 0 / 0xFF), podemos hacer la inversión necesaria del valor de retorno al final de la función con
xor al, 1
(2B) en lugar dedec eax
(también 2B en x86-64) para todavía produce un valor apropiadobool
/ de_Bool
retorno.Esto solía guardar 1B para x86-64 con cadenas de longitud implícita, al evitar la necesidad de poner a cero los bytes altos de EAX. (Había estado usando
and eax, 0x7F ^ 0x20
para forzar a mayúsculas y poner a cero el resto de eax con un byte de 3 bytesand r32,imm8
. Pero ahora estoy usando la codificación de 2 byte de inmediato con AL que tienen la mayoría de las instrucciones 8086, como ya lo estaba haciendo para elsub
ycmp
.)Pierde en
bt
/salc
en modo de 32 bits, y las cadenas de longitud explícita necesitan ECX para el recuento, por lo que tampoco funciona allí.Pero luego me di cuenta de que estaba equivocado:
bt edx, eax
todavía funciona con mucha basura en eax. Aparentemente enmascara el turno de contar la misma manera queshr r32, cl
lo hace (mirar sólo a los 5 bits bajas de Cl). Esto es diferente debt [mem], reg
, que puede acceder fuera de la memoria a la que hace referencia el modo / tamaño de direccionamiento, tratándolo como una cadena de bits. (Crazy CISC ...)El manual de referencia de Intel Insn Set no documenta el enmascaramiento, por lo que tal vez sea el comportamiento indocumentado lo que Intel está preservando por ahora. (Ese tipo de cosas no es infrecuente.
bsf dst, src
Con src = 0 siempre deja dst sin modificar, aunque está documentado que deja dst con un valor indefinido en ese caso. AMD en realidad documenta el comportamiento src = 0). Probé en Skylake y Core2, y labt
versión funciona con basura distinta de cero en EAX fuera de AL.Un buen truco aquí es usar
xchg eax,ecx
(1 byte) para obtener el recuento en CL. Desafortunadamente, BMI2shrx eax, edx, eax
es de 5 bytes, frente a solo 2 bytes parashr eax, cl
. El usobextr
necesita un byte de 2mov ah,1
(para la cantidad de bits a extraer), por lo que nuevamente son 5 + 2 bytes como SHRX + AND.El código fuente se ha vuelto bastante desordenado después de agregar
%if
condicionales. Aquí está el desmontaje de cadenas de longitud implícita x32 (usando la estrategia alternativa para el mapa de bits, por lo que todavía son 46 bytes).La principal diferencia con la versión de longitud explícita está en el primer bucle. Observe cómo hay un
lods
antes, y en la parte inferior, en lugar de solo uno en la parte superior del bucle.fuente
retina ,
49 4745 bytesPruébalo en línea!
Guardado 2 bytes gracias a Neil.
Ahorró otros 2 bytes gracias a Martin.
Elimina las no letras y luego reemplaza las vocales con 1 y las consonantes con 2, para obtener valores consistentes. Luego, elimina repetidamente el primer y el último carácter si son iguales. Una vez que no lo son, la palabra es simétrica si quedan uno o cero caracteres.
fuente
\D
2
Funciona para ahorrarle un par de bytesT`lL`2
?PHP, 82 bytes
Pruébalo en línea!
fuente
(bool)
y eliminar el$s=
y el==$s
cheque para guardar 1 byte.(bool)
con solo0||
decir falso, o ... en cambio, guardar 3 bytes adicionales.\w
para la palabra caracteres en lugar de laa-z
?\w
contiene dígitos subrayados y letras. Esto no funcionará y[^/p{L}]
es más largo como[^a-z]
plus i. Comparo la cadena inversa con la cadena, por lo que$s
es necesaria para crear el booleanoMATL, 14 bytes
Pruébalo en MATL Online .
Aquí hay una versión ligeramente modificada para verificar todos los casos de prueba.
Explicación
fuente
Haskell,
84757469 bytes-10 gracias a @nimi
-5 gracias a @Zgarb
La comprensión de la lista reemplaza cada letra con un booleano y elimina todos los demás caracteres. La primera parte verifica si la lista resultante es o no un palíndromo.
Pruébalo en línea!
fuente
filter
sigue,map
incluso si tiene que cambiar a no poitfree. 2) El<$>id
es superfluo.f x=(==)<*>reverse$[elem c"aeiouAEIOU"|c<-x,c
elem['A'..'Z']++['a'..'z']]
.c
y"
por un byte más.c`elem`['A'..'Z']++['a'..'z']
se puede acortar a'@'<c,c<'{','`'<c||c<'['
Pyth,
1815 bytesPruébalo aquí
-2 gracias a KarlKastor , y posteriormente -1.
fuente
_I/L"aeiou"@Grz0
(utilizando el operador de invariancia I)z
,Brachylog , 13 bytes
Pruébalo en línea!
Explicación
fuente
Alice , 28 bytes
Pruébalo en línea!
Salidas
1
como verdaderas y nada como falsas.Explicación
Cada comando en este programa se ejecuta en modo ordinal, pero con un ligero giro en la plantilla que me permite guardar un byte. Si una nueva línea es un valor de verdad aceptable, puedo guardar un byte más por el mismo método.
Linealizado, el programa es el siguiente:
fuente
Python 3 ,
7271 bytes-1 byte gracias a @ovs
Pruébalo en línea!
fuente
def f(s):s=[c in'AEIOU'for c in s.upper()if'@'<c<'['];return s==s[::-1]
para 71 bytesJavaScript (ES6),
7269 bytesGuardado 3 bytes gracias a Neil
Devuelve un booleano.
Casos de prueba
Mostrar fragmento de código
fuente
2
.+''
al final? Eso ahorraría 3 bytes en su lugar.Mathematica, 113 bytes
fuente
PalindromeQ@StringReplace[#,{Characters@"aeiouAEIOU"->"1",LetterCharacter->"0",_->""}]&
GolfScript , 42 bytes
Pruébalo en línea!
La parte difícil es generar el alfabeto en mayúsculas y minúsculas en una cadena, que usaremos en una función de filtro para filtrar las letras de la entrada. Afortunadamente, dado que las cadenas en GolfScript son solo matrices de puntos de código con una propiedad especial, podemos generar los puntos de código de manera eficiente. Así es como los generamos:
Primero, generamos el rango [0..122], siendo 122 el punto de código para
z
. Luego, tomamos los elementos del elemento en el índice 65 en adelante. 65 es el punto de código paraA
. En este momento, tenemos [65..122]. Todo bien, excepto que tenemos algunos puntos de código no deseados ([91..96]) allí. Entonces, primero hacemos un duplicado de ese rango. Luego, tomamos los elementos del índice 26 en adelante, y tenemos [91..122]. Después de eso, obtenemos los elementos hasta e incluyendo el índice 5. Ahora tenemos [91..96]. Finalmente, eliminamos esos elementos de nuestro [65..122], dejándonos wil [65..90, 97..122]. Esos son los puntos de código que queremos.Ahora que hicimos la lista de puntos de código del alfabeto superior / inferior, continuamos nuestra función de filtrado. La función se asigna a cada carácter en la cadena de entrada, que, como dije inicialmente, se analiza como su punto de código. Entonces ahora esencialmente tenemos
[codepoint, [65..90, 97..122]]
. Para saber si charcodepoint
es una letra, simplemente tomamos su índice en la lista que hicimos. Si no está allí, obtendremos-1
el índice en su lugar.En este momento, obtenemos un valor falsey solo si
codepoint == 65
, es decir, el primer índice de nuestra lista, ya que solo entonces el índice sería 0. Pero un solo incremento solucionará este problema y, ahora, sicodepoint
está en nuestra lista, lo haremos obtener su índice + 1, que siempre es un número positivo, por lo tanto, siempre es verdadero, mientras que si no está allí obtendremos -1 + 1 = 0, es decir, falsey.Finalmente aplicamos la función que describí a cada carácter de la entrada, y solo tomamos los caracteres para los cuales la función devolvió un resultado verdadero.
A continuación tenemos que determinar si cada carácter es una vocal o consonante. Dado que las vocales son menos que las consonantes, crear una cadena de vocales para que verifiquemos esa condición es más corto que crear una cadena de consonantes, por lo que verificamos si cada carácter es una vocal. Pero, para verificar si la lista booleana es palindrómica, necesitamos booleanos, que no obtenemos simplemente tomando el índice + 1, ya que eso puede resultar en cualquier número de [1..10] si el carácter es una vocal. Y, como la mayoría de los idiomas de golf, este tampoco tiene una
bool
función. Entonces, simplemente usamosnot not x
, ya quenot
siempre devuelve un valor booleano. Pero espera; ¿Realmente necesitamos tener booleanos específicos? Comonot
siempre devuelve un valor booleano, ¿por qué no eliminamos el segundo?not
, y verifica si cada char es una consonante? Sí, eso es exactamente lo que haremos!Después de la verificación, que devuelve una lista de booleanos, verificamos si esta lista booleana que obtuvimos es un palíndromo, que es lo que este desafío nos pide que hagamos. Bueno, ¿cuál es la definición de un palíndromo? Sí, un palíndromo es una lista o cadena que es igual a su reverso. Entonces, ¿cómo lo comprobamos? Simple, lo duplicamos, tomamos el reverso y lo comparamos con la lista original. El resultado que obtenemos es, finalmente , lo que debería devolver nuestro código.
fuente
PHP , 87 bytes
Versión PHP gratuita de Regex. Se agregó una "vocal" ya que stripos puede devolver 0 que es falso en PHP.
Defecto corregido por Jörg.
Pruébalo en línea!
fuente
for(;a&$c=$argn[$p++];)ctype_alpha($c)?$s.=stripos(_aeiou,$c)?0:1:0;echo$s==strrev($s);
pero obtiene el resultado correcto para cadenas que contienen ceroq / kdb +,
4238 bytesSolución:
Ejemplo:
Explicación:
Ediciones:
reverse
por k equivalente|:
fuente
CJam , 26 bytes
Pruébalo en línea!
-1 gracias a Esolanging Fruit .
fuente
26,'af+
con'{,97>
para guardar un byte.Braingolf,
43 bytes-1 byte gracias a Erik the Outgolfer
Resulta que tuve
P
todo el tiempo, incluso antes de este desafío.J
sin embargo, a pesar de haber sido creado antes de este desafío, no fue empujado a github antes del desafío, por lo tanto, todavía no compite.Explicación:
fuente
n
?Alex A.
?Python 2, 83 bytes
Define una función que da
True
oFalse
fuente
"aeiouAEIOU".__contains__
lugar delambda y:y.lower()in"aeiou"
.CJam , 79 bytes
Primerizo! (Hice lo que pude)
Pruébalo en línea!
fuente
Python 3 ,
928774726968 bytesPruébalo en línea!
fuente
for c in s
s
variable reemplazandos
en la segunda línea ainput().lower()
Ruby, 57 bytes
Pruébalo en línea!
fuente
Bash , 82 bytes
Pruébalo en línea!
Recibe el nombre como parámetro, elimina los que no son letras, reemplaza las vocales con 0, las no vocales ni 0 con 1 y se compara con el mismo reverso.
Podría jugar al golf un poco más si puede llegar al trabajo doble o triple sustitución
El estado de salida es 0 para verdadero y 1 para no.
fuente
i=${i^^*};
conviertei
a mayúsculas. Pero creo que solo te ahorra una-z
and anaeiou
, que es menos del 10B que cuesta.Japt v2.0a0,
1911 bytesPruébalo en línea
Explicación
fuente
APL (Dyalog) ,
3433 bytesPruébalo en línea!
Golf en progreso.
fuente
819⌶⍨∘1
(⊢≡⌽)
PowerShell, 108 bytes
fuente
Axioma, 126 bytes
prueba
fuente
Pyke, 12 bytes
Pruébalo aquí!
fuente
PowerShell, 87 bytes
Obtenga una copia de la cadena donde las vocales son 0 y las consonantes son 1, con todos los caracteres especiales eliminados, compare esa cadena con una versión inversa unida de nuevo a una cadena
Salida:
fuente
Retina , 47 bytes
Pruébalo en línea!
Este es solo un enfoque diferente para caracteres no alfabéticos
fuente