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 1
es 0
onde cada consoante está 1
e 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. y
nã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 = '')
code-golf
string
palindrome
HyperNeutrino
fonte
fonte
Respostas:
05AB1E , 9 bytes
Experimente online!
-2 graças a Adnan .
Isso ataca exatamente o ponto de dor de Jelly. Ele usa
l
eA
, equivalentes de 1 byte para o JellyŒl
eØa
respectivamente.fonte
AÃ
porá
eDR
porÂ
.á
, não sabia o queÂ
faz, obrigado!00
paraFF
a esses 256 caracteres, ver a resposta JellyGelatina , 11 bytes
Experimente online!
Versões alternativas:
É claro que um desafio para apreciar Dennis deve ter uma resposta no idioma dele.
fonte
função de código de máquina x86 de 32 bits,
4241 bytesAtualmente, 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:
4140 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):
4544 bytescódigo de máquina x86-64 (com ponteiros de 32 bits, como o ABI x32):
4443 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
byte
tamanho 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 documentada
salc
para definir AL a partir de CF, da mesma maneira quesbb al,al
faria. É 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:
bt
, inspirado por uma saída agradável do compilador paraswitch
.stosb
.cmp
/salc
não é uma opção, porquesalc
funciona apenas para CF e 0xFF-0 não define CF.sete
tem 3 bytes, mas evitaria oinc
exterior 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.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 quesetcc
em muitas CPUs (por exemplo, 3 uops vs. 1 no Skylake), mas uma verificação de bitmap combt/salc
ainda é 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.
strlen
implementação do int80h.org .Uma versão de 64 bits dessa função poderia usar
sbb eax,eax
, que é de apenas 2 bytes em vez de 3 parasetc al
. Também seria necessário um byte extra paradec
ounot
no 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
%if
condicionais. 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
rsp
e o ponteiro de entrada no baixo espaço de endereço 4G.Eu olhei para mexer com o DF (a bandeira de direção que controla
lodsd
/scasd
e 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 bytessub 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,r32
ainda funciona com alto lixo no índice de bits. Simplesmente não está documentado do jeito queshr
está.Em vez de
bt / sbb
obter o bit dentro / fora do CF, use um shift / mask para isolar o bit que queremos do bitmap.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 dedec eax
(também 2B em x86-64) para ainda produz um valor adequadobool
/ 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 ^ 0x20
para forçar para maiúsculas e zerar o restante do eax com 3 bytesand 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 osub
ecmp
.)Ele perde para
bt
/salc
no 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, eax
ainda trabalha com alto teor de lixo em eax. Aparentemente mascara o deslocamento contar da mesma formashr r32, cl
faz (olhando apenas para os baixos 5 bits de cl). É diferente debt [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, src
Com 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 abt
versã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 IMC2shrx eax, edx, eax
é de 5 bytes, contra apenas 2 bytes parashr eax, cl
. O usobextr
precisa de 2 bytesmov 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
%if
condicionais. 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
lods
antes dele e na parte inferior, em vez de apenas um na parte superior do loop.fonte
Retina ,
49 4745 bytesExperimente 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.
fonte
\D
2
trabalho para salvar-lhe um par de bytes maisT`lL`2
?PHP, 82 bytes
Experimente online!
fonte
(bool)
e remover$s=
a==$s
seleção e para economizar 1 byte.(bool)
por apenas0||
para dizer falso, ou ... em vez disso, economizando 3 bytes adicionais.\w
para word caracteres em vez de aa-z
?\w
conté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 booleanoMATL, 14 bytes
Experimente no MATL Online .
Aqui está uma versão ligeiramente modificada para verificar todos os casos de teste.
Explicação
fonte
Haskell,
84757469 bytes-10 graças a @nimi
-5 graças a @Zgarb
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!
fonte
filter
seguida,map
mesmo que você precise mudar para não isento de poit. 2) O<$>id
é supérfluo.f x=(==)<*>reverse$[elem c"aeiouAEIOU"|c<-x,c
elem['A'..'Z']++['a'..'z']]
.c
e"
para mais um byte.c`elem`['A'..'Z']++['a'..'z']
pode ser reduzido para'@'<c,c<'{','`'<c||c<'['
Pitão,
1815 bytesExperimente aqui.
-2 graças a KarlKastor e, posteriormente, -1.
fonte
_I/L"aeiou"@Grz0
(usando o operador de invariância I)z
demasiado, vou assumir entrada citado)Braquilog , 13 bytes
Experimente online!
Explicação
fonte
Alice , 28 bytes
Experimente online!
Saídas
1
como 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:
fonte
Python 3 ,
7271 bytes-1 byte graças a @ovs
Experimente online!
fonte
def f(s):s=[c in'AEIOU'for c in s.upper()if'@'<c<'['];return s==s[::-1]
para 71 bytesJavaScript (ES6),
7269 bytesEconomizou 3 bytes graças a Neil
Retorna um booleano.
Casos de teste
Mostrar snippet de código
fonte
2
.+''
do final? Isso economizaria 3 bytes.Mathematica, 113 bytes
fonte
PalindromeQ@StringReplace[#,{Characters@"aeiouAEIOU"->"1",LetterCharacter->"0",_->""}]&
GolfScript , 42 bytes
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 paraA
. 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 charcodepoint
é uma letra, simplesmente pegamos seu índice na lista que criamos. Se não estiver lá, obteremos-1
o í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, secodepoint
estiver 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
bool
função. Então, nós simplesmente usamosnot not x
, já quenot
sempre retorna um booleano. Mas espere; realmente precisamos de booleanos específicos? Comonot
sempre retorna um booleano, por que não removemos o segundonot
e 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.
fonte
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.
Experimente online!
fonte
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 zeroq / kdb +,
4238 bytesSolução:
Exemplo:
Explicação:
Editar% s:
reverse
para k equivalente|:
fonte
CJam , 26 bytes
Experimente online!
-1 graças a Esolanging Fruit .
fonte
26,'af+
por'{,97>
para salvar um byte.Braingolf,
43 bytes-1 byte graças a Erik the Outgolfer
Acontece que eu tive o tempo
P
todo, 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:
fonte
n
?Alex A.
?Python 2, 83 bytes
Define uma função que fornece
True
ouFalse
fonte
"aeiouAEIOU".__contains__
vez delambda y:y.lower()in"aeiou"
.CJam , 79 bytes
Primeiro tempo! (Fiz o que pude)
Experimente online!
fonte
Python 3 ,
928774726968 bytesExperimente online!
fonte
for c in s
s
variável substituindos
na segunda linha porinput().lower()
Ruby, 57 bytes
Experimente online!
fonte
Bash , 82 bytes
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.
fonte
i=${i^^*};
convertei
para maiúsculas. Mas acho que só economiza uma-z
e umaeiou
, que é menor que os 10B que custa.Japt v2.0a0,
1911 bytesExperimente online
Explicação
fonte
APL (Dyalog) ,
3433 bytesExperimente online!
Golfe em andamento.
fonte
819⌶⍨∘1
(⊢≡⌽)
PowerShell, 108 bytes
fonte
Axioma, 126 bytes
teste
fonte
Pyke, 12 bytes
Experimente aqui!
fonte
PowerShell, 87 bytes
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:
fonte
Retina , 47 bytes
Experimente online!
Esta é apenas uma abordagem diferente para caracteres não alfabéticos
fonte