Bueno, eso es extraño ... no, espera, eso es par!

70

Preámbulo

Los enteros siempre son pares o impares . Los enteros pares son divisibles por dos, los enteros impares no.

Cuando agrega dos enteros, puede inferir si el resultado será par o impar en función de si los sumandos fueron pares o impares:

  • Par + Par = Par
  • Par + impar = impar
  • Impar + par = impar
  • Impar + impar = par

Del mismo modo, cuando multiplica dos enteros, puede inferir si el resultado será par o impar en función de si los factores fueron pares o impares:

  • Par * Par = Par
  • Par * impar = par
  • Impar * par = par
  • Odd * Odd = Odd

Por lo tanto, si conoce la uniformidad o impar de todas las variables en una expresión matemática que solo involucra la suma y la multiplicación, puede inferir si el resultado será par o impar.

Por ejemplo, podemos decir con confianza que (68 + 99) * 37da como resultado un impar porque un par más un impar ( 68 + 99) es un impar, y ese impar multiplicado por otro impar ( odd * 37) da un impar.

Desafío

Escriba un programa o función que tome una cadena que solo contenga los cuatro caracteres eo+*. Esta cadena representa una expresión matemática dada en notación de prefijo que involucra solo la suma ( +) y la multiplicación ( *). Cada uno erepresenta un número par arbitrario, y cada uno orepresenta un número impar arbitrario.

Su tarea es simplificar la expresión, imprimir o devolver una sola eo en ofunción de si el resultado de la expresión es par o impar.

Puede suponer que la entrada siempre estará en notación de prefijo válida. Específicamente, cada uno +y *siempre tendrá dos operandos correspondientes que ocurren después de él. Estos operandos pueden ser un solo eo o, u otro +o *expresión que a su vez tiene operandos.

Por ejemplo, la entrada *+eoopodría leerse como mul(add(e, o), o), o (e + o) * oen notación infija normal . El ey el primero oson los operandos correspondientes al +, +eoy el último oson los operandos correspondientes al *.

Solo para que quede claro, aquí hay algunas entradas inválidas que tienen una notación de prefijo incorrecta:

eo
ooe
o+e
ee*
+*oe
+e*o

Una nueva línea final en la salida está bien, pero de lo contrario, todo lo que debe salir es una llanura epar o oimpar.

El código más corto en bytes gana.

Casos de prueba

(Las líneas vacías son solo para ayudar a separar visualmente casos similares).

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
Pasatiempos de Calvin
fuente
8
¿Podemos tomar 1 y 0 en lugar de e y o como entrada?
ghosts_in_the_code
8
@ghosts_in_the_code No, lo siento.
Aficiones de Calvin
2
¿Está usando evalOK?
xnor
1
@xnor Claro. Lo que sea que funcione.
Aficiones de Calvin
2
Dudo que pueda usar esto para superar los 13 bytes ya publicados, pero noto que la suma coincide con una exclusiva o y una multiplicación simple o.
WGroleau

Respuestas:

43

CJam, 18 17 13 bytes

Gracias a aditsu por guardar 4 bytes.

qW:O%eu~"eo"=

Prueba el paquete de prueba aquí. (El conjunto de pruebas es demasiado largo para el enlace permanente. Simplemente cópielos de la especificación de desafío).

Explicación

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
fuente
27

Pyth, 16 14 bytes

@"eo".vjdXzGU9

Pyth puede evaluar por sí mismo una cadena, que está en sintaxis Pyth. Por lo tanto, reemplazo ey ocon 4y 5. Luego, la evaluación me dará un número par o impar, y puedo imprimir fácilmente el resultado.

Pruébelo en línea: Demostración o conjunto de pruebas

Explicación:

@"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"

Explicación adicional al reemplazo. Ges una variable inicializada con el alfabeto abc...xyz. U9es la lista [0, 1, ..., 8]. XzGU9reemplaza las letras del alfabeto con los valores de la lista. Entonces ase reemplaza con 0, bcon 1, ..., econ 4, ..., icon 8, jcon 0, ... y ocon 5. Por lo tanto, me ereemplazan con un número par y ocon un número impar. Todos los demás reemplazos no tienen ningún efecto.

Jakube
fuente
¿Por qué estás invirtiendo la expresión? Además, ¿no necesita tomar el módulo de resultado 2, o la indexación se está ajustando?
xnor
@xnor para acceder a un elemento en una cadena se realiza el ajuste del módulo. Así que no es necesario el módulo 2.
Jakube
@xnor Pero gracias por lo contrario. Por supuesto, esto no es necesario. (Estoy un poco cansado hoy.)
Jakube
16

Perl, 50 45 40 caracteres

(Código de 39 caracteres + opción de línea de comando de 1 carácter).

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

Ejecución de muestra:

bash-4.3$ echo -n '**o++*ee*++eoe*eo+eoo' | perl -pe '1while s/\+oe|\+eo|\*oo/o/||s/\W\w\w/e/'
o
hombre trabajando
fuente
¿Qué tal while/../?
primo
Doh Yo estupido En realidad usé esa condición mientras probaba su sedversión ... Gracias, @primo.
manatwork el
O incluso mejor 1while s/\+oe.... También estoy bastante seguro de que [+*]se puede reemplazar con \W.
primo
Gracias de nuevo, @primo. Creo que debería concentrarme en una única solución una vez. ( gema
volviéndome
¡El mismo enfoque con Sed ahora 2 bytes más corto!
Trauma digital
13

Retina , 29 bytes

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

Para la conveniente versión de un archivo -s, se usa la bandera.

Intercambiamos expresiones impares ( *oo, +oe, +eo) a ohasta que podamos, a continuación, cambiar las expresiones símbolo letras letras restantes a e. Repetimos esto hasta que podamos y la letra final es nuestra salida.

(Esta solución es similar a la respuesta Perl de manatwork ).

Pruébalo en línea! (por Dennis)

randomra
fuente
12

Pitón 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)]

La iterfunción es una buena manera de hacer que la cadena de entrada se convierta en una cola FIFO que recuerde cuánto de la cadena se ha analizado en las llamadas de f. Es idempotente, por lo que es inofensivo llamarlo nuevamente cuando la entrada ya es un iterador en lugar de una cadena. La mitad final de la respuesta que comienza con or'oe'... parece que debería ser golfable, pero no pude encontrar nada.

-1 gracias a Sp3000.

Feersum
fuente
¡Gran solución! El uso de funciones recursivas iterrealmente me aturde.
xnor
3
Aquí hay una manera de calcular la aritmética directamente con 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
1
@xnor También podrías publicar eso como respuesta. Es muy diferente de esta solución.
Feersum
9

Mathematica, 91 84 bytes

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

Buscando una manera de comprimir esto ...

LegionMammal978
fuente
3
//.es más corto 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]

Esto se basa en la respuesta muy inteligente de feersum que utiliza un iterpara implementar operaciones de notación polaca. La nueva idea es utilizar evalpara evaluar las expresiones +y *con eval(f(i)+a+f(i)), donde el operador ase coloca infijo entre los resultados recursivos. La evaluación utiliza los enlaces e=0,o=1en los argumentos de la función opcional. La salida se toma mod 2.

xnor
fuente
Esto también funciona en Python 3. Por cierto, ¿cómo evalúa necesitar los enlaces "e = 0, o = 1"?
karhell
@karhell Evalúa expresiones como e+o, por lo que necesita las variables para referirse a los números.
xnor
8

C, 79 bytes

Recurrencia directa. Se basa en algunas propiedades bit a bit (¿coincidentes?) De los cuatro caracteres de entrada permitidos.

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

Utilidades Shell + GNU, 33

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

La entrada se toma de STDIN.

Esto hace el mismo truco de invertir la entrada y evaluar con una calculadora basada en pila, en este caso dc. Podríamos reemplazar ey ocon 0y 1, pero luego sería necesario insertar espacios para evitar el codicioso análisis de los dígitos en los números incorrectos.

En esu lugar, se reemplaza con Kcuál es el dccomando para empujar la precisión actual a la pila, que por defecto es 0. Y ose reemplaza con Ocuál es el dccomando para empujar la base de salida actual a la pila. Esto debe ser extraño, por lo que lo configuramos en 15 Foantes de hacer cualquier otra cosa en cc.

Entonces es simplemente una cuestión de tomar mod 2 e imprimir 2%p. Los únicos valores posibles son ahora 0y 1, por lo que no importa que la base de salida sea 15. Luego se trtraduce de nuevo a oo e.


Me gusta que si entrecerras los ojos, esta fuente casi se parece dc Forever OK.

Trauma digital
fuente
5

En serio , 24 bytes

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

Una manipulación de pila más eficiente probablemente podría hacer esto más corto, pero me alegra.

Toma la entrada como una cadena, como "+*oee"

Pruébelo en línea (la entrada debe ingresarse manualmente)

Explicación:

,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
fuente
5

Ruby, 61 bytes

Uso de análisis de descenso recursivo y álgebra booleana.

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

La función lee un carácter de stdin a la vez. Si lee a +o a *, se llama a sí mismo dos veces para determinar par o impar. La función devuelve truepara impar y falsepara even. Los operadores ^ XOR y & AND se utilizan para determinar la "rareza" de las expresiones de suma y multiplicación, respectivamente.

Aquí hay una versión sin golf:

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

puts f ? 'o' : 'e'

Gracias @Shel por señalar un error en la versión inicial.

daniero
fuente
1
Esto no funciona, +eeda o. Me gusta la idea
Shelvacu
reemplazar f^fcon !f^fy f&fcon f|fy funciona. Programa para ejecutar casos de prueba: pastebin.com/ufXfd1vc
Shelvacu
1
Gracias, buena captura! Parece que me confundí un poco allí. Bonita suite de prueba también! Prueba de manejo es el camino a seguir, también cuando se
juega
@Shel Aha ..! He cambiado la espalda f^fy f&fy da la vuelta $_==?ey ?e:?oen su lugar :)
daniero
1
Wow, aprende algo nuevo todos los días ... ruby-doc.org/core/Regexp.html#method-i-7E
Shelvacu
4

Minkolang 0.14 , 40 bytes

Intenté hacer un método de evaluación inteligente, pero resulta que los valores agregados al cuadro de código fuera del espacio original nunca serán alcanzados por el contador del programa. Entonces hice un método eval menos inteligente. :PAGS

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

Pruébalo aquí.

Explicación

$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
fuente
1
Woohoo! buen ol ' late un lenguaje de (semi) golf ;-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"});

¡Ciertamente no es la solución más pequeña, pero probablemente sea la solución más pequeña posible en un lenguaje detallado como JavaScript!

Arkain
fuente
El uso de grupos sin captura es bueno para el rendimiento pero malo para el tamaño del código. Mejor eliminar esos ?:.
manatwork
de acuerdo ... y tan modificado.
Arkain
Echó otro vistazo ahora. Su código puede reducirse un poco más while(i.length>2)i=i.replace(/[+*][eo]{2}/,function(o){return"+oe+eo*oo".indexOf(o)>=0?"o":"e"}). O si cambia a la función de flecha gruesa de ECMAScript 6, entonces while(i.length>2)i=i.replace(/[+*][eo]{2}/,o=>"+oe+eo*oo".indexOf(o)>=0?"o":"e"). Pero desafortunadamente, el requisito dice programa o función, mientras que su código actual es un fragmento. Debe manejar entrada y salida o argumento y valor de retorno.
manatwork
1
Lamentablemente, para ser válido en este sitio, no podemos suponer que ya existe una variable. Tendrás que hacer que funcione icomo dijiste.
Alex A.
1
@Arkain, no necesita capturar un grupo en la expresión regular, ya que de todos modos utilizará toda la subcadena coincidente como una sola pieza. Por la misma razón, no es necesario pasar el parámetro e a la devolución de llamada.
manatwork
4

O , 24 20 19 18 bytes

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

Toma datos, los invierte, los asigna ea 2 y oa 1 y los publica en Tumblr lo evalúa como código O.

Explicación:

i` Obtener entrada y revertirla, porque O usa notación postfix
2: e; Asigne `e` a 2
1: o; Asignar `o` a 1
~ 2% Evalúa y comprueba si el resultado es par
'o'e? Salida 'e' si par, 'o' si impar
fase
fuente
4

GNU Sed, 36

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

Después de la publicación de esta vi exactamente el mismo enfoque que @ de respuesta Perl manatwork y respuesta de la retina de @ randomra . Así que supongo que también podría ir hasta el final y pedir prestado \W\w\wtambién.

Gracias a @Ruud por reducir 4 bytes.

Trauma digital
fuente
Sin los paréntesis, ahora vale la pena abandonar la expresión regular extendida. Usted gana 2 bytes por no escapar +, pierde 2 bytes por escapar |, pero el resultado final es que gana 1 byte por la opción de soltar -r.
Ruud Helderman
@Ruud Eso es correcto. Lo intenté antes, pero no me di cuenta de la |necesidad de escapar cuando -rno se usa. Aún así, 2 bytes más fuera del puntaje, ¡gracias!
Trauma digital
2

Haskell, 160 bytes

Llamar 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
fuente
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á un poco ofuscado, pero quería hacer 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"
        ))

La repetición de (e[…]>"e")me molesta un poco, pero lo siguiente tampoco es mejor (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])]))

Entonces, al final, el enfoque de @ Arkain con una simple coincidencia de subcadenas es superior. Convertido en una función, con algunas optimizaciones:

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

Dart, 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]);}

Esto no es competitivo, pero lo que sea. La esencia de la solución es, comenzando en 0, reemplazar recursivamente a cada operador con la evaluación del par de caracteres que siguen a ese operador y luego eliminar esos caracteres de la lista.

Mella
fuente
1

Haskell, 231 bytes

Aquí hay un enfoque que usa un lenguaje serio;)

Versión de golf:

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

Ejemplo:

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

Versión sin golf y bastante completa:

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

Ejemplo:

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

Características: coincidencia de patrones y recursividad.

usuario3389669
fuente
1

Jolf, 11 bytes

(No competitivo, ya que el lenguaje es posterior a la pregunta). ¡ Pruébelo aquí!

FVyAi"oe"@\x12

(Reemplace \x12con el carácter real \x12. Esto debe hacerse automáticamente en el intérprete).

Explicación:

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
fuente
1

Python 3, 171 145 135 bytes

No es competitivo, pero me divertí haciéndolo, así que no pude guardarlo para mí. A diferencia de la entrada de Python de iterador recursivo (muy inteligente) por feersum , esta invierte la entrada y luego realiza un buen análisis basado en pila de la notación polaca inversa.

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
fuente
Eso callable()es elegante, pero largo. (Revertir la condición y eliminar notsería más corto). Verifique si m es entero m in[0,1]sería más corto, pero verificar si c es valor c in'eo'sería aún más corto. Esto luego es lo mismo que c>'a'en este caso.
manatwork
En realidad no hay necesidad de la variable my sus valores numéricos. Ponga solo esto dentro de for:s+=[c>'e'if c>'a'else{'*':o.and_,'+':o.xor}[c](s.pop(),s.pop())]
manatwork
@manatwork: ¡Gracias! No pensé que podría revertir la condición, porque pensé que eso habría significado llamar s.pop()(dos veces) cada bucle. No me molesté en probar hasta ahora; pero bueno, el punto es discutible ahora.
Tim Pederick
Una pregunta me molestó desde el principio: ¿por qué usar el operator módulo? bool.__and__()y bool.__xor__()son más práctico: s+=[c>'e'if c>'a'else getattr(s.pop(),{'*':'__and__','+':'__xor__'}[c])(s.pop())]. Pero según la punta de corte de gnibbler , eso se puede cambiar a . s+=[c>'e'if c>'a'else getattr(s.pop(),'__'+('axnodr'[c>'*'::2])+'__')(s.pop())]
manatwork
@manatwork: Porque no había pensado en eso. Solo consideré los operadores infijos ( ^, &) y sus operatorcontrapartes, olvidando los métodos que realmente los implementan. Ah, y reversed()ahora se ha eliminado gracias a otro de los consejos de golf de Python .
Tim Pederick
1

Haskell, 98 94 bytes

Lamento molestarte con otro intento de Haskell; solo quería demostrar que es muy posible en 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 una función pque acepta cualquier expresión válida como parámetro y devuelve el resultado como una cadena de longitud 1.

Ejemplo:

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

La función funciona reduciendo repetidamente el operador más a la derecha de la cadena hasta que no queden operadores.

Ruud Helderman
fuente
0

Agregar ++ , 46 bytes

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

Pruébalo en línea!

El pie de página simplemente enumera todas las entradas de ejemplo y sus salidas correspondientes.

Cómo funciona

Como una pérdida de las respuestas aquí, esto usa reemplazo y evaluación. Nuestra función principal es f, y ges una función auxiliar. Usaremos "*e*o*e*oe"(que es e) como un ejemplo.

fcomienza tomando la cadena de entrada e invirtiéndola, cediendo "eo*e*o*e*". Luego mapeamos gsobre cada elemento:

gcomienza duplicando el argumento, para mantener una copia hasta el comando final. Luego verificamos si el argumento está en la cadena "oe", produciendo 1 para letras y 0 para *o +. Luego empujamos el argumento nuevamente y verificamos si es igual a "e". Este resultado se agrega a la verificación anterior. Esto produce 0 para cualquiera *o +, 1 para oy 2 para e. Luego tomamos el OR lógico entre este valor y el argumento. Si el valor es 0 , se reemplaza por el argumento (es decir, *o +), de lo contrario se deja como está (es decir, 1 y 2 ).

Esto convierte todas las letras en el reverso de la entrada en un valor numérico. Luego unimos cada elemento por espacios, para garantizar que los dígitos no estén concatenados. Para nuestro ejemplo, esto produce la cadena "2 1 * 2 * 1 * 2 *". Luego podemos evaluar esto, usando la notación postfix de Add ++, obteniendo 8 . Luego tomamos la paridad de este valor, produciendo 0 para números pares y 1 para números impares, antes de indexar en la cadena "eo"y devolver la letra correspondiente.

caird coinheringaahing
fuente