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) * 37
da 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 e
representa un número par arbitrario, y cada uno o
representa un número impar arbitrario.
Su tarea es simplificar la expresión, imprimir o devolver una sola e
o en o
funció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 e
o o
, u otro +
o *
expresión que a su vez tiene operandos.
Por ejemplo, la entrada *+eoo
podría leerse como mul(add(e, o), o)
, o (e + o) * o
en notación infija normal . El e
y el primero o
son los operandos correspondientes al +
, +eo
y el último o
son 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 e
par o o
impar.
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
fuente
eval
OK?Respuestas:
CJam,
181713 bytesGracias a aditsu por guardar 4 bytes.
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
fuente
Pyth,
1614 bytesPyth puede evaluar por sí mismo una cadena, que está en sintaxis Pyth. Por lo tanto, reemplazo
e
yo
con4
y5
. 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:
Explicación adicional al reemplazo.
G
es una variable inicializada con el alfabetoabc...xyz
.U9
es la lista[0, 1, ..., 8]
.XzGU9
reemplaza las letras del alfabeto con los valores de la lista. Entoncesa
se reemplaza con0
,b
con1
, ...,e
con4
, ...,i
con8
,j
con0
, ... yo
con5
. Por lo tanto, mee
reemplazan con un número par yo
con un número impar. Todos los demás reemplazos no tienen ningún efecto.fuente
Perl,
504540 caracteres(Código de 39 caracteres + opción de línea de comando de 1 carácter).
Ejecución de muestra:
fuente
while/../
?sed
versión ... Gracias, @primo.1while s/\+oe...
. También estoy bastante seguro de que[+*]
se puede reemplazar con\W
.gema
Retina , 29 bytes
Para la conveniente versión de un archivo
-s
, se usa la bandera.Intercambiamos expresiones impares (
*oo
,+oe
,+eo
) ao
hasta que podamos, a continuación, cambiar las expresiones símbolo letras letras restantes ae
. 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)
fuente
Pitón 2, 90
La
iter
funció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 def
. 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 conor'oe'
... parece que debería ser golfable, pero no pude encontrar nada.-1 gracias a Sp3000.
fuente
iter
realmente me aturde.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 bytesBuscando una manera de comprimir esto ...
fuente
//.
es más corto queFixedPoint
.Python 2, 80 bytes
Esto se basa en la respuesta muy inteligente de feersum que utiliza un
iter
para implementar operaciones de notación polaca. La nueva idea es utilizareval
para evaluar las expresiones+
y*
coneval(f(i)+a+f(i))
, donde el operadora
se coloca infijo entre los resultados recursivos. La evaluación utiliza los enlacese=0,o=1
en los argumentos de la función opcional. La salida se toma mod 2.fuente
e+o
, por lo que necesita las variables para referirse a los números.C, 79 bytes
Recurrencia directa. Se basa en algunas propiedades bit a bit (¿coincidentes?) De los cuatro caracteres de entrada permitidos.
fuente
Utilidades Shell + GNU, 33
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 reemplazare
yo
con0
y1
, pero luego sería necesario insertar espacios para evitar el codicioso análisis de los dígitos en los números incorrectos.En
e
su lugar, se reemplaza conK
cuál es eldc
comando para empujar la precisión actual a la pila, que por defecto es 0. Yo
se reemplaza conO
cuál es eldc
comando para empujar la base de salida actual a la pila. Esto debe ser extraño, por lo que lo configuramos en 15Fo
antes 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 ahora0
y1
, por lo que no importa que la base de salida sea 15. Luego setr
traduce de nuevo ao
oe
.Me gusta que si entrecerras los ojos, esta fuente casi se parece
dc Forever OK
.fuente
En serio , 24 bytes
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:
fuente
Ruby, 61 bytes
Uso de análisis de descenso recursivo y álgebra booleana.
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 devuelvetrue
para impar yfalse
paraeven
. 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:
Gracias @Shel por señalar un error en la versión inicial.
fuente
+ee
dao
. Me gusta la ideaf^f
con!f^f
yf&f
conf|f
y funciona. Programa para ejecutar casos de prueba: pastebin.com/ufXfd1vcf^f
yf&f
y da la vuelta$_==?e
y?e:?o
en su lugar :)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
Pruébalo aquí.
Explicación
fuente
JavaScript,
11010694 bytes¡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!
fuente
?:
.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, entonceswhile(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.i
como dijiste.O ,
24201918 bytesToma datos, los invierte, los asigna
e
a 2 yo
a 1 y lospublica en Tumblr loevalúa como código O.Explicación:
fuente
GNU Sed, 36
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\w
también.Gracias a @Ruud por reducir 4 bytes.
fuente
+
, pierde 2 bytes por escapar|
, pero el resultado final es que gana 1 byte por la opción de soltar-r
.|
necesidad de escapar cuando-r
no se usa. Aún así, 2 bytes más fuera del puntaje, ¡gracias!Haskell, 160 bytes
Llamar
f
.fuente
JavaScript,
9271 bytesEstá un poco ofuscado, pero quería hacer algo usando
eval
operadores bit a bit. Anotado:La repetición de
(e[…]>"e")
me molesta un poco, pero lo siguiente tampoco es mejor (103 bytes):Entonces, al final, el enfoque de @ Arkain con una simple coincidencia de subcadenas es superior. Convertido en una función, con algunas optimizaciones:
fuente
Dart, 173 bytes
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.
fuente
Haskell, 231 bytes
Aquí hay un enfoque que usa un lenguaje serio;)
Versión de golf:
Ejemplo:
Versión sin golf y bastante completa:
Ejemplo:
Características: coincidencia de patrones y recursividad.
fuente
Jolf, 11 bytes
(No competitivo, ya que el lenguaje es posterior a la pregunta). ¡ Pruébelo aquí!
(Reemplace
\x12
con el carácter real\x12
. Esto debe hacerse automáticamente en el intérprete).Explicación:
fuente
Python 3,
171145135 bytesNo 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.
fuente
callable()
es elegante, pero largo. (Revertir la condición y eliminarnot
sería más corto). Verifique si m es enterom in[0,1]
sería más corto, pero verificar si c es valorc in'eo'
sería aún más corto. Esto luego es lo mismo quec>'a'
en este caso.for
:s+=[c>'e'if c>'a'else{'*':o.and_,'+':o.xor}[c](s.pop(),s.pop())]
s.pop()
(dos veces) cada bucle. No me molesté en probar hasta ahora; pero bueno, el punto es discutible ahora.operator
módulo?bool.__and__()
ybool.__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())]
^
,&
) y susoperator
contrapartes, olvidando los métodos que realmente los implementan. Ah, yreversed()
ahora se ha eliminado gracias a otro de los consejos de golf de Python .Haskell,
9894 bytesLamento molestarte con otro intento de Haskell; solo quería demostrar que es muy posible en menos de 100 bytes.
Define una función
p
que acepta cualquier expresión válida como parámetro y devuelve el resultado como una cadena de longitud 1.Ejemplo:
La función funciona reduciendo repetidamente el operador más a la derecha de la cadena hasta que no queden operadores.
fuente
Agregar ++ , 46 bytes
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
, yg
es una función auxiliar. Usaremos"*e*o*e*oe"
(que ese
) como un ejemplo.f
comienza tomando la cadena de entrada e invirtiéndola, cediendo"eo*e*o*e*"
. Luego mapeamosg
sobre cada elemento:g
comienza 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 parao
y 2 parae
. 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.fuente