Preâmbulo
Os números inteiros são sempre pares ou ímpares . Mesmo números inteiros são divisíveis por dois, números inteiros ímpares não são.
Quando você adiciona dois números inteiros, é possível inferir se o resultado será par ou ímpar, com base no fato de os somas serem pares ou ímpares:
- Par + Par = Par
- Par + Ímpar = Ímpar
- Ímpar + Par = Ímpar
- Ímpar + Ímpar = Par
Da mesma forma, quando você multiplica dois números inteiros, pode inferir se o resultado será par ou ímpar, com base nos fatores pares ou ímpares:
- Par * Par = Par
- Par * Ímpar = Par
- Ímpar * Par = Par
- Ímpar * Ímpar = Ímpar
Portanto, se você conhece a uniformidade ou a estranheza de todas as variáveis em uma expressão matemática que envolve apenas adição e multiplicação, é possível inferir se o resultado será par ou ímpar.
Por exemplo, podemos dizer com segurança que (68 + 99) * 37
resulta em um ímpar, porque um par mais um ímpar ( 68 + 99
) é um ímpar, e que ímpares vezes que outro ímpar ( odd * 37
) dá um ímpar.
Desafio
Escreva um programa ou função que utilize uma sequência contendo apenas os quatro caracteres eo+*
. Essa string representa uma expressão matemática dada na notação de prefixo envolvendo apenas adição ( +
) e multiplicação ( *
). Cada um e
representa um número par arbitrário e cada um o
representa um número ímpar arbitrário.
Sua tarefa é simplificar a expressão, imprimir ou retornar uma única e
ou com o
base em se o resultado da expressão é par ou ímpar.
Você pode assumir que a entrada sempre estará em notação de prefixo válida. Especificamente, cada um +
e *
sempre terá dois operandos correspondentes ocorrendo após ele. Esses operandos podem ser um único e
ou o
, ou outro +
ou *
expressão que, por sua vez, possui operandos.
Por exemplo, a entrada *+eoo
pode ser lida como mul(add(e, o), o)
ou (e + o) * o
em notação de infixo normal . O e
e o primeiro o
são os operandos correspondentes ao +
, +eo
e o último o
são os operandos correspondentes ao *
.
Apenas para esclarecer, aqui estão algumas entradas inválidas que possuem notação de prefixo incorreta:
eo
ooe
o+e
ee*
+*oe
+e*o
Uma única nova linha à direita na saída é boa, mas, caso contrário, uma planície e
para pares ou o
ímpares é tudo o que deve ser produzido.
O código mais curto em bytes vence.
Casos de teste
(Linhas vazias servem apenas para ajudar a separar visualmente casos semelhantes.)
e -> e
o -> o
+ee -> e
+eo -> o
+oe -> o
+oo -> e
*ee -> e
*eo -> e
*oe -> e
*oo -> o
+e+ee -> e
+e+eo -> o
+e+oe -> o
+e+oo -> e
+e*ee -> e
+e*eo -> e
+e*oe -> e
+e*oo -> o
+o+ee -> o
+o+eo -> e
+o+oe -> e
+o+oo -> o
+o*ee -> o
+o*eo -> o
+o*oe -> o
+o*oo -> e
*e+ee -> e
*e+eo -> e
*e+oe -> e
*e+oo -> e
*e*ee -> e
*e*eo -> e
*e*oe -> e
*e*oo -> e
*o+ee -> e
*o+eo -> o
*o+oe -> o
*o+oo -> e
*o*ee -> e
*o*eo -> e
*o*oe -> e
*o*oo -> o
++eee -> e
++eeo -> o
++eoe -> o
++eoo -> e
++oee -> o
++oeo -> e
++ooe -> e
++ooo -> o
+*eee -> e
+*eeo -> o
+*eoe -> e
+*eoo -> o
+*oee -> e
+*oeo -> o
+*ooe -> o
+*ooo -> e
*+eee -> e
*+eeo -> e
*+eoe -> e
*+eoo -> o
*+oee -> e
*+oeo -> o
*+ooe -> e
*+ooo -> e
**eee -> e
**eeo -> e
**eoe -> e
**eoo -> e
**oee -> e
**oeo -> e
**ooe -> e
**ooo -> o
+e+e+e+ee -> e
+o+o+o+oo -> o
*e*e*e*ee -> e
*o*o*o*oo -> o
+e+o+e+oe -> e
+o+e+o+eo -> o
*e*o*e*oe -> e
*o*e*o*eo -> e
+e*e+e*ee -> e
+o*o+o*oo -> o
*e+e*e+ee -> e
*o+o*o+oo -> o
+**++*+*eeoeeooee -> e
+**++*+***eooeoeooeoe -> e
+**+***+**++**+eooeoeeoeeoeooeo -> o
+e*o*e**eoe -> e
+*e+e+o+e**eeoe -> e
**o++*ee*++eoe*eo+eoo -> o
fonte
eval
OK?Respostas:
CJam,
181713 bytesObrigado ao aditsu por salvar 4 bytes.
Experimente o conjunto de testes aqui. (O conjunto de testes é muito longo para o link permanente. Basta copiá-los da especificação do desafio.)
Explicação
fonte
Pitão,
1614 bytesO próprio Pyth pode avaliar uma string, que está na sintaxe do Pyth. Portanto, substituo
e
eo
por4
e5
. Em seguida, a avaliação fornecerá um número par ou ímpar e eu posso imprimir facilmente o resultado.Experimente on-line: Demonstration or Test Suite
Explicação:
Explicação adicional para a substituição.
G
é uma variável inicializada com o alfabetoabc...xyz
.U9
é a lista[0, 1, ..., 8]
.XzGU9
substitui as letras do alfabeto pelos valores da lista. Então,a
é substituído por0
,b
com1
, ...,e
com4
, ...,i
com8
,j
com0
, ... eo
com5
. Portanto, soue
substituído por um número par eo
por um número ímpar. Todas as outras substituições não têm efeito algum.fonte
Perl,
504540 caracteres(Código de 39 caracteres + opção de linha de comando de 1 caractere.)
Exemplo de execução:
fonte
while/../
?sed
versão… Obrigado, @primo.1while s/\+oe...
. Eu também tenho certeza que[+*]
pode ser substituído por\W
.gema
me enlouquecendo…)Retina , 29 bytes
Para a versão conveniente de um arquivo, o
-s
sinalizador é usado.Nós trocar expressões ímpares (
*oo
,+oe
,+eo
) parao
até que possamos, em seguida, trocar as restantes expressões símbolo letras letras ae
. Repetimos isso até que possamos e a letra final é a nossa saída.(Essa solução é semelhante à resposta Perl de manatwork .)
Experimente online! (de Dennis)
fonte
Python 2, 90
A
iter
função é uma boa maneira de transformar a string de entrada em uma fila FIFO que lembra quanto da string foi analisada nas chamadas def
. É idempotente, portanto, é inofensivo chamá-lo novamente quando a entrada já é um iterador e não uma sequência. A metade da resposta que começa comor'oe'
... parece que deveria ser jogável, mas não consegui encontrar nada.-1 graças ao Sp3000.
fonte
iter
realmente incomodam minha mente.eval
:def f(s,e=0,o=1):i=iter(s);a=next(i);return'eo'[eval(a*(a>'a')or f(i)+a+f(i))%2]
Mathematica,
9184 bytesProcurando uma maneira de comprimir isso ...
fonte
//.
é mais curto queFixedPoint
.Python 2, 80 bytes
Isso se baseia na resposta muito inteligente do feersum que usa um
iter
para implementar operações de notação polonesa. A nova idéia é usareval
para avaliar as expressões+
e*
comeval(f(i)+a+f(i))
, onde o operadora
é colocado no infixo entre os resultados recursivos. O eval usa as ligaçõese=0,o=1
nos argumentos da função opcional. A saída é então tomada mod 2.fonte
e+o
, portanto, precisa das variáveis para se referir a números.C, 79 bytes
Recursão direta. Depende de algumas propriedades (coincidentes?) Em bits dos quatro caracteres de entrada permitidos.
fonte
Utilitários Shell + GNU, 33
A entrada é retirada do STDIN.
Isso faz o mesmo truque de reverter a entrada e avaliar com uma calculadora baseada em pilha - nesse caso
dc
. Poderíamos substituire
eo
por0
e1
, mas é necessário inserir espaços para impedir a análise gananciosa dos dígitos nos números incorretos.Em vez disso,
e
é substituído porK
qual é odc
comando para enviar a precisão atual para a pilha, que por padrão é 0. Eo
é substituído porO
qual é odc
comando para enviar a base de saída atual para a pilha. Isso precisa ser estranho, então o definimos como 15Fo
antes de fazer qualquer outra coisa em CC.Então é simplesmente uma questão de pegar o mod 2 e imprimir
2%p
. Os únicos valores possíveis são agora0
e1
, portanto, não importa que a base de saída seja 15. Em seguida,tr
converta de volta parao
oue
.Eu gosto que, se você apertar os olhos, essa fonte quase se parece
dc Forever OK
.fonte
Sério , 24 bytes
Uma manipulação de pilha mais eficiente provavelmente poderia tornar isso mais curto, mas meh, estou feliz com isso.
Recebe entrada como uma string, como
"+*oee"
Experimente online (a entrada deve ser inserida manualmente)
Explicação:
fonte
Ruby, 61 bytes
Usando análise de descida recursiva e álgebra booleana.
A função lê um caractere de stdin por vez. Se lê um
+
ou a*
, chama-se duas vezes para determinar ímpar ou par. A função retornatrue
para ímpar efalse
paraeven
. Os operadores^
XOR e&
AND são usados para determinar "estranheza" das expressões de adição e multiplicação, respectivamente.Aqui está uma versão não destruída:
Obrigado @Shel por apontar um bug na versão inicial.
fonte
+ee
dáo
. Eu gosto da ideia #f^f
por!f^f
ef&f
comf|f
e funciona. Programa para executar casos de teste: pastebin.com/ufXfd1vcf^f
ef&f
virei$_==?e
e em?e:?o
vez disso :) #Minkolang 0.14 , 40 bytes
Tentei fazer um método inteligente de avaliação, mas acontece que quaisquer valores adicionados à caixa de códigos fora do espaço original nunca serão atingidos pelo contador de programas. Então, eu fiz um método de avaliação menos inteligente. : P
Experimente aqui.
Explicação
fonte
JavaScript,
11010694 bytesCertamente não é a menor solução, mas provavelmente a menor solução possível em uma linguagem detalhada como o JavaScript!
fonte
?:
.while(i.length>2)i=i.replace(/[+*][eo]{2}/,function(o){return"+oe+eo*oo".indexOf(o)>=0?"o":"e"})
. Ou se você mudar para a função de seta gorda do ECMAScript 6, entãowhile(i.length>2)i=i.replace(/[+*][eo]{2}/,o=>"+oe+eo*oo".indexOf(o)>=0?"o":"e")
. Infelizmente, porém, o requisito diz programa ou função, enquanto seu código atual é um trecho. Ele deve lidar com entrada e saída ou argumento e valor de retorno.i
como você disse.O ,
24201918 bytesPega entrada, inverte, atribui
e
a 2 eo
a 1 epublica no Tumblravalia como código O.Explicação:
fonte
GNU Sed, 36
Depois de postar Eu vi isso exatamente a mesma abordagem do Perl resposta @ manatwork e resposta Retina de @ randomra . Então eu acho que posso ir até o fim e pedir emprestado o seu
\W\w\w
também.Obrigado ao @Ruud por remover 4 bytes.
fonte
+
, perde 2 bytes por escapar|
, mas o resultado final é que você ganha 1 byte por deixar cair a opção-r
.|
necessidades de escapar quando-r
não é usado. Ainda assim, mais 2 bytes de pontuação - obrigado!Haskell, 160 bytes
Ligue
f
.fonte
JavaScript,
9271 bytesEstá um pouco ofuscado, mas eu queria fazer algo usando
eval
operadores bit a bit. Anotado:A repetição de
(e[…]>"e")
me irrita um pouco, mas o seguinte também não é melhor (103 bytes):Portanto, no final, a abordagem da @ Arkain com correspondência simples de substring é superiour. Transformado em uma função, com algumas otimizações:
fonte
Dardo, 173 bytes
Isso não é competitivo, mas tanto faz. A essência da solução é, começando em 0, substituindo recursivamente todos os operadores pela avaliação do par de caracteres após esse operador e removendo-os da lista.
fonte
Haskell, 231 bytes
Aqui está uma abordagem usando uma linguagem séria;)
Versão Golfed:
Exemplo:
Versão ungolfed e bastante abrangente:
Exemplo:
Características: Correspondência de padrões e recursão.
fonte
Jolf, 11 bytes
(Não competitivo, pois o idioma é posterior à pergunta.) Experimente aqui!
(Substitua
\x12
pelo caractere real\x12
. Isso deve ser feito automaticamente no intérprete.)Explicação:
fonte
Python 3,
171145135 bytesNão é competitivo, mas me diverti fazendo isso, então não consegui guardar para mim. Diferentemente da entrada (muito inteligente) do iterador recursivo do Python por feersum , esta reverte a entrada e faz uma boa e antiga análise baseada em pilha da notação polonesa reversa.
fonte
callable()
é elegante, mas longo. (A reversão da condição e a remoçãonot
seriam mais curtas.) Verifique se m é inteirom in[0,1]
seria menor, mas verificar se c é o valorc in'eo'
seria ainda mais curto. Posteriormente, é o mesmo quec>'a'
neste caso.for
:s+=[c>'e'if c>'a'else{'*':o.and_,'+':o.xor}[c](s.pop(),s.pop())]
s.pop()
(duas vezes) cada loop. Eu não me incomodei em testar até agora; mas ei, o ponto é discutido agora.operator
módulo?bool.__and__()
ebool.__xor__()
são mais prático:s+=[c>'e'if c>'a'else getattr(s.pop(),{'*':'__and__','+':'__xor__'}[c])(s.pop())]
. Mas com base em gnibbler da ponta de corte , que pode ser transformado ems+=[c>'e'if c>'a'else getattr(s.pop(),'__'+('axnodr'[c>'*'::2])+'__')(s.pop())]
.^
,&
) e seusoperator
equivalentes, esquecendo os métodos que realmente os implementam. Ah, ereversed()
agora foi descartada graças a outra das dicas de golfe em Python .Haskell,
9894 bytesDesculpe incomodá-lo com mais uma tentativa de Haskell; só queria provar que é muito bem possível em menos de 100 bytes.
Define uma função
p
que aceita qualquer expressão válida como parâmetro e retorna o resultado como uma sequência de comprimento 1.Exemplo:
A função funciona reduzindo repetidamente o operador mais à direita na string até que nenhum operador seja deixado.
fonte
Adicionar ++ , 46 bytes
Experimente online!
O rodapé simplesmente enumera todas as entradas de exemplo e suas saídas correspondentes.
Como funciona
Como uma perda das respostas aqui, isso usa substituição e avaliação. Nossa principal função é
f
eg
é uma função auxiliar. Usaremos"*e*o*e*oe"
(que ée
) como exemplo.f
começa pegando a string de entrada e revertendo-a, produzindo"eo*e*o*e*"
. Em seguida, mapeamosg
cada elemento:g
começa duplicando o argumento, para manter uma cópia até o comando final. Em seguida, verificamos se o argumento está na string"oe"
, produzindo 1 para letras e 0 para*
ou+
. Em seguida, pressionamos o argumento novamente e verificamos se é igual a"e"
. Este resultado é então adicionado à verificação anterior. Isso gera 0 para um*
ou+
, 1 parao
e 2 parae
. Em seguida, tomamos o OR lógico entre esse valor e o argumento. Se o valor for 0 , ele será substituído pelo argumento (*
ou seja+
), caso contrário, ele será deixado como está (ou seja, 1 e 2 ).Isso converte todas as letras no verso da entrada em um valor numérico. Em seguida, juntamos cada elemento por espaços, para garantir que os dígitos não sejam concatenados. Para o nosso exemplo, isso gera a string
"2 1 * 2 * 1 * 2 *"
. Podemos então avaliar isso, usando a notação postfix de Add ++, produzindo 8 . Em seguida, tomamos a paridade desse valor, produzindo 0 para números pares e 1 para números ímpares, antes de indexar na sequência"eo"
e retornar a letra correspondente.fonte