Desafío de apreciación del usuario # 1: Dennis ♦


53

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 1sys 0donde está cada consonante 1y 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. yNo 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 = '')

Pruébalo en línea!


¿Cuándo y quién es el número 2?
caird coinheringaahing

@cairdcoinheringaahing Gracias por recordármelo. Será sobre Mego (TNB RO, de ahí las cursivas), pero aún no he podido finalizarlo.
HyperNeutrino

¿debería decirle o simplemente se zambulliría en el agua para buscar peces?
caird coinheringaahing

@cairdcoinheringaahing Estoy bastante seguro de que él ya lo sabe; Dije que haría una sobre él, pero aún no he decidido si voy a hacer algo relacionado con los pingüinos o TNB.
HyperNeutrino

Calculo pingüinos. Es lo que él sabe (para mí)
caird coinheringaahing

Respuestas:


15

05AB1E , 9 bytes

žM¹álSåÂQ

Pruébalo en línea!

-2 gracias a Adnan .

Esto ataca el punto de dolor de Jelly exactamente. Utiliza ly A, equivalentes de 1 byte para Jelly's Œly Øarespectivamente.


¿Estás seguro de que esto funciona? Ejecute esto
MCCCS

@MCCCS Hmm, puede que tengas razón.
Erik the Outgolfer

Puede reemplazar por áy poco DRa poco Â.
Adnan

@Adnan Olvidó á, no sabía lo que Âhace, gracias!
Erik the Outgolfer

11
@alexis la mayoría de idiomas de golf utilizan 256 caracteres diferentes y una página de código personalizado que mapea hexagonal 00que FFa esos 256 caracteres, véase la respuesta de jalea
Stephen

18

Jalea , 11 bytes

ŒufØAe€ØCŒḂ

Pruébalo en línea!

Versiones alternativas:

ŒlfØae€ØCŒḂ

ŒufØAe€ØcŒḂ

ŒlfØae€ØcŒḂ

Por supuesto, un desafío para apreciar a Dennis debe tener una respuesta en un idioma suyo.


15
Œuf es huevo en francés. Solo
digo

13

x86 función de código de máquina de 32 bits, 42 41 bytes

Actualmente, 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: 41 40 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): 45 44 bytes

Código de máquina x86-64 (con punteros de 32 bits, como el x32 ABI): 44 43 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 byteel 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 documentadasalc para establecer AL desde CF, de la misma manera que lo sbb al,alharí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:

  • truco de comparación sin firmar para una combinación de isalpha () y toupper (), y cero-extiende el byte para llenar eax, configurando para:
  • mapa de bits inmediato en un registro para bt, inspirado en una buena salida del compilador paraswitch .
  • Crear una matriz de tamaño variable en la pila con push in a loop. (Estándar para asm, pero no es algo que pueda hacer con C para la versión de cadena de longitud implícita). Utiliza 4 bytes de espacio de pila para cada carácter de entrada, pero ahorra al menos 1 byte en comparación con el golf óptimo.stosb .
  • En lugar de cmp / setne en la matriz booleana, XOR se junta para obtener un valor de verdad directamente. ( cmp/ salcno es una opción, porque salcsolo funciona para CF, y 0xFF-0 no establece CF. setees de 3 bytes, pero evitaría el incexterior del bucle, por un costo neto de 2 bytes (1 en modo de 64 bits )) vs.xor en el bucle y arreglarlo con inc.
; explicit-length version: input string in ESI, byte count in ECX
08048060 <dennis_like>:
 8048060:       55                      push   ebp
 8048061:       89 e5                   mov    ebp,esp  ; a stack frame lets us restore esp with LEAVE (1B)
 8048063:       ba ee be ef 03          mov    edx,0x3efbeee ; consonant bitmap

08048068 <dennis_like.filter_loop>:
 8048068:       ac                      lods   al,BYTE PTR ds:[esi]
 8048069:       24 5f                   and    al,0x5f    ; uppercase
 804806b:       2c 41                   sub    al,0x41    ; range-shift to 0..25
 804806d:       3c 19                   cmp    al,0x19    ; reject non-letters
 804806f:       77 05                   ja     8048076 <dennis_like.non_alpha>
 8048071:       0f a3 c2                bt     edx,eax    # AL = 0..25 = position in alphabet
 8048074:       d6                      SALC     ; set AL=0 or 0xFF from carry.  Undocumented insn, but widely supported
 8048075:       50                      push   eax
08048076 <dennis_like.non_alpha>:
 8048076:       e2 f0                   loop   8048068 <dennis_like.filter_loop>   # ecx = remaining string bytes
 ; end of first loop

 8048078:       89 ee                   mov    esi,ebp  ; ebp = one-past-the-top of the bool array
0804807a <dennis_like.palindrome_loop>:
 804807a:       58                      pop    eax      ; read from the bottom
 804807b:       83 ee 04                sub    esi,0x4
 804807e:       32 06                   xor    al,BYTE PTR [esi]
 8048080:       75 04                   jne    8048086 <dennis_like.non_palindrome>
 8048082:       39 e6                   cmp    esi,esp             ; until the pointers meet or cross in the middle
 8048084:       77 f4                   ja     804807a  <dennis_like.palindrome_loop>

08048086 <dennis_like.non_palindrome>:
 ; jump or fall-through to here with al holding an inverted boolean
 8048086:       40                      inc    eax
 8048087:       c9                      leave  
 8048088:       c3                      ret    
;; 0x89 - 0x60 = 41 bytes

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.) salcEs más lenta que setccen 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. strlenimplementación de int80h.org .

; build with the same %define macros as the source below (so this uses 32-bit regs in 32-bit mode)
global _start
_start:
    ;%define PTRSIZE 4   ; true for x32 and 32-bit mode.

    mov  esi, [rsp+4 + 4*1]  ; esi = argv[1]
    ;mov  rsi, [rsp+8 + 8*1]  ; rsi = argv[1]   ; For regular x86-64 (not x32)

%if IMPLICIT_LENGTH == 0
        ; strlen(esi)
         mov     rdi, rsi
         mov     rcx, -1
        xor     eax, eax
        repne scasb    ; rcx = -strlen - 2
        not     rcx
        dec     rcx
%endif

    mov  eax, 0xFFFFAEBB   ; make sure the function works with garbage in EAX
    call dennis_like

    ;; use the 32-bit ABI _exit syscall, even in x32 code for simplicity
    mov ebx, eax
    mov eax, 1
    int 0x80           ; _exit( dennis_like(argv[1]) )

    ;; movzx edi, al   ; actually mov edi,eax is fine here, too
    ;; mov eax,231     ; 64-bit ABI exit_group( same thing )
    ;; syscall

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 para setc al. También necesitaría un byte adicional para deco notal 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 %ifcondicionales. 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 rsppuntero de entrada y en el bajo 4G del espacio de direcciones.

%define IMPLICIT_LENGTH 0

; This source can be built as x32, or as plain old 32-bit mode
; x32 needs to push 64-bit regs, and using them in addressing modes avoids address-size prefixes
; 32-bit code needs to use the 32-bit names everywhere

;%if __BITS__ != 32   ; NASM-only
%ifidn __OUTPUT_FORMAT__, elfx32
%define CPUMODE 64
%define STACKWIDTH 8    ; push / pop 8 bytes
%else
%define CPUMODE 32
%define STACKWIDTH 4    ; push / pop 4 bytes
%define rax eax
%define rcx ecx
%define rsi esi
%define rdi edi
%define rbp ebp
%define rsp esp
%endif

    ; A regular x86-64 version needs 4 REX prefixes to handle 64-bit pointers
    ; I haven't cluttered the source with that, but I guess stuff like %define ebp rbp  would do the trick.


    ;; Calling convention similar to SysV x32, or to MS vectorcall, but with different arg regs
    ;; _Bool dennis_like_implicit(const char *esi)
    ;; _Bool dennis_like_explicit(size_t ecx, const char *esi)
global dennis_like
dennis_like:
    ; We want to restore esp later, so make a stack frame for LEAVE
    push  rbp
    mov   ebp, esp   ; enter 0,0 is 4 bytes.  Only saves bytes if we had a fixed-size allocation to do.

    ;         ZYXWVUTSRQPONMLKJIHGFEDCBA
    mov  edx, 11111011111011111011101110b   ; consonant/vowel bitmap for use with bt

;;; assume that len >= 1
%if IMPLICIT_LENGTH
    lodsb   ; pipelining the loop is 1B shorter than  jmp .non_alpha
.filter_loop:
%else
.filter_loop:
    lodsb
%endif

    and   al, 0x7F ^ 0x20  ; force ASCII to uppercase.
    sub   al, 'A'          ; range-shift to 'A' = 0
    cmp   al, 'Z'-'A'      ; if al was less than 'A', it will be a large unsigned number
    ja  .non_alpha
    ;; AL = position in alphabet (0-25)

    bt    edx, eax              ; 3B
%if CPUMODE == 32
    salc                        ; 1B   only sets AL = 0 or 0xFF.  Not available in 64-bit mode
%else
    sbb   eax, eax              ; 2B   eax = 0 or -1, according to CF.
%endif
    push  rax

.non_alpha:
%if IMPLICIT_LENGTH
    lodsb
    test   al,al
    jnz .filter_loop
%else
    loop .filter_loop
%endif
    ; al = potentially garbage if the last char was non-alpha
    ; esp = bottom of bool array

    mov   esi, ebp  ; ebp = one-past-the-top of the bool array
.palindrome_loop:
    pop   rax

    sub   esi, STACKWIDTH
    xor   al, [rsi]   ; al = (arr[up] != arr[--down]).  8-bit operand-size so flags are set from the non-garbage
    jnz .non_palindrome

    cmp   esi, esp
    ja .palindrome_loop

.non_palindrome:  ; we jump here with al=1 if we found a difference, or drop out of the loop with al=0 for no diff
    inc   eax     ;; AL transforms 0 -> 1  or  0xFF -> 0.
    leave
    ret           ; return value in AL.  high bytes of EAX are allowed to contain garbage.

Miré a jugar con DF (la bandera de dirección que controla lodsd/ scasdy 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 bytes sub 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,r32aún funciona con mucha basura en el índice de bits. Simplemente no está documentado como shrestá.

En lugar de bt / sbbobtener el bit dentro / fuera de CF, use un desplazamiento / máscara para aislar el bit que queremos del mapa de bits.

%if IMPLICIT_LENGTH && CPUMODE == 64
    ; incompatible with LOOP for explicit-length, both need ECX.  In that case, bt/sbb is best
    xchg  eax, ecx
    mov   eax, 11111011111011111011101110b   ; not hoisted out of the loop
    shr   eax, cl
    and   al, 1
%else
    bt    edx, eax
    sbb   eax, eax
%endif
    push  rax

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 de dec eax(también 2B en x86-64) para todavía produce un valor apropiado bool/ 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 ^ 0x20para forzar a mayúsculas y poner a cero el resto de eax con un byte de 3 bytes and 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 el suby cmp.)

Pierde en bt/ salcen 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, eaxtodavía funciona con mucha basura en eax. Aparentemente enmascara el turno de contar la misma manera que shr r32, cllo hace (mirar sólo a los 5 bits bajas de Cl). Esto es diferente de bt [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, srcCon 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 la btversió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, BMI2 shrx eax, edx, eaxes de 5 bytes, frente a solo 2 bytes para shr eax, cl. El uso bextrnecesita un byte de 2 mov 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 %ifcondicionales. 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 lodsantes, y en la parte inferior, en lugar de solo uno en la parte superior del bucle.

    ; 64-bit implicit-length version using the alternate bitmap strategy
    00400060 <dennis_like>:
      400060:       55                      push   rbp
      400061:       89 e5                   mov    ebp,esp
      400063:       ac                      lods   al,BYTE PTR ds:[rsi]

    00400064 <dennis_like.filter_loop>:
      400064:       24 5f                   and    al,0x5f
      400066:       2c 41                   sub    al,0x41
      400068:       3c 19                   cmp    al,0x19
      40006a:       77 0b                   ja     400077 <dennis_like.non_alpha>
      40006c:       91                      xchg   ecx,eax
      40006d:       b8 ee be ef 03          mov    eax,0x3efbeee  ; inside the loop since SHR destroys it
      400072:       d3 e8                   shr    eax,cl
      400074:       24 01                   and    al,0x1
      400076:       50                      push   rax
    00400077 <dennis_like.non_alpha>:
      400077:       ac                      lods   al,BYTE PTR ds:[rsi]
      400078:       84 c0                   test   al,al
      40007a:       75 e8                   jne    400064 <dennis_like.filter_loop>

      40007c:       89 ee                   mov    esi,ebp
    0040007e <dennis_like.palindrome_loop>:
      40007e:       58                      pop    rax
      40007f:       83 ee 08                sub    esi,0x8
      400082:       32 06                   xor    al,BYTE PTR [rsi]
      400084:       75 04                   jne    40008a <dennis_like.non_palindrome>
      400086:       39 e6                   cmp    esi,esp
      400088:       77 f4                   ja     40007e <dennis_like.palindrome_loop>

    0040008a <dennis_like.non_palindrome>:
      40008a:       ff c8                   dec    eax  ; invert the 0 / non-zero status of AL.  xor al,1 works too, and produces a proper bool.
      40008c:       c9                      leave  
      40008d:       c3                      ret    

   0x8e - 0x60 = 0x2e = 46 bytes

8

retina ,49 47 45 bytes

\P{L}

i`[aeiou]
1
\D
2
+`^(.)(.*)\1$
$2
^.?$

Prué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.


¿ \D 2Funciona para ahorrarle un par de bytes T`lL`2?
Neil

@Neil Sí, parece, buena captura!
FryAmTheEggman

Bien hecho. Estaba tratando de hacer esto :(
Christopher

7

PHP, 82 bytes

<?=strrev($s=preg_replace(["#[^a-z]#i","#[aeiou]#i","#\pL#"],["",0,1],$argn))==$s;

Pruébalo en línea!


Puede anteponer el encasillado (bool)y eliminar el $s=y el ==$scheque para guardar 1 byte.
Kaiser

Si no me equivoco, puede reemplazar el (bool)con solo 0||decir falso, o ... en cambio, guardar 3 bytes adicionales.
Kaiser

Hm. ¿No podría utilizar \wpara la palabra caracteres en lugar de la a-z?
Kaiser

@kaiser \wcontiene 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 $ses necesaria para crear el booleano
Jörg Hülsermann

Eso es verdad. Aún así los otros deberían trabajar. "Debería" ... lo hacen.
Kaiser

6

MATL, 14 bytes

t3Y2m)13Y2mtP=

Pruébalo en MATL Online .

Aquí hay una versión ligeramente modificada para verificar todos los casos de prueba.

Explicación

        % Implicitly grab the input as a string
        %     STACK: {'Martin Ender'}
t       % Duplicate the input
        %     STACK: {'Martin Ender', 'Martin Ender'}
3Y2     % Push the string 'ABC...XYZabc...xyz'
        %     STACK: {'Martin Ender', 'Martin Ender', 'ABC...XYZabc...xyz'}
m       % Find which characters of the input are letters using this string
        %     STACK: {'Martin Ender', [1 1 1 1 1 1 0 1 1 1 1]}
)       % Use this boolean array to select only the letters
        %     STACK: {'MartinEnder'}
13Y2    % Push the string literal 'aeiouAEIOU' to the stack
        %     STACK: {'MartinEnder', 'aeiouAEIOU'}
m       % Check for membership of each letter of the input in this string.
        %     STACK: {[0 1 0 0 1 0 1 0 0 1 0]}
tP      % Create a reversed copy
        %     STACK: {[0 1 0 0 1 0 1 0 0 1 0], [0 1 0 0 1 0 1 0 0 1 0]}
=       % Perform an element-wise comparison yielding a truthy (all 1's) or 
        % falsey (any 0's) result
        %     STACK: {[1 1 1 1 1 1 1 1 1 1 1]}
        % Implicitly display the result

¿Lo demuestras con "Martin Ender" en lugar de "Dennis"? Tengo que mirar el título del desafío nuevamente.
Roman Gräf

1
Presumiblemente, Suever quería una demostración que tuviera cierta cantidad de filtrado en el primer paso.
Greg Martin

Entonces debería usar "Alex A." en cambio, también tiene un período.
Erik the Outgolfer

2
Estoy confundido cuál es el problema. Elegí Martin Ender porque en realidad sería cierto si elimina espacios y falso de lo contrario. También
incluí

6

Haskell, 84 75 74 69 bytes

-10 gracias a @nimi
-5 gracias a @Zgarb

f x=(==)<*>reverse$[elem c"aeiouAEIOU"|c<-x,'@'<c,c<'{','`'<c||c<'[']

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!


Dos consejos: 1) Una comprensión de la lista a menudo se acorta de lo que se filtersigue, mapincluso si tiene que cambiar a no poitfree. 2) El <$>ides superfluo. f x=(==)<*>reverse$[elem c"aeiouAEIOU"|c<-x,celem ['A'..'Z']++['a'..'z']].
nimi

Puede soltar el espacio entre cy "por un byte más.
nimi

1
Creo que c`elem`['A'..'Z']++['a'..'z']se puede acortar a'@'<c,c<'{','`'<c||c<'['
Zgarb


4

Brachylog , 13 bytes

ḷ{∈Ṿg|∈Ḅg}ˢ.↔

Pruébalo en línea!

Explicación

ḷ                Lowercase the input
 {       }ˢ.     Select each char if:
  ∈Ṿg              it's a vowel, and replace it with ["aeiou"]            
     |             Or
      ∈Ḅg          it's a consonant, and replace it with ["bcdfghjklkmnpqrstvwxyz"]
           .↔    The resulting list is a palindrome

3

Alice , 28 bytes

/uia.QN."-e@
\1"lyuy.Ra$i1/o

Pruébalo en línea!

Salidas 1como 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:

1il.uN."aei ou"ayQy.R-$@1o1@

1                           % Append "1" to top of stack
                            % STACK: ["1"]
 i                          % Push input to stack
                            % STACK: ["1", "Dennis"]
  l                         % Convert to lowercase
                            % STACK: ["1", "dennis"]
   .                        % Duplicate
                            % STACK: ["1", "dennis", "dennis"]
    u                       % Convert to uppercase
                            % STACK: ["1", "dennis", "DENNIS"]
     N                      % Take multiset difference; this removes all non-alphabetic characters
                            % STACK: ["1", "dennis"]
      .                     % Duplicate
                            % STACK: ["1", "dennis", "dennis"]
       "aei ou"             % Push "aei ou"
                            % STACK: ["1", "dennis", "dennis", "aei ou"]
              a             % Push newline
                            % STACK: ["1", "dennis", "dennis", "aeiou", "\n"]
               y            % Transliterate: replace all vowels with newlines
                            % STACK: ["1", "dennis", "d\nnn\ns"]
                Q           % Reverse stack
                            % STACK: ["d\nnn\ns", "dennis", "1"]
                 y          % Transliterate: replace remaining characters with "1"
                            % STACK: ["1\n11\n1"]
                  .         % Duplicate
                            % STACK: ["1\n11\n1", "1\n11\n1"]
                   R        % Reverse top of stack
                            % STACK: ["1\n11\n1", "1\n11\n1"]
                    -       % Remove occurrences: for same-length strings, result is "" iff strings are equal.
                            % STACK: [""]
                     $      % Pop stack, and skip next command if ""
                      @     % Terminate (skipped if c/v pattern is palindromic)
                       1o   % Output "1"
                         1  % Push "1" (useless)
                          @ % Terminate

3

Python 3 , 72 71 bytes

-1 byte gracias a @ovs

def f(s):s=[c in'AEIOU'for c in s.upper()if'@'<c<'['];return s==s[::-1]

Pruébalo en línea!


def f(s):s=[c in'AEIOU'for c in s.upper()if'@'<c<'['];return s==s[::-1]para 71 bytes
ovs

3

JavaScript (ES6), 72 69 bytes

Guardado 3 bytes gracias a Neil

Devuelve un booleano.

s=>(a=s.match(/[a-z]/gi).map(c=>!/[aeiou]/i.exec(c)))+''==a.reverse()

Casos de prueba


Ahorre un par de bytes reemplazando las 2 cadenas vacías con 2.
Shaggy

1
¿Necesitas el +''al final? Eso ahorraría 3 bytes en su lugar.
Neil

¡Me gusta más la idea de @ Neil!
Shaggy

2

Mathematica, 113 bytes

PalindromeQ@StringCases[StringReplace[#,{Characters["aeiouAEIOU"]->"1",CharacterRange["A","z"]->"0"}],{"0","1"}]&

Puede deshacerse de bastantes bytes:PalindromeQ@StringReplace[#,{Characters@"aeiouAEIOU"->"1",LetterCharacter->"0",_->""}]&
No es un árbol

2

GolfScript , 42 bytes

{123,65>.26>6<-?)},{"AEIOUaeiou"?)!}%.-1%=

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 para A. 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 char codepointes una letra, simplemente tomamos su índice en la lista que hicimos. Si no está allí, obtendremos -1el í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, si codepointestá 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 boolfunción. Entonces, simplemente usamos not not x, ya que notsiempre devuelve un valor booleano. Pero espera; ¿Realmente necesitamos tener booleanos específicos? Como notsiempre 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.


1
Explicación gigante para un programa de 42 bytes. Ahora supongo que se explica por sí mismo ...
Erik the Outgolfer

2

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.

for(;a&$c=$argn[$p++];)!ctype_alpha($c)?:$s.=stripos(_aeiou,$c)?0:1;echo$s==strrev($s);

Pruébalo en línea!


El mismo recuento de bytes. 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 cero
Jörg Hülsermann

@ JörgHülsermann Gracias.
ME

2

q / kdb +, 42 38 bytes

Solución:

{x~|:[x]}{inter[x;.Q.a]in"aeiou"}lower

Ejemplo:

q){x~|:[x]}{inter[x;.Q.a]in"aeiou"}lower"Dennis"
1b
q){x~|:[x]}{inter[x;.Q.a]in"aeiou"}lower"Adam"
0b
q){x~|:[x]}{inter[x;.Q.a]in"aeiou"}lower"Alex A."
1b

Explicación:

lower        // converts argument on the right to lowercase
.Q.a         // lowercase alphabet "abc..xyz"
inter[x;y]   // intersection of x and y (thus only return a-z)
x in "aeiou" // returns boolean list whether x is a vowel; "dennis" = 010010b
|:           // k shorthand for 'reverse'

Ediciones:

  • -4 bytes; cambiar reversepor k equivalente|:

2

CJam , 26 bytes

lel_'{,97>--"aeiou"fe=_W%=

Pruébalo en línea!

-1 gracias a Esolanging Fruit .


Puede reemplazar 26,'af+con '{,97>para guardar un byte.
Esolanging Fruit

@EsolangingFruit una respuesta tan antigua ...
Erik the Outgolfer

Un byte guardado hace medio año no es diferente de un byte guardado ahora. No es que haya una inflación de bytes ni nada: P
Esolanging Fruit

@EsolangingFruit Me refería a mi experiencia siempre en desarrollo con el golf ... por supuesto, usted obtuvo un crédito como de costumbre, ¡no se preocupe!
Erik the Outgolfer

2

Braingolf,  4  3 bytes

&JP

-1 byte gracias a Erik the Outgolfer

Resulta que tuve Ptodo 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:

&JP  Implicit input, push ASCII value of each char in string to stack
&J   Replace each item in stack with 1 if vowel, otherwise 0
  P  Pop entire stack, push 1 if stack is palindromic, 0 otherwise
     Implicit output of last item on stack

¿Por qué lo necesitas n?
Erik the Outgolfer

@EriktheOutgolfer porque soy un imbécil certificado
Skidsdev

Hmm, olvidaste eliminarlo de la explicación.
Erik the Outgolfer

@EriktheOutgolfer Yo iba a escribir "Erick" y luego tachar la c, pero solo parece "Eriek"
Skidsdev

¿No fallará esto para los gustos de Alex A.?
Shaggy

1

Python 2, 83 bytes

def f(x):k=map(lambda y:y.lower()in"aeiou",filter(str.isalpha,x));return k==k[::-1]

Define una función que da TrueoFalse


Puede guardar 2 bytes utilizando en "aeiouAEIOU".__contains__lugar de lambda y:y.lower()in"aeiou".
Blender




1

Bash , 82 bytes

i=${1//[^a-zA-Z]};a=aeouiAEOUI;b=${i//[$a]/0};c=${b//[!0$a]/1};[ $c = `rev<<<$c` ]

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.


En versiones recientes de bash, se i=${i^^*};convierte ia mayúsculas. Pero creo que solo te ahorra un a-zand an aeiou, que es menos del 10B que cuesta.
Peter Cordes

1

Japt v2.0a0, 19 11 bytes

k\L mè\v ê¬

Pruébalo en línea


Explicación

        :Implicit input of string U.
 k\L    :Remove all non-letter characters from U.
 m      :Map over resulting string, replacing each character ...
 è\v    :with the count of the number of vowels in each single character substring.
 ê¬     :Is the above a palindrome?
        :Implicit output of boolean result.


0

PowerShell, 108 bytes

read-host|%{[char[]]$_|%{$d=$_-replace'\P{L}'-replace'[aeiou]',0-replace'\D',1;$s="$s$d";$r="$d$r"};$s-eq$r}

0

Axioma, 126 bytes

g(x)==~member?(x,alphabetic());v(s:String):Boolean==(w:=remove(g,s);a:=[member?(w.r,"aeiouAEIOU")for r in 1..#w];a=reverse(a))

prueba

(8) -> [[i,v(i)] for i in ["Dennis", "Martin", "Martin Ender", "Alex", "Alex A.", "Doorknob", "Mego"]]
   (8)
   [["Dennis",true], ["Martin",true], ["Martin Ender",true], ["Alex",false],
    ["Alex A.",true], ["Doorknob",false], ["Mego",false]]
                                                      Type: List List Any

0

Pyke, 12 bytes

#B)l1~-L{D_q

Pruébalo aquí!

#B)          -    filter(is_alpha, input)
   l1        -   ^.lower()
     ~-L{    -  ^ - "bcdfghjklmnpqrstvwxyz"
         D_q - ^ == reversed(^)

0

PowerShell, 87 bytes

$s=("$args"-replace '\P{L}'-replace'[aeiou]',0-replace'\D',1);$s-eq(-join($s[-1..-99]))

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:

PS C:\Users\Connor> "Dennis","Martin","Martin Ender","Alex","Alex A.","Doorknob","Mego" | % {
    $s=("$_"-replace '\P{L}'-replace'[aeiou]',0-replace'\D',1);$s-eq(-join($s[-1..-99]))
}
True
True
True
False
True
False
False

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.