Two Symbol Math

8

Introducción

Los cuatro operadores matemáticos básicos (+, -, *, /) se pueden reducir a solo dos, debido a que:

x + y = x - (-y)
x * y = x / (1/y), y != 0
x * 0 = 0/x

Desafío

El desafío es tomar la entrada como una "cadena" que contiene:

  • Números
  • Variables de un solo carácter ("x", "y")
  • Los cuatro operadores matemáticos básicos (+, -, *, /)
  • Paréntesis

y genera una cadena manipulada para que produzca el mismo resultado matemático que la entrada, pero que contenga solo los símbolos matemáticos '-' y '/'

Detalles específicos

  • La entrada puede estar en cualquier forma aceptable (archivo, STDIN, etc.) y puede representarse como una cadena o matriz de caracteres (pero no como una matriz de matrices)
  • La salida puede tener cualquier forma aceptable (archivo, STDIN, etc.) y puede representarse como una cadena o matriz de caracteres (pero no como una matriz de matrices)
  • Debes reconocer y mantener un paréntesis equilibrado
  • Las lagunas estándar no están permitidas
  • Es su elección si quiere representar x + ycomo x - -yox - (-y)
  • Debe mantener el orden de las operaciones.
  • Nunca tiene que manejar entradas no válidas
  • La entrada puede estar vacía o un solo número / variable, en ese caso el programa debería generar la entrada
  • Nota: Usted no tiene que utilizar las sustituciones en la introducción, siempre y cuando input = output, el programa podría cambiar 2 * 2a 8/2, si desea
  • Puede suponer que "0" es la única forma en que aparecerá un cero en la ecuación (es decir, no tiene que manejarlo 1 * (4 - 4))
  • Sugerencia: para probar su programa, vaya a este sitio web escriba input = output, donde input es la entrada y output es la salida, y si el resultado es "verdadero", su programa manejó ese caso con éxito ( ejemplo , ejemplo )

Casos de prueba

A continuación se presentan algunos casos de prueba, ingresados ​​como una sola cadena y producidos como una sola cadena.

x + y
x - (-y)

x * y
x / (1/y)

x / y
x / y

x - y
x - y

1
1

5
5

-6
-6

+x
x

1 + (x * 4) - (512 * 3)
1 - (-(x / (1/4))) - (512 / (1/3))

1 - 3 / 4 + l / g
1 - 3/4 - (-(l / g))

5 * 0 / 2
0/5 / 2

(a + g) * 0
0/(a - (-g))

Puntuación

Es , por lo que la respuesta más corta en bytes gana. Los empates se resuelven por primera publicación.

Fénix Socrático
fuente
2
Por cierto x / 1/y= x/yporque la división no es asociativa. Sé lo que estás pensando, pero incluso WolframAlpha no reconoce que quieres espacios para cambiar el orden de las operaciones ... así que probablemente deberías repensar esto o no mencionarlo como una forma válida de verificar las cosas.
Linus
1
@Linus: Tampoco es equivalente cuando y=0, pero supongo que el desafío lo asume implícitamente n/d => d != 0.
Tim Čas
@ TimČas ahh! No pensé en eso. Actualizaré el desafío, solo sé que tendrá que ser manejado adecuadamente
Socratic Phoenix
Tal como están las cosas, hay muy poco que nos impida simplemente evaluar la expresión y devolver el resultado (después de todo, son matemáticamente iguales). Recomiendo cambiar eso, a menos que quieras vser una solución adecuada en Pyth.
Steven H.
Espera, así que si hay variables (como x e y), ¿cómo podemos dividir sin arriesgar la división por cero? 5 * (a - b)si a = b. ¿Y tenemos que detectar cosas como 5 * (a - a)? ¿Qué tal 5 * (4 - 4)y 5 * (a / a - 1)o 5 * (4 / 4 - 1)?
Adám

Respuestas:

4

Python 3, 267 bytes

Gracias a @ ConorO'Brien

import re
q=re.sub
g=lambda m:'--'+m.group()[1:]
h=lambda m:'/(1/'+m.group()[1:]+')'
i=lambda m:'0/'+m.group()[:-2]
print(q(r'\*[^\(\)]+',h,q(r'[^\(\)]\*0',i,q(r'\+[^\(\)]+',g,q(r'\*\([^\)]+\)',h,q(r'\([^\)]+\)\*0',i,q(r'\+\([^\)]+\)',g,input().replace(' ',''))))))))

Ideone it!

Decaimiento Beta
fuente
Honestamente, no tengo idea de qué magia oscura has empleado, pero +1 para FGITW
Socratic Phoenix el
@SocraticPhoenix Jaja, la magia oscura se llama regex;)
Beta Decay
1

Dyalog APL , 42 bytes

Esto mantiene el orden de las operaciones de APL. Tenga en cuenta que ÷xes1÷x

'\+' '×'R'--' '÷÷'('(.*)×0'R'0÷\1'~∘' ')

TryAPL en línea!

( sobre el resultado de ...

~∘' ' eliminar espacios

'(.*)×0'⎕R'0÷\1' reemplace cualquier cosa seguida de "× 0" con "0 ÷" seguido de ella

) evaluar...

'\+' '×'⎕R'--' '÷÷' reemplace "+" con "-" y "×" con "÷ útiles"

Para verificar:

  1. Asignar al azar no cero números a x, y, l, g, y a.

  2. Ejecuta las expresiones originales.

  3. Ejecute las expresiones modificadas.

  4. Compara los resultados.

Adán
fuente
0

SED 272 246 239 213

s,^\+,,;s,[^+*/()-]\+,(&),g;t;:;s,)[^)]*)\*(0,&,;tr;s,\((.*)\)\*(0),(0/\1),;ty;s,\*([^)]*(,&,;tr;s,\*\(([^)]*)\),/(1/\1),;ty;s,\+([^)]*(,&,;tr;s,\+\(([^)]*)\),-(-\1),;ty;p;q;:r;s,(\([^()]*\)),!\1@,;t;:y;y,!@,(),;b

Tomar entrada sin espacios (p x+y*2. Ej .).
Este es uno de los pocos casos en los que es más corto escapar (y )capturar grupos en lugar de usarlos -r. Estoy seguro de que esto se puede jugar más, pero estoy feliz por ahora.

Sin golf, con comentarios:

s,^\+,, #remove leading +
s,[^+*/()-]\+,(&),g #suround numbers/variables in ()
t start #reset the test because the line above will always match

:start
#------------- deal with *0 ------------------
s,)[^)]*)\*(0,&, #remove inner matching ()
t replace
s,\((.*)\)\*(0),(0/\1),
t y
#------------- deal with generic * -----------
s,\*([^)]*(,&, #remove inner matching ()
t replace
s,\*\(([^)]*)\),/(1/\1),
t y
#------------- deal with + -------------------
s,\+([^)]*(,&, #remove inner matching ()
t replace
s,\+\(([^)]*)\),-(-\1),
t y

b end #all done, branch to the end

#------------- replace a set of () with !@ ---
#repeated application of this helps find the matching ( or )
:replace
s,(\([^()]*\)),!\1@,
t start

:y
y,!@,(),
b start

:end
Riley
fuente