Bem, isso é estranho ... não, espere, isso é mesmo!

70

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) * 37resulta 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 erepresenta um número par arbitrário e cada um orepresenta um número ímpar arbitrário.

Sua tarefa é simplificar a expressão, imprimir ou retornar uma única eou com obase 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 eou o, ou outro +ou *expressão que, por sua vez, possui operandos.

Por exemplo, a entrada *+eoopode ser lida como mul(add(e, o), o)ou (e + o) * oem notação de infixo normal . O ee o primeiro osão os operandos correspondentes ao +, +eoe o último osã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 epara 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
Passatempos de Calvin
fonte
8
Podemos usar 1 e 0 em vez de e e o como entrada?
Gdts_in_the_code
8
@ghosts_in_the_code Não, desculpe.
Calvin's Hobbies
2
Está usando evalOK?
xnor
11
@xnor Claro. O que quer que funcione.
Hobbies de Calvin
2
Duvido que eu possa usar isso para vencer os 13 bytes já postados, mas percebo que a adição corresponde a uma exclusiva ou multiplicação e simples ou.
WGroleau

Respostas:

43

CJam, 18 17 13 bytes

Obrigado ao aditsu por salvar 4 bytes.

qW:O%eu~"eo"=

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

q     e# Read the input.
W:O   e# Push a -1 and store it in variable O.
%     e# Use the -1 to reverse the string, because CJam's stack-based nature and the
      e# commutativity of the operators means we can evaluate the code in postfix notation.
eu    e# Convert the string to upper case, turning 'e' into 'E' (a variable with even value
      e# 14) and 'o' into 'O' (which we've stored the odd value -1 in).
~     e# Evaluate the string as CJam code, leaving the result on the stack.
"eo"= e# Use the result as an index into the string "eo". CJam's indexing is cyclic so it
      e# automatically takes inputs modulo 2. Negative indices also work as expected.
Martin Ender
fonte
27

Pitão, 16 14 bytes

@"eo".vjdXzGU9

O próprio Pyth pode avaliar uma string, que está na sintaxe do Pyth. Portanto, substituo ee opor 4e 5. 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:

@"eo".vjdXzGU9   implicit: z = input string
         XzGU9   replace "e" in z with 4 and "o" with 5
       jd        put a space between each char
     .v          evaluate it (Pyth style)
@"eo"            and print "e" or "o"

Explicação adicional para a substituição. Gé uma variável inicializada com o alfabeto abc...xyz. U9é a lista [0, 1, ..., 8]. XzGU9substitui as letras do alfabeto pelos valores da lista. Então, aé substituído por 0, bcom 1, ..., ecom 4, ..., icom 8, jcom 0, ... e ocom 5. Portanto, sou esubstituído por um número par e opor um número ímpar. Todas as outras substituições não têm efeito algum.

Jakube
fonte
Por que você está revertendo a expressão? Além disso, você não precisa usar o módulo 2 do resultado, ou a indexação está em andamento?
Xnor
O @xnor acessando um elemento em uma string é feito com o modulo wrapping. Portanto, não há necessidade de módulo 2.
Jakube
@ xnor Mas obrigado pela coisa inversa. Claro que isso não é necessário. (Eu sou um pouco pequena hospedaria cansado hoje.)
Jakube
16

Perl, 50 45 40 caracteres

(Código de 39 caracteres + opção de linha de comando de 1 caractere.)

1while s/\+oe|\+eo|\*oo/o/||s/\W\w\w/e/

Exemplo de execução:

bash-4.3$ echo -n '**o++*ee*++eoe*eo+eoo' | perl -pe '1while s/\+oe|\+eo|\*oo/o/||s/\W\w\w/e/'
o
homem a trabalhar
fonte
Que tal while/../?
Primo
Doh. Eu estúpido. Na verdade, usei essa condição enquanto tentava sua sedversão… Obrigado, @primo.
Manatwork
Ou melhor ainda 1while s/\+oe.... Eu também tenho certeza que [+*]pode ser substituído por \W.
Primo
Obrigado novamente, @primo. Acho que devo me concentrar em uma única solução uma vez. ( gemame enlouquecendo…)
manatwork
A mesma abordagem com o Sed agora 2 bytes mais curta!
Digital Trauma
13

Retina , 29 bytes

(+`\*oo|\+(eo|oe)
o
\W\w\w
e

Para a versão conveniente de um arquivo, o -ssinalizador é usado.

Nós trocar expressões ímpares ( *oo, +oe, +eo) para oaté que possamos, em seguida, trocar as restantes expressões símbolo letras letras a e. 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)

randomra
fonte
12

Python 2, 90

def f(s):i=iter(s);a=next(i);return(a>'a')*a or'oe'[f(i)==f(i)if'*'<a else'e'in f(i)+f(i)]

A iterfunção é uma boa maneira de transformar a string de entrada em uma fila FIFO que lembra quanto da string foi analisada nas chamadas de f. É 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 com or'oe'... parece que deveria ser jogável, mas não consegui encontrar nada.

-1 graças ao Sp3000.

feersum
fonte
Ótima solução! Funções recursivas usando iterrealmente incomodam minha mente.
Xnor
3
Aqui está uma maneira de calcular a aritmética diretamente com 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]
xnor
11
@ xnor Você também pode postar isso como resposta. É muito diferente desta solução.
feersum
9

Mathematica, 91 84 bytes

#//.s_:>s~StringReplace~{"+ee"|"+oo"|"*ee"|"*eo"|"*oe"->"e","+eo"|"+oe"|"*oo"->"o"}&

Procurando uma maneira de comprimir isso ...

LegionMammal978
fonte
3
//.é mais curto que FixedPoint.
Alephalpha #
8

Python 2, 80 bytes

def f(s,e=0,o=1):i=iter(s);a=next(i);return(a>'a')*a or'eo'[eval(f(i)+a+f(i))%2]

Isso se baseia na resposta muito inteligente do feersum que usa um iterpara implementar operações de notação polonesa. A nova idéia é usar evalpara avaliar as expressões +e *com eval(f(i)+a+f(i)), onde o operador aé colocado no infixo entre os resultados recursivos. O eval usa as ligações e=0,o=1nos argumentos da função opcional. A saída é então tomada mod 2.

xnor
fonte
Isso também funciona no python 3. A propósito, como eval precisa das ligações "e = 0, o = 1"?
karhell
@karhell Avalia expressões como e+o, portanto, precisa das variáveis ​​para se referir a números.
Xnor
8

C, 79 bytes

Recursão direta. Depende de algumas propriedades (coincidentes?) Em bits dos quatro caracteres de entrada permitidos.

f(){int c=getchar();return c&4?c:c&1?f()^f()^'e':f()&f();}main(){putchar(f());}
Ruud Helderman
fonte
8

Utilitários Shell + GNU, 33

dc -eFo`rev|tr oe OK`2%p|tr 10 oe

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 substituir ee opor 0e 1, 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 por Kqual é o dccomando para enviar a precisão atual para a pilha, que por padrão é 0. E oé substituído por Oqual é o dccomando para enviar a base de saída atual para a pilha. Isso precisa ser estranho, então o definimos como 15 Foantes 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 agora 0e 1, portanto, não importa que a base de saída seja 15. Em seguida, trconverta de volta para oou e.


Eu gosto que, se você apertar os olhos, essa fonte quase se parece dc Forever OK.

Trauma Digital
fonte
5

Sério , 24 bytes

,R'2'e(Æ'1'o(Æ£ƒ'e'o2(%I

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:

,R        get input and reverse it
'2'e(Æ    replace all "e"s with "2"s
'1'o(Æ    replace all "o"s with "1"s
£ƒ        cast as function and call
'e'o2(%I  push "e" if result is even, else "o"
Mego
fonte
5

Ruby, 61 bytes

Usando análise de descida recursiva e álgebra booleana.

def f
gets(1)==?+?f^f : ~/\*/?f&f : $_==?o
end
puts f ? ?o:?e

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 retorna truepara ímpar e falsepara even. 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:

def f
  x = gets(1)
  case x
  when '+'
    f ^ f
  when '*'
    f & f
  else
    x == 'o'
  end
end

puts f ? 'o' : 'e'

Obrigado @Shel por apontar um bug na versão inicial.

daniero
fonte
11
Isso não funciona, +eeo. Eu gosto da ideia #
Shelvacu
substitua f^fpor !f^fe f&fcom f|fe funciona. Programa para executar casos de teste: pastebin.com/ufXfd1vc
Shelvacu 3/15/15
11
Obrigado, boa captura! Parece que me confundi um pouco lá. Nice suite de teste também! Teste-driven é o caminho a percorrer, também quando golfe :)
daniero
@Shel Aha ..! Eu mudei de volta f^fe f&fvirei $_==?ee em ?e:?ovez disso :) #
daniero 03/12/2015
11
Uau, aprender algo novo todos os dias ... ruby-doc.org/core/Regexp.html#method-i-7E
Shelvacu
4

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

$o"eo+*"r0I4-[4g1Z2*1F]l*"e"+O.
0f1f+f*f

Experimente aqui.

Explicação

$o                                Read in whole input as characters
  "eo+*"                          Push these characters onto the stack (in reverse order)
        r                         Reverse the stack
         I4-                      Push the length of the stack - 4
            [                     For loop; pop n and repeat that many times
             4g                   Get the item at the fourth index and put it on top
               1Z                 Pops n and pushes first index of n in stack
                 2*               Multiply by 2
                   1F             Gosub; goes to codebox(2n,1) to be returned to
                     ]            Close for loop
                      l*          Multiply by 10
                        "e"+      Add 101 ("o" is 111)
                            O.    Output as character and stop.
0f1f+f*f                          Does the appropriate operation then returns to F
El'endia Starman
fonte
11
Woohoo! bom ol 'shell bate um idioma (semi-) de golfe ;-P
Digital Trauma
4

JavaScript, 110106 94 bytes

while(i.length>2)i=i.replace(/([+*][eo]{2})/,(o,e)=>{return"+oe+eo*oo".indexOf(o)<0?"e":"o"});

Certamente não é a menor solução, mas provavelmente a menor solução possível em uma linguagem detalhada como o JavaScript!

Arkain
fonte
O uso de grupos que não capturam é bom para o desempenho, mas ruim para o tamanho do código. Melhor removê-los ?:.
Manatwork 03/12/2015
concordou ... e assim modificado.
Arkain 3/15/15
Deu outra olhada agora. Seu código pode ser reduzido um pouco mais para 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ão while(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.
Manatwork 03/12/2015
11
Infelizmente, para ser válido neste site, não podemos assumir que uma variável já exista. Você terá que fazer isso funcionar icomo você disse.
Alex A.
11
@Arkain, você não precisa capturar um grupo na expressão regular, pois você usará toda a substring correspondente como uma única peça. Pelo mesmo motivo, não há necessidade de passar o parâmetro e para o retorno de chamada.
manatwork
4

O , 24 20 19 18 bytes

i`2:e;1:o;~2%'o'e?

Pega entrada, inverte, atribui ea 2 e oa 1 e publica no Tumblr avalia como código O.

Explicação:

i` Obtenha entrada e inverta-a, porque O usa notação postfix
2: e; Atribua `e` a 2
1: o; Atribua `o 'a 1
~ 2% de avaliação e verifique se o resultado é uniforme
'o'e? Saída 'e' se for par, 'o' se for ímpar
Estágio
fonte
4

GNU Sed, 36

:
s/*oo\|+eo\|+oe/o/
t
s/\W\w\w/e/
t

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\wtambém.

Obrigado ao @Ruud por remover 4 bytes.

Trauma Digital
fonte
Sem os parênteses, agora compensa abandonar o regexp estendido. Você ganha 2 bytes por não escapar +, perde 2 bytes por escapar |, mas o resultado final é que você ganha 1 byte por deixar cair a opção -r.
Ruud Helderman
@ Ruud Isso mesmo. Eu tentei antes, mas não percebi as |necessidades de escapar quando -rnão é usado. Ainda assim, mais 2 bytes de pontuação - obrigado!
Digital Trauma
2

Haskell, 160 bytes

Ligue f.

f=until((==1).l)r
r s|l s<3=s|3#s?o=r('o':3%s)|3#s?sequence["+*","oe","oe"]=r('e':3%s)|0<1=1#s++r(1%s)
l=length
(#)=take
(%)=drop
(?)=elem
o=["+eo","+oe","*oo"]
Leif Willerts
fonte
2

JavaScript, 92 71 bytes

f=i=>i>"0"?i:f(i.replace(/.[eo]{2}/,e=>"eo"[eval((e[1]>"e")+"^&"[+(e[0]<"+")]+(e[2]>"e"))]))

Está um pouco ofuscado, mas eu queria fazer algo usando evaloperadores bit a bit. Anotado:

f = (i) => // function(i) { return
    i>"0"  // i[0] == "o" || i[0] == "e" :-) - the characters `*` and `+` are both <"0"
      ? i  // finish
      : f(i.replace( // recursively repeat with
          /.[eo]{2}/, // first occurrence of "something" followed by two values
          (e) =>    // replaced by
              "eo"[ // string indexing
                eval(
                    (e[1]>"e")        // e[1] == "o" ? "true" : "false"
                  + "^&"[+(e[0]<"+")] // e[0] == "+" ? "^" : "&"
                  + (e[2]>"e")        // e[2] == "o" ? "true" : "false"
                )
              ]     // like eval(…) ? "o" : "e"
        ))

A repetição de (e[…]>"e")me irrita um pouco, mas o seguinte também não é melhor (103 bytes):

f=i=>i>"0"?i:f(i.replace(/e|o/g,x=>+(x>"e")).replace(/.\d\d/,e=>"eo"[eval(e[1]+"^&"[+(e[0]<"+")]+e[2])]))

Portanto, no final, a abordagem da @ Arkain com correspondência simples de substring é superiour. Transformado em uma função, com algumas otimizações:

f=i=>i>"0"?i:f(i.replace(/.[eo]{2}/,v=>"eo"[+"+oe+eo*oo".includes(v)]))
Bergi
fonte
1

Dardo, 173 bytes

f(i){var l=i.split(''),e='e',o='o';g(p){if(l[p]!=e&&l[p]!=o){var x=p+1,y=p+2;g(x);g(y);l[p]=l[p]=='+'?l[x]!=l[y]?o:e:l[x]==o?l[y]:e;l.removeRange(x,p+3);}}g(0);print(l[0]);}

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.

usuario
fonte
1

Haskell, 231 bytes

Aqui está uma abordagem usando uma linguagem séria;)

Versão Golfed:

p(s:_)[]=s
p s(x:y)=p(r$x:s)y
r[]=[]
r('e':'e':'+':x)=r$'e':x
r('e':'o':'+':x)=r$'o':x
r('o':'e':'+':x)=r$'o':x
r('o':'o':'+':x)=r$'e':x
r('e':'e':'*':x)=r$'e':x
r('e':'o':'*':x)=r$'e':x
r('o':'e':'*':x)=r$'e':x
r('o':'o':'*':x)=r$'o':x
r x=x

Exemplo:

*Main> p [] "+**+***+**++**+eooeoeeoeeoeooeo"
'o'

Versão ungolfed e bastante abrangente:

type Stack = String

parse :: String -> Char
parse = parse' []

parse' :: Stack -> String -> Char
parse' (s:_) []     = s
parse' s     (x:xs) = parse' (reduce $ x:s) xs

reduce :: Stack -> Stack
reduce [] = []
reduce ('e':'e':'+':xs) = reduce $ 'e':xs
reduce ('e':'o':'+':xs) = reduce $ 'o':xs
reduce ('o':'e':'+':xs) = reduce $ 'o':xs
reduce ('o':'o':'+':xs) = reduce $ 'e':xs
reduce ('e':'e':'*':xs) = reduce $ 'e':xs
reduce ('e':'o':'*':xs) = reduce $ 'e':xs
reduce ('o':'e':'*':xs) = reduce $ 'e':xs
reduce ('o':'o':'*':xs) = reduce $ 'o':xs
reduce xs               = xs

Exemplo:

*Main> parse "+**+***+**++**+eooeoeeoeeoeooeo"
'o'

Características: Correspondência de padrões e recursão.

user3389669
fonte
1

Jolf, 11 bytes

(Não competitivo, pois o idioma é posterior à pergunta.) Experimente aqui!

FVyAi"oe"@\x12

(Substitua \x12pelo caractere real \x12. Isso deve ser feito automaticamente no intérprete.)

Explicação:

FVyAi"oe"@\x12
    i          input
          \x12 character 12
         @     char code at
   A "oe"      replace all os with 1s and all es with 2s
  y            eval as jolf, returning the answer
 V             return parity "even" or "odd"
F              get first character
               implicit output
Conor O'Brien
fonte
1

Python 3, 171 145 135 bytes

Nã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.

def p(i):
 s=[]
 for c in i[::-1]:
  s+=[c>'e'if c>'a'else getattr(s.pop(),'__'+('axnodr'[c>'*'::2])+'__')(s.pop())]
 return'eo'[s[0]]
Tim Pederick
fonte
Isso callable()é elegante, mas longo. (A reversão da condição e a remoção notseriam mais curtas.) Verifique se m é inteiro m in[0,1]seria menor, mas verificar se c é o valor c in'eo'seria ainda mais curto. Posteriormente, é o mesmo que c>'a'neste caso.
Manatwork
Na verdade, não há necessidade da variável me seus valores numéricos. Coloque apenas isso dentro de for:s+=[c>'e'if c>'a'else{'*':o.and_,'+':o.xor}[c](s.pop(),s.pop())]
manatwork
@ manatwork: Obrigado! Não achei que pudesse reverter a condição, porque pensei que isso significaria chamar s.pop()(duas vezes) cada loop. Eu não me incomodei em testar até agora; mas ei, o ponto é discutido agora.
Tim Pederick
Uma pergunta me incomodou desde o início: por que usar o operator módulo? bool.__and__()e bool.__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 em s+=[c>'e'if c>'a'else getattr(s.pop(),'__'+('axnodr'[c>'*'::2])+'__')(s.pop())].
Manatwork
@ manatwork: Porque eu não tinha pensado nisso. Eu considerei apenas os operadores infix ( ^, &) e seus operatorequivalentes, esquecendo os métodos que realmente os implementam. Ah, e reversed()agora foi descartada graças a outra das dicas de golfe em Python .
Tim Pederick
1

Haskell, 98 94 bytes

Desculpe incomodá-lo com mais uma tentativa de Haskell; só queria provar que é muito bem possível em menos de 100 bytes.

p(c:s)|any(<'a')s=p(c:p s)
p('+':x:y:s)|x/=y='o':s
p('*':'o':s)=s
p(c:_:_:s)|c<'a'='e':s
p s=s

Define uma função pque aceita qualquer expressão válida como parâmetro e retorna o resultado como uma sequência de comprimento 1.

Exemplo:

*Main> p "**o++*ee*++eoe*eo+eoo"
"o"

A função funciona reduzindo repetidamente o operador mais à direita na string até que nenhum operador seja deixado.

Ruud Helderman
fonte
0

Adicionar ++ , 46 bytes

D,g,@,d"oe"$eA"e"=+o
D,f,@,bR€gbU32CjbV2%"eo":

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 é fe gé uma função auxiliar. Usaremos "*e*o*e*oe"(que é e) como exemplo.

fcomeça pegando a string de entrada e revertendo-a, produzindo "eo*e*o*e*". Em seguida, mapeamos gcada elemento:

gcomeç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 para oe 2 para e. 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.

caird coinheringaahing
fonte