Desafio de apreciação do usuário # 1: Dennis ♦

53

Tive a ideia espontânea de fazer uma série de desafios de usuários que ajudaram e continuam a ajudar a comunidade PPCG a ser um lugar agradável para todos, ou talvez apenas especificamente para mim. : P

Se você converter o nome de Dennis em uma matriz de se 1es 0onde cada consoante está 1e cada vogal 0, a matriz [1, 0, 1, 1, 0, 1]é simétrica. Portanto, seu desafio é determinar como são os outros nomes.

Desafio

Dada uma sequência ASCII, remova todos os caracteres que não são letras e determine se a configuração de vogais e consoantes é simétrica. ynão é uma vogal.

Observe que seu programa não precisa ser esse tipo de string.

Casos de teste

Dennis -> truthy
Martin -> truthy
Martin Ender -> truthy
Alex -> falsy
Alex A. -> truthy
Doorknob -> falsy
Mego -> falsy

Implementação de referência

Esse código Python 3 fornecerá a saída correta em um caso de teste. É o máximo que eu poderia fazer sem 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 = '')

Experimente online!

HyperNeutrino
fonte
Quando e quem é o número 2?
caird coinheringaahing
@cairdcoinheringaahing Obrigado por me lembrar. Vai ser sobre Mego (TNB RO, portanto, itálico), mas ainda não cheguei a finalizá-lo.
HyperNeutrino
devo dizer a ele ou ele simplesmente mergulharia na água em busca de peixe?
caird coinheringaahing
@cairdcoinheringaahing Tenho certeza que ele já sabe; Eu disse que faria um sobre ele, mas ainda não decidi se vou fazer algo relacionado a pinguins ou TNB ainda.
HyperNeutrino
Eu acho pinguins. É o que ele é conhecido por (para mim)
caird coinheringaahing

Respostas:

15

05AB1E , 9 bytes

žM¹álSåÂQ

Experimente online!

-2 graças a Adnan .

Isso ataca exatamente o ponto de dor de Jelly. Ele usa le A, equivalentes de 1 byte para o Jelly Œle Øarespectivamente.

Erik, o Outgolfer
fonte
Tem certeza de que isso funciona? Execute isto
MCCCS
@MCCCS Hmm, você pode estar certo.
Erik the Outgolfer
Você pode substituir por áe DRpor Â.
Adnan
@ Adnan Esqueceu á, não sabia o que Âfaz, obrigado!
Erik the Outgolfer
11
@alexis maioria de línguas de golfe usar 256 caracteres diferentes e uma página de código personalizado que mapeia hex 00para FFa esses 256 caracteres, ver a resposta Jelly
Stephen
18

Gelatina , 11 bytes

ŒufØAe€ØCŒḂ

Experimente online!

Versões alternativas:

ŒlfØae€ØCŒḂ

ŒufØAe€ØcŒḂ

ŒlfØae€ØcŒḂ

É claro que um desafio para apreciar Dennis deve ter uma resposta no idioma dele.

Erik, o Outgolfer
fonte
15
Œuf é Egg em francês. Apenas dizendo '
YSC
13

função de código de máquina x86 de 32 bits, 42 41 bytes

Atualmente, a resposta mais curta no idioma não-golfe, 1B menor que o q / kdb + do @ streetster .

Com 0 para verdade e diferente de zero para falsidade: 41 40 bytes. (em geral, economiza 1 byte para 32 bits, 2 bytes para 64 bits).

Com seqüências de comprimento implícito (terminação 0 no estilo C): 45 44 bytes

código de máquina x86-64 (com ponteiros de 32 bits, como o ABI x32): 44 43 bytes .

x86-64 com seqüências de comprimento implícito, ainda 46 bytes (a estratégia de bitmap de deslocamento / máscara está equilibrada agora).

Esta é uma função com a assinatura C _Bool dennis_like(size_t ecx, const char *esi). A convenção de chamada é um pouco fora do padrão, próxima ao MS vectorcall / fastcall, mas com diferentes registros arg: string no ESI e o comprimento no ECX. Ele só derruba seus arg-regs e EDX. O AL mantém o valor de retorno, com os bytes altos mantendo o lixo (conforme permitido pelas ABIs do SysV x86 e x32. IDK o que as ABIs da MS dizem sobre o lixo alto ao retornar números inteiros estreitos ou booleanos).


Explicação do algoritmo :

Faça um loop sobre a sequência de entrada, filtrando e classificando em uma matriz booleana na pilha: para cada byte, verifique se é um caractere alfabético (se não, continue para o próximo caractere) e transforme-o em um número inteiro de 0 a 25 (AZ) . Use esse número 0-25 para verificar um bitmap da vogal = 0 / consoante = 1. (O bitmap é carregado em um registro como uma constante imediata de 32 bits). Empurre 0 ou 0xFF na pilha de acordo com o resultado do bitmap (na verdade, no byte baixo de um elemento de 32 bits, que pode ter lixo nos 3 bytes principais).

O primeiro loop produz uma matriz de 0 ou 0xFF (em elementos dword preenchidos com lixo). Faça a verificação habitual do palíndromo com um segundo loop que para quando os ponteiros se cruzam no meio (ou quando ambos apontam para o mesmo elemento se houver um número ímpar de caracteres alfabéticos). O ponteiro para cima é o ponteiro da pilha e usamos o POP para carregar + incrementar. Em vez de comparar / setcc nesse loop, podemos apenas usar o XOR para detectar o mesmo / diferente, pois existem apenas dois valores possíveis. Poderíamos acumular (com OR) se encontrássemos elementos não correspondentes, mas uma ramificação antecipada nos sinalizadores definidos pelo XOR é pelo menos tão boa.

Observe que o segundo loop usa bytetamanho de operando, portanto, não importa o lixo que o primeiro loop deixa fora do byte baixo de cada elemento da matriz.


Ele usa a instrução não documentadasalc para definir AL a partir de CF, da mesma maneira que sbb al,alfaria. É suportado em todas as CPUs Intel (exceto no modo de 64 bits), até no Knight's Landing! O Agner Fog também lista os horários para todos os processadores AMD (incluindo Ryzen), por isso, se os fornecedores de x86 insistirem em vincular esse byte de espaço do código de operação desde 8086, é melhor aproveitarmos isso.

Truques interessantes:

  • truque de comparação não assinada para um isalpha () e um toupper () combinados e estende zero o byte para preencher o eax, configurando para:
  • bitmap imediato em um registro para bt, inspirado por uma saída agradável do compilador paraswitch .
  • Criando uma matriz de tamanho variável na pilha com push em um loop. (Padrão para asm, mas não algo que você possa fazer com C para a versão de cadeia de comprimento implícito). Ele usa 4 bytes de espaço na pilha para cada caractere de entrada, mas economiza pelo menos 1 byte em relação ao golfe ideal stosb.
  • Em vez de cmp / setne na matriz booleana, o XOR se ajusta para obter um valor verdade diretamente. ( cmp/ salcnão é uma opção, porque salcfunciona apenas para CF e 0xFF-0 não define CF. setetem 3 bytes, mas evitaria o incexterior do loop, por um custo líquido de 2 bytes (1 no modo de 64 bits )) vs. xor no loop e corrigindo-o com 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

Essa é provavelmente também uma das respostas mais rápidas, já que nenhum golfe realmente dói muito, pelo menos para cadeias de caracteres com menos de alguns milhares de caracteres em que o uso da memória 4x não causa muitos erros de cache. (Também pode ser prejudicial para as respostas anteriores a seqüências que não sejam do tipo Dennis antes de repetir todos os caracteres.) salcÉ mais lento do que setccem muitas CPUs (por exemplo, 3 uops vs. 1 no Skylake), mas uma verificação de bitmap com bt/salcainda é mais rápido que uma pesquisa por sequência ou correspondência de expressão regular. E não há sobrecarga de inicialização, por isso é extremamente barato para strings curtas.

Fazer isso de uma só vez, significa repetir o código de classificação para as direções para cima e para baixo. Isso seria mais rápido, mas maior tamanho de código. (Obviamente, se você quiser rápido, poderá executar 16 ou 32 caracteres por vez com o SSE2 ou AVX2, ainda usando o truque de comparação, deslocando o intervalo para a parte inferior do intervalo assinado).


Teste o programa (para ia32 ou x32 Linux) para chamar esta função com um cmdline arg e saia com status = return value. strlenimplementação do 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

Uma versão de 64 bits dessa função poderia usar sbb eax,eax, que é de apenas 2 bytes em vez de 3 para setc al. Também seria necessário um byte extra para decou notno final (porque apenas 32 bits possui 1 byte inc / dec r32). Usando a ABI x32 (ponteiros de 32 bits no modo longo), ainda podemos evitar prefixos REX, mesmo que copiemos e comparemos ponteiros.

setc [rdi]pode gravar diretamente na memória, mas reservar bytes ECX de espaço na pilha custa mais tamanho de código do que isso economiza. (E precisamos percorrer a matriz de saída. [rdi+rcx]Leva um byte extra para o modo de endereçamento, mas realmente precisamos de um contador que não atualize para caracteres filtrados, para que seja pior do que isso.)


Essa é a fonte YASM / NASM com %ifcondicionais. Ele pode ser criado com -felf32(código de 32 bits) ou -felfx32( código de 64 bits com a ABI x32) e com comprimento implícito ou explícito . Eu testei todas as 4 versões. Consulte esta resposta para obter um script para construir um binário estático a partir da fonte NASM / YASM.

Para testar a versão de 64 bits em uma máquina sem suporte para a ABI x32, você pode alterar os registros do ponteiro para 64 bits. (Em seguida, basta subtrair o número de prefixos REX.W = 1 (0x48 bytes) da contagem. Nesse caso, 4 instruções precisam de prefixos REX para operar em regs de 64 bits). Ou simplesmente chame-o com o rspe o ponteiro de entrada no baixo espaço de endereço 4G.

%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.

Eu olhei para mexer com o DF (a bandeira de direção que controla lodsd/ scasde assim por diante), mas simplesmente não parecia ser uma vitória. As ABIs usuais exigem que o DF seja limpo na entrada e saída da função. Assumir que a permissão foi liberada na entrada, mas deixá-la definida na saída seria trapaça, IMO. Seria bom usar o LODSD / SCASD para evitar os 3 bytes sub esi, 4, especialmente no caso em que não há muito lixo.


Estratégia alternativa de bitmap (para cadeias de comprimento implícito x86-64)

Acontece que isso não salva bytes, porque bt r32,r32ainda funciona com alto lixo no índice de bits. Simplesmente não está documentado do jeito que shrestá.

Em vez de bt / sbbobter o bit dentro / fora do CF, use um shift / mask para isolar o bit que queremos do bitmap.

%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 isso produz 0/1 em AL no final (em vez de 0 / 0xFF), podemos fazer a inversão necessária do valor de retorno no final da função com xor al, 1(2B) em vez de dec eax(também 2B em x86-64) para ainda produz um valor adequado bool/ de_Bool retorno.

Isso costumava salvar 1B para x86-64 com cadeias de comprimento implícito, evitando a necessidade de zerar os bytes altos do EAX. (Eu estava usando and eax, 0x7F ^ 0x20para forçar para maiúsculas e zerar o restante do eax com 3 bytes and r32,imm8. Mas agora estou usando a codificação imediata com AL de 2 bytes que a maioria das instruções do 8086 possui, como eu já estava fazendo para o sube cmp.)

Ele perde para bt/ salcno modo de 32 bits e as seqüências de comprimento explícito precisam de ECX para a contagem, para que isso também não funcione.

Mas então eu percebi que estava errado: bt edx, eaxainda trabalha com alto teor de lixo em eax. Aparentemente mascara o deslocamento contar da mesma forma shr r32, clfaz (olhando apenas para os baixos 5 bits de cl). É diferente de bt [mem], reg, que pode acessar fora da memória referenciada pelo modo / tamanho de endereçamento, tratando-a como uma cadeia de bits. (CISC louco ...)

O manual insn set ref da Intel não documenta a máscara, então talvez seja um comportamento não documentado que a Intel esteja preservando por enquanto. (Esse tipo de coisa não é incomum. bsf dst, srcCom src = 0 sempre deixa o dst sem modificação, mesmo que esteja documentado para deixar o dst mantendo um valor indefinido nesse caso. A AMD realmente documenta o comportamento do src = 0.) Testei no Skylake e no Core2, e a btversão funciona com lixo diferente de zero no EAX fora do AL.

Um truque interessante aqui é usar xchg eax,ecx(1 byte) para obter a contagem no CL. Infelizmente, o IMC2 shrx eax, edx, eaxé de 5 bytes, contra apenas 2 bytes para shr eax, cl. O uso bextrprecisa de 2 bytes mov ah,1(para o número de bits a serem extraídos), portanto, são novamente 5 + 2 bytes como SHRX + AND.


O código fonte ficou bastante bagunçado depois de adicionar %ifcondicionais. Aqui está a desmontagem de cadeias de comprimento implícito x32 (usando a estratégia alternativa para o bitmap, então ainda tem 46 bytes).

A principal diferença da versão de tamanho explícito está no primeiro loop. Observe como há um lodsantes dele e na parte inferior, em vez de apenas um na parte superior do loop.

    ; 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
Peter Cordes
fonte
8

Retina ,49 47 45 bytes

\P{L}

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

Experimente online!

Economizou 2 bytes graças a Neil.

Economizou mais 2 bytes graças a Martin.

Remove as não letras e substitui as vogais por 1 e as consoantes por 2, para obter valores consistentes. Em seguida, remove repetidamente o primeiro e o último caractere, se forem iguais. Como não são, a palavra será simétrica se houver um ou zero caracteres restantes.

FryAmTheEggman
fonte
O \D 2trabalho para salvar-lhe um par de bytes mais T`lL`2?
Neil
@ Neil Sim, parece, boa captura!
FryAmTheEggman 28/05
Bem feito. Eu estava tentando fazer isso :(
Christopher
7

PHP, 82 bytes

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

Experimente online!

Jörg Hülsermann
fonte
Você pode anexar a pré-visualização (bool)e remover $s=a ==$sseleção e para economizar 1 byte.
Kaiser
Se não me engano, você pode substituir (bool)por apenas 0||para dizer falso, ou ... em vez disso, economizando 3 bytes adicionais.
Kaiser
Hum. Você não poderia usar \wpara word caracteres em vez de a a-z?
Kaiser
O @kaiser \wcontém dígitos sublinhados e letras. Isso não funcionará e [^/p{L}]é mais longo que o [^a-z]i. Eu comparo a string reversa com a string, então $sé necessário criar o booleano
Jörg Hülsermann 29/05
Isso é verdade. Ainda os outros devem funcionar. "Deveriam" ... eles fazem.
Kaiser #
6

MATL, 14 bytes

t3Y2m)13Y2mtP=

Experimente no MATL Online .

Aqui está uma versão ligeiramente modificada para verificar todos os casos de teste.

Explicação

        % 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
Suever
fonte
Você demonstra isso com "Martin Ender" em vez de "Dennis"? Eu tenho que olhar para o título do desafio novamente.
Roman Gräf 28/05
11
Presumivelmente, Suever queria uma demonstração que tivesse uma certa quantidade de filtragem no primeiro passo.
Greg Martin
Então ele deve usar "Alex A." em vez disso, também tem um período.
Erik the Outgolfer
2
Estou confuso qual é o problema. Eu escolhi Martin Ender porque seria realmente verdade se você remover espaços e false caso contrário. Também incluí um link para todos os casos de teste
Suever
6

Haskell, 84 75 74 69 bytes

-10 graças a @nimi
-5 graças a @Zgarb

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

A compreensão da lista substitui cada letra por um booleano e remove todos os outros caracteres. A primeira parte verifica se a lista resultante é ou não um palíndromo.

Experimente online!

bearbear2k
fonte
Duas dicas: 1) Geralmente, a compreensão da lista é mais curta do que a filterseguida, mapmesmo que você precise mudar para não isento de poit. 2) O <$>idé supérfluo. f x=(==)<*>reverse$[elem c"aeiouAEIOU"|c<-x,celem ['A'..'Z']++['a'..'z']].
Nimi 28/05
Você pode soltar o espaço entre ce "para mais um byte.
Nimi 28/05
11
Eu acho que c`elem`['A'..'Z']++['a'..'z']pode ser reduzido para'@'<c,c<'{','`'<c||c<'['
Zgarb
5

Pitão, 18 15 bytes

_I/L"aeiou"@Gr0

Experimente aqui.

-2 graças a KarlKastor e, posteriormente, -1.

Erik, o Outgolfer
fonte
16 bytes: _I/L"aeiou"@Grz0(usando o operador de invariância I)
KarlKastor 28/05
@KarlKastor Eu sabia que tinha que haver algum operador assim ... obrigado. (BTW eu posso agora remover o zdemasiado, vou assumir entrada citado)
Erik o Outgolfer
4

Braquilog , 13 bytes

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

Experimente online!

Explicação

ḷ                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
Fatalizar
fonte
3

Alice , 28 bytes

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

Experimente online!

Saídas 1como verdade e nada como falsidade.

Explicação

Todo comando neste programa é executado no modo ordinal, mas com uma ligeira torção no modelo que me permite salvar um byte. Se uma nova linha for um valor de verdade aceitável, posso salvar mais um byte pelo mesmo método.

Linearizado, o programa é o seguinte:

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
Nitrodon
fonte
3

Python 3 , 72 71 bytes

-1 byte graças a @ovs

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

Experimente online!

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

JavaScript (ES6), 72 69 bytes

Economizou 3 bytes graças a Neil

Retorna um booleano.

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

Casos de teste

Arnauld
fonte
Salve alguns bytes substituindo as duas cadeias vazias por 2.
Shaggy
11
Você ainda precisa +''do final? Isso economizaria 3 bytes.
Neil
Eu gosto mais da idéia do @ Neil!
Shaggy
2

Mathematica, 113 bytes

PalindromeQ@StringCases[StringReplace[#,{Characters["aeiouAEIOU"]->"1",CharacterRange["A","z"]->"0"}],{"0","1"}]&
J42161217
fonte
Você pode se livrar de alguns bytes:PalindromeQ@StringReplace[#,{Characters@"aeiouAEIOU"->"1",LetterCharacter->"0",_->""}]&
Não é uma árvore
2

GolfScript , 42 bytes

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

Experimente online!

A parte difícil é gerar o alfabeto maiúsculo e minúsculo em uma sequência, que usaremos em uma função de filtro para filtrar as letras da entrada. Felizmente, como as strings no GolfScript são apenas matrizes de códigos com uma propriedade especial, para que possamos gerar os códigos de maneira eficiente. Veja como os geramos:

Primeiro, geramos o intervalo [0..122], 122 sendo o ponto de código para z. Em seguida, pegamos os elementos do elemento no índice 65 em diante. 65 é o ponto de código para A. No momento, temos [65..122]. Tudo bem, exceto que temos alguns pontos de código indesejados ([91..96]) lá. Então, primeiro criamos uma duplicata desse intervalo. Então, pegamos os elementos do índice 26 em diante e temos [91..122]. Depois disso, obtemos os elementos até e incluindo o índice 5. Agora temos [91..96]. Por fim, removemos esses elementos de nosso [65..122], deixando-nos [65..90, 97..122]. Esses são os pontos de código que queremos.

Agora que fizemos a lista de pontos de código do alfabeto superior / inferior, continuamos nossa função de filtragem. A função é mapeada para cada caractere na sequência de entrada, que, como eu disse inicialmente, é analisada como seu ponto de código. Então agora temos essencialmente [codepoint, [65..90, 97..122]]. Para descobrir se char codepointé uma letra, simplesmente pegamos seu índice na lista que criamos. Se não estiver lá, obteremos -1o índice.

No momento, obtemos um valor de falsey apenas se codepoint == 65, ou seja, o primeiro índice da nossa lista, já que somente então o índice seria 0. Mas um único incremento corrigirá esse problema e, agora, se codepointestiver em nossa lista, obtenha seu índice + 1, que é sempre um número positivo, portanto sempre verdadeiro, enquanto que, se não estiver lá, obteremos -1 + 1 = 0, ou seja, falsey.

Finalmente, aplicamos a função que descrevi a todos os caracteres da entrada e usamos apenas os caracteres para os quais a função retornou um resultado verdadeiro.

Em seguida, temos que determinar se cada caractere é uma vogal ou consoante. Como as vogais são menos que as consoantes, a criação de uma sequência de vogais para que verifiquemos essa condição é mais curta do que a criação de uma sequência de consoantes; portanto, verificamos se cada caractere é uma vogal. Mas, para verificar se a lista booleana é palíndrica, precisamos de booleanos, que não obtemos apenas com o índice + 1, pois isso pode resultar em qualquer número de [1..10] se o caractere for uma vogal. E, como a maioria das linguagens de golfe, essa também não tem boolfunção. Então, nós simplesmente usamos not not x, já que notsempre retorna um booleano. Mas espere; realmente precisamos de booleanos específicos? Como notsempre retorna um booleano, por que não removemos o segundonote verifique se cada caractere é uma consoante? Sim, é exatamente isso que faremos!

Após a verificação, que retorna uma lista de booleanos, verificamos se essa lista booleana que recebemos é um palíndromo, que é o que esse desafio nos pede que façamos. Bem, qual é a definição de um palíndromo? Sim, um palíndromo é uma lista ou sequência igual ao seu reverso. Então, como verificamos? Simples, duplicamos, fazemos o inverso e comparamos com a lista original. O resultado que obtemos é, finalmente , o que nosso código deve retornar.

Erik, o Outgolfer
fonte
11
Explicação gigante para um programa de 42 bytes. Agora eu acho que é bastante auto-explicativo ...
Erik o Outgolfer
2

PHP , 87 bytes

Regex versão PHP grátis. Adicionada uma "vogal", pois os stripos podem retornar 0, o que é falso no PHP.

Falha corrigida por Jörg.

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

Experimente online!

MIM
fonte
Contagem de mesmos bytes. for(;a&$c=$argn[$p++];)ctype_alpha($c)?$s.=stripos(_aeiou,$c)?0:1:0;echo$s==strrev($s);mas obter o resultado correto para cordas que contém de zero
Jörg Hülsermann
@ JörgHülsermann Obrigado.
ME
2

q / kdb +, 42 38 bytes

Solução:

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

Exemplo:

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

Explicação:

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'

Editar% s:

  • -4 bytes; mudar reversepara k equivalente|:
rua
fonte
2

CJam , 26 bytes

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

Experimente online!

-1 graças a Esolanging Fruit .

Erik, o Outgolfer
fonte
Você pode substituir 26,'af+por '{,97>para salvar um byte.
Esolanging Fruit
@EsolangingFruit uma resposta tão velho ...
Erik o Outgolfer
Um byte salvo há meio ano não é diferente de um byte salvo agora. Não é como se houvesse inflação de bytes ou algo assim: P
Esolanging Fruit
@EsolangingFruit Eu estava me referindo à minha experiência sempre em desenvolvimento no golfe ... é claro que você tem um crédito como sempre, não se preocupe!
Erik the Outgolfer
2

Braingolf,  4  3 bytes

&JP

-1 byte graças a Erik the Outgolfer

Acontece que eu tive o tempo Ptodo, mesmo antes deste desafio.

J no entanto, apesar de ter sido criado antes desse desafio, não foi enviado ao github antes do desafio, portanto ainda não é competitivo.

Explicação:

&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
Skidsdev
fonte
Por que você precisa n?
Erik the Outgolfer
@EriktheOutgolfer porque eu sou um idiota certificado
Skidsdev
Hmm, você esqueceu de removê-lo da explicação.
Erik the Outgolfer
@EriktheOutgolfer eu era gunna write "Erick", em seguida, atacar o c, mas apenas se parece com "Eriek"
Skidsdev
Isso não vai falhar 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 uma função que fornece TrueouFalse

Loovjo
fonte
Você pode salvar 2 bytes usando em "aeiouAEIOU".__contains__vez de lambda y:y.lower()in"aeiou".
Blender
1

CJam , 79 bytes

Primeiro tempo! (Fiz o que pude)

r{:X"AEIOUaeiou"#W>{X"BCDFGHJKLMNPQRSTVWXYZbdfghjklmnpqrstvwxyz"#W={'0}&}'1?~}%

Experimente online!

Iaka Noe
fonte
11
Bem-vindo ao PP&CG!
Greg Martin
1

Python 3 , 92 87 74 72 69 68 bytes

l=[c in'aeouiAEOUI'for c in input()if c.isalpha()]
print(l==l[::-1])

Experimente online!

Martmists
fonte
Você pode remover o espaço antes dafor c in s
Kritixi Lithos 28/17/17
E você pode remover a svariável substituindo sna segunda linha porinput().lower()
Kritixi Lithos 28/05
1

Ruby, 57 bytes

->s{x=s.scan(/\p{L}/).map{|c|c=~/[aeiou]/i};x==x.reverse}

Experimente online!

daniero
fonte
1

Bash , 82 bytes

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

Experimente online!

Recebe o nome como parâmetro, remove não leters, substitui vogais por 0, não vogais nem 0 por 1 e compara com o mesmo invertido.

Poderia jogar golfe um pouco mais, se conseguir trabalhar dupla ou tripla substituição

O status de saída é 0 para verdadeiro e 1 para não.

marcosm
fonte
Nas versões recentes do bash, i=${i^^*};converte ipara maiúsculas. Mas acho que só economiza um a-ze um aeiou, que é menor que os 10B que custa.
Peter Cordes
1

Japt v2.0a0, 19 11 bytes

k\L mè\v ê¬

Experimente online


Explicação

        :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.
Shaggy
fonte
0

APL (Dyalog) , 34 33 bytes

{(∧/⊢=⌽)'AEIOU'∊⍨⍵/⍨⍵∊⎕A}1∘(819⌶)

Experimente online!

Golfe em andamento.

Kritixi Lithos
fonte
Salvar um byte com819⌶⍨∘1
Adám
E dois com(⊢≡⌽)
Adám
… Mas eu posso resolver isso em 24. Quer alguma dica?
Adám
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}
Andrei Odegov
fonte
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))

teste

(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
RosLuP
fonte
0

Pyke, 12 bytes

#B)l1~-L{D_q

Experimente aqui!

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

PowerShell, 87 bytes

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

Obtenha uma cópia da sequência em que as vogais são 0 e as consoantes são 1, com todos os caracteres especiais removidos, compare essa sequência com uma versão reversa associada a uma sequência

Resultado:

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
colsw
fonte
0

Retina , 47 bytes

i(`[^a-z]

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

Experimente online!

Esta é apenas uma abordagem diferente para caracteres não alfabéticos

Christopher
fonte