Genere una ecuación válida utilizando números especificados por el usuario.

10

Esto se basa en un juego que uno de mis maestros de matemáticas solía jugar en la escuela secundaria. Escribiría 5 números aleatorios de un dígito en la pizarra, y luego un número aleatorio de dos dígitos. Intentaríamos crear una ecuación que usara los 5 números de un dígito para obtener el número de dos dígitos. Aquí hay algunos ejemplos con soluciones para explicar esto mejor:

Input:           Solution:
7 5 4 8 4 34     5*8-7+4/4 = 34
3 1 5 7 6 54     (7+3)*6-5-1 = 54
3 9 2 1 6 87     9*(2+1)*3+6 = 87
2 1 6 9 7 16     (9-7+6*1)*2 = 16
2 4 5 8 6 96     8*(5+6)+2*4 = 96
3 8 4 5 4 49     8*(4+4)-3*5 = 49

Este desafío es escribir un programa que pueda generar tales ecuaciones para una entrada dada. La entrada se puede proporcionar a través de la línea de comando o mediante un indicador. Los 5 números de un dígito siempre se ingresarán primero (sin ningún orden en particular), seguidos del número de dos dígitos. El programa imprimirá una ecuación de solución que encuentre; no tiene que manejar situaciones donde no hay solución. La función debe ser capaz de usar las siguientes operaciones en la ecuación: suma, resta, multiplicación y división. Si desea permitir operaciones básicas adicionales, está bien siempre y cuando permanezcan en el espíritu del desafío (la negación, la exponenciación y el módulo serían buenas adiciones). El orden de las operaciones sigue las reglas matemáticas estándar, por lo que se necesitará paréntesis para la agrupación.

Los programas se puntuarán según la longitud del código (incluido el espacio en blanco requerido). Nota: la división debe ser exacta, no redondeada o truncada al entero más cercano.

Sir_Lagsalot
fuente
Esa es una tarea muy similar, pero creo que el término adicional y ninguna restricción sobre cómo se agrupan las expresiones debería expandir el problema lo suficiente como para que sea interesantemente diferente. Además, este es un desafío de golf en lugar de un desafío de código, que requerirá diferentes soluciones.
Sir_Lagsalot
¿Qué pasa con la concatenación? por ejemplo, si se le da 7 5 4 8 4 34, ¿se permitiría la salida 7 + 54/8 * 4?
Patrick Roberts

Respuestas:

7

Python 2.7 (284), Python 3.x (253)

from __future__ import division #(Remove for Python 3.x)
from itertools import *
a=raw_input().split()
for i in permutations(a[:-1],5):
 for j in product('+-*/',repeat=5):
  for k,l in combinations(range(1,12,2),2):
   d=''.join(sum(zip(i,j),()))[:-1];d='('+d[:l]+')'+d[l:]
   if eval(d)==int(a[-1]):print d;b

Da un error (llamando a una función desconocida b) en la solución.

Básicamente, es una fuerza bruta gigantesca. Toma la entrada, la divide por sus espacios ( 1 2 -> [1,2]) y luego permuta a través de esa lista. Con cada permutación, iterará a través de todas las cadenas posibles de longitud 5 usando los caracteres +-*/. Con cada una de esas iteraciones, generará las combinaciones de longitud 2 de la lista [1,3,5,7,9,11], entrelazará la permutación y la cadena ( 12345 *-/+- -> 1*2-3/4+5-), y pondrá los paréntesis. Finalmente, lo evaluará, y si la respuesta y la ecuación son verdaderas, imprime la ecuación y se detiene.

Esto es terriblemente ineficiente, O(n!/(n-5)!)=O(n^5)pero funciona en un tiempo razonable para las entradas de prueba.

beary605
fuente
1
La matemática entera puede causar resultados incorrectos cuando se usa la división. Por ejemplo, la entrada "3 6 8 7 1 29" produce "(3 + 8/6) * 7 + 1", que equivale a 31 1/3, no 29. Actualizaré la descripción para hacerlo explícito.
Sir_Lagsalot
Da (3/6)*8*7+1por mi.
beary605
Ok, lo marcaré como un problema con el intérprete que utilicé.
Sir_Lagsalot
3

Scala 368:

El segundo g = -Línea es más fácil de probar, el primero es flexible para tomar argumentos de comando, y ambos son de igual longitud, por lo que solo cuento desde el segundo: elimínelo para pasar args:

val g=(args.map(_.toDouble))
val g=Array(3,9,2, 1, 6, 87)
val k="+*/-DQ"
val i=(0 to 5)
val f:Seq[(Double,Double)=>Double]=Seq(_+_,_*_,_/_,_-_,(a,b)=>b-a,(a,b)=>b/a)
val h=g.init.permutations;
for(j<-h;o<-i;p<-i;q<-i;r<-i;z=try{f(r)(f(q)(f(p)(f(o)(j(0),j(1)),j(2)),j(3)),j(4))}catch{case _ => 0}
if(z==g(5)))printf("(((%d%c%d)%c%d)%c%d)%c%d=%d\n",j(0),k(o),j(1),k(p),j(2),k(q),j(3),k(r),j(4),g(5))

Ejemplo de salida (es posible que tenga una pregunta en este momento, solo un momento):

(((5+7)/1)+6)*3=54
(((5-7)D1)*6)*3=54
(((5D7)+1)*6)*3=54
(((5+7)+6)Q1)Q3=54

¿Qué hay de esta cosa 5D7? D1? ¿Es hexadecimal? Hay Q1, Q3, ¿qué es eso?

Sir_Lagsalot permitió nuevas operaciones básicas en el espíritu del desafío, y sí, estas son operaciones básicas, Delta y Cociente.

Son diferentes de a / by ab en que aQb significa b / a y aDb significa ba. Llamémosle la notación ucraniana.

Entonces

(((5-7)D1)*6)*3=54

medio

((1-(5-7))*6)*3=54
 (1-(-2))*6*3
   3*6*3 = 18*3=54

A la pregunta más interesante del cómo y por qué: al principio me enojé por las posibilidades de colocar los paréntesis y si (a + b) -c = a + bc = (a + bc) = ((a + b ) -c) = (b + a) -c y así sucesivamente. Puede enojarse por esta pregunta, pero si escribe las posibles combinaciones de paréntesis, a veces tira la hoja de memoria y enfrenta el hecho: siempre realiza 4 operaciones entre 5 valores, y siempre comienza con una de ellas. Si el patrón es siempre (((_x_)x_)x_)x_ ?= _(x es uno de los 4 operadores) y permite la dirección opuesta (xb) y (bxa), abordó todas las posibilidades.

Ahora para a + b y a * b no necesitamos ninguna dirección opuesta, son conmutativos. Así que inventé el operador D y Q, que simplemente cambia la dirección. Ahora tengo 2 operadores más, pero no necesito cambiar de dirección. Bueno, se hace en la función Secuencia:

 (a,b)=>b-a,(a,b)=>b/a

Mi comprensión inicial toma los valores de la matriz g, y los distribuye en una ae, luego selecciono 4 índices para elegir la función y luego el símbolo del operador asociado (solo por índice). Tengo que atrapar errores div / 0, ya que la resta puede conducir a ceros, mientras que los datos de entrada de muestra no contienen un 0.

usuario desconocido
fuente
Los operadores Delta y Cociente están bien. Sin embargo, si planea jugar al golf, necesitará agregar paréntesis a la salida.
Sir_Lagsalot
La salida ahora imprime paréntesis.
Usuario desconocido