Produzca una poof formal completa de declaraciones tales como 1+2=3
, 2+2=2*(1+1)
etc.
Introuction
Si conoce la aritmética de Peano, probablemente puede saltear esta sección.
Así es como definimos los números naturales:
(Axiom 1) 0 is a number
(Axiom 2) If `x` is a number, the `S(x)`, the successor of `x`, is a number.
Por lo tanto, por ejemplo, S(S(S(0)))
es un número.
Puede usar cualquier representación equivalente en su código. Por ejemplo, todos estos son válidos:
0 "" 0 () !
1 "#" S(0) (()) !'
2 "##" S(S(0)) ((())) !''
3 "###" S(S(S(0))) (((()))) !'''
...
etc
Podemos extender las reglas para definir la suma de la siguiente manera.
(Rule 1) X+0 = X
(Rule 2) X+S(Y)=S(X)+Y
Con esto podemos probar 2 + 2 = 4 de la siguiente manera
S(S(0)) + S(S(0)) = 2 + 2
[Rule 2 with X=S(S(0)), Y=S(0)]
S(S(S(0))) + S(0) = 3 + 1
[Rule 2 with X=S(S(S(0))), Y=0]
S(S(S(S(0)))) + 0 = 4 + 0
[Rule 1 with X=S(S(S(S(0))))
S(S(S(S(0)))) = 4
Podemos extender estas reglas para definir la multiplicación de la siguiente manera
(Rule 3) X*0 = 0
(Rule 4) X*S(Y) = (X*Y) + X
Aunque para permitir esto necesitamos definir el papel estructural de los paréntesis.
(Axiom 3) If X is a number, (X) is the same number.
Los operadores de suma y multiplicación son estrictamente binarios y los paréntesis siempre deben ser explícitos. A+B+C
no está bien definido, pero (A+B)+C
y A+(B+C)
son.
Ejemplo
Ahora tenemos suficiente para demostrar un teorema sobre la multiplicación: 2 + 2 = 2 * 2
2 + 2
(2) + 2
(0 + 2) + 2
((0*2) + 2) + 2
(1*2) + 2
2*2
Requisitos
Una prueba de queA=B
es una lista de expresiones tales que:
- el primero es
A
, - el último es
B
, y - cada expresión en la lista, aparte de la primera, puede obtenerse de la anterior transformándola bajo una de las reglas.
Su programa tomará dos expresiones válidas como entrada , cada expresión contiene números, suma, multiplicación y paréntesis como se definió anteriormente.
Su programa generará una prueba, una lista como se definió anteriormente, que las dos expresiones son iguales, si tal prueba existe.
Si las dos expresiones no son iguales, su programa no generará nada.
Probar o refutar siempre es posible en un número finito de pasos, porque cada expresión se puede reducir a un solo número y estos números se pueden probar trivialmente para determinar la igualdad.
Si las expresiones de entrada no son válidas (por ejemplo, paréntesis desequilibrados, contienen operadores que no son números u operadores no binarios), entonces su programa debería salir con error, lanzar una excepción, imprimir un error o producir algún comportamiento observable que sea distinto del caso en el que las entradas son válidas pero no iguales .
En resumen, la salida normal para entradas admisibles es una lista de números iguales, incluidas las entradas, que se produce mediante las siguientes reglas.
(Axiom 1) 0 is a number
(Axiom 2) If `x` is a number, the `S(x)`, the successor of `x`, is a number.
(Axiom 3) If X is a number, (X) is the same number
(Rule 1) X+0 = X
(Rule 2) X+S(Y)=S(X)+Y
(Rule 3) X*0 = 0
(Rule 4) X*S(Y) = (X*Y) + X
(Rule 5) X = (X) (Axiom 3 expressed as a transformation rule.)
Se permite cualquier representación adecuada de los números en la entrada y la salida, por ejemplo 0=""=()
, 3="###"=(((())))
, etc. espacio en blanco es irrelevante.
Las reglas pueden, por supuesto, aplicarse en cualquier dirección. Su programa no tiene que mostrar qué regla se usa, solo la expresión producida por su acción en la expresión anterior.
El código más corto gana.
Respuestas:
Perl, 166 + 1 bytes
Corre con
-p
(penalización de 1 byte).Más legible:
El formato de entrada expresa números en unario como cadenas de
S
, y requiere las dos entradas en líneas separadas (cada una seguida de una nueva línea y un EOF después de que se vean ambas). Interpreté la pregunta como que requiere que los paréntesis sean literalmente(
)
y que la suma / multiplicación sea literal+
*
; Puedo guardar algunos bytes con menos escape si se me permite hacer diferentes elecciones.El algoritmo en realidad compara la primera línea de entrada con una línea vacía, la segunda con la primera, la tercera con la segunda, y así sucesivamente. Esto cumple con los requisitos de la pregunta. Aquí hay un ejemplo de ejecución:
Mi entrada:
Salida del programa:
El duplicado
SSSS
en el medio es molesto, pero decidí que no violaba la especificación, y tiene menos bytes para dejarlo.En una entrada no válida, agrego
1
al carácter de nueva línea, por lo que se extravían1
al final de la salida.fuente
echo -e "((SS+)+(S+S))\nSS*SS" | perl -p /tmp/x.pl
salidas1
.(SS*SS)
). "Los operadores de suma y multiplicación son estrictamente binarios y los paréntesis siempre deben ser explícitos".