Multiplicar con operaciones restringidas

44

Hay una recompensa no oficial de 500 repeticiones por vencer a la mejor respuesta actual .

Gol

Su objetivo es multiplicar dos números usando solo un conjunto muy limitado de operaciones aritméticas y asignación de variables.

  1. Adición x,y -> x+y
  2. Recíproco x -> 1/x( no división x,y -> x/y)
  3. Negación x -> -x( no resta x,y -> x-y, aunque puede hacerlo como dos operaciones x + (-y))
  4. La constante 1(no se permiten otras constantes, excepto las producidas por operaciones de 1)
  5. Asignación variable [variable] = [expression]

Puntuación: Los valores comienzan en variables ay b. Su objetivo es guardar su producto a*ben la variable cutilizando la menor cantidad de operaciones posible. Cada operación y asignación +, -, /, =cuesta un punto (de manera equivalente, cada uso de (1), (2), (3) o (4)). Las constantes 1son gratis. La solución con menos puntos gana. Tiebreak es la primera publicación.

Permiso: su expresión tiene que ser aritméticamente correcta para reales ay "aleatorios" b. Se puede fallar en un subconjunto medida en cero de R 2 , es decir, un conjunto que no tiene área si trazada en el a- bplano cartesiano. (Es probable que esto sea necesario debido a los recíprocos de expresiones que podrían ser 0similares 1/a).

Gramática:

Este es un . No se pueden utilizar otras operaciones. En particular, esto significa que no hay funciones, condicionales, bucles o tipos de datos no numéricos. Aquí hay una gramática para las operaciones permitidas (las posibilidades están separadas por |). Un programa es una secuencia de <statement>s, donde a <statement>se da de la siguiente manera.

<statement>: <variable> = <expr>
<variable>: a | b | c | [string of letters of your choice]
<expr>: <arith_expr> | <variable> | <constant>
<arith_expr>: <addition_expr> | <reciprocal_expr> | <negation_expr> 
<addition_expr>: <expr> + <expr>
<reciprocal_expr>: 1/(<expr>)
<negation_expr>: -<expr>
<constant>: 1

En realidad, no tiene que publicar código en esta gramática exacta, siempre que esté claro lo que está haciendo y su recuento de operaciones sea correcto. Por ejemplo, puede escribir a-bpara a+(-b), y considero como dos operaciones, o definir macros para mayor brevedad.

(Hubo una pregunta anterior Multiplicar sin Multiplicar , pero permitió un conjunto de operaciones mucho más flexible).

xnor
fuente
44
¿Es esto posible?
Ypnypn
1
@Ypnypn Sí, y he escrito un ejemplo para asegurarme.
xnor
2
Esto se siente como un desafío donde es probable que se encuentre una solución óptima (una vez que se haya encontrado alguna solución). Entonces, ¿cuál es el desempate en ese caso?
Martin Ender
1
@ MartinBüttner Tiebreak es la publicación más temprana en ese caso. Creo que hay una buena cantidad de espacio para las optimizaciones, por lo que no creo que sea una carrera encontrar uno que funcione y escribirlo limpiamente. Al menos, eso es lo que encontré al intentarlo; quizás alguien encuentre una solución claramente mínima.
xnor
2
De acuerdo, ya que no todos pensaron que mi respuesta era tan divertida como yo, la eliminé y comenté aquí: la regla sobre el conjunto de medidas cero no se elige con prudencia ya que los números racionales son un conjunto de medidas cero con respecto a la medida de lebesgue, sugeriría usando un cierto porcentaje en su lugar. (U otro tipo) ¡Pero me gusta totalmente la idea de este desafío!
flawr

Respuestas:

34

22 operaciones

itx = 1/(1+a+b)     #4
nx = -1/(itx+itx)   #4
c = -( 1/(itx + itx + 1/(1+nx)) + 1/(1/(a+nx) + 1/(b+nx)) ) #14

Pruébalo en línea!

Las operaciones son 10 adiciones, 7 inversas, 2 negaciones y 3 asignaciones.

Entonces, ¿cómo conseguí esto? Comencé con la prometedora plantilla de la suma de dos fracciones de dos pisos, un motivo que había aparecido en muchos intentos anteriores.

c = 1/(1/x + 1/y) + 1/(1/z + 1/w)

Cuando restringimos la suma a x+y+z+w=0, ocurre una hermosa cancelación, dando:

c = (x+z)*(y+z)/(x+y),

que contiene un producto (A menudo es más fácil de obtener t*u/vque t*uporque el primero tiene un grado 1.)

Hay una forma más simétrica de pensar sobre esta expresión. Con la restricción x+y+z+w=0, sus valores se especifican mediante tres parámetros p,q,rde sus sumas por pares.

 p = x+y
-p = z+w
 q = x+z
-q = y+w
 r = x+w
-r = y+z

y tenemos c=-q*r/p. La suma pse distingue por estar en el denominador correspondiente a los pares (x,y)y (z,w)a las variables que están en la misma fracción.

Esta es una buena expresión para cin p,q,r, pero la fracción de dos pisos está en, x,y,z,wasí que debemos expresar la primera en términos de la segunda:

x = ( p + q + r)/2
y = ( p - q - r)/2
z = (-p + q - r)/2
w = (-p - q + r)/2

Ahora, queremos elegir p,q,rpara que sea c=-q*r/pigual a*b. Una opción es:

p = -4
q = 2*a
r = 2*b

Luego, los valores duplicados para qy rse dividen convenientemente en dos:

x = -2 + a + b
y = -2 - a - b
z =  2 + a - b
w =  2 - a + b

Guardar 2como una variable ty conectarlos a la ecuación para cda una solución de 24 operaciones.

#24 ops
t = 1+1   #2
c = 1/(1/(-t+a+b) + 1/-(t+a+b))  +  1/(1/(-b+t+a) + 1/(-a+b+t)) #1, 10, 1, 10

Hay 12 adiciones, 6 inversas, 4 negaciones y 2 asignaciones.

Se gastan muchas operaciones expresándose x,y,z,wen términos de 1,a,b. Para guardar operaciones, en lugar de expresar xen p,q,r(y por lo tanto a,b,1) y luego escribir y,z,wen términos de x.

y = -x + p
z = -x + q
w = -x + r

Elegir

p = 1
q = a
r = b

y expresando ccon una negación como c=-q*r/p, obtenemos

x = (1+a+b)/2
y = -x + 1
z = -x + a
w = -x + b

Desafortunadamente, reducir a la mitad xes costoso. Debe hacerse invirtiendo, agregando el resultado a sí mismo e invirtiendo nuevamente. También negate a producir nxpara el -x, ya que es lo y,z,wuso. Esto nos da la solución de 23 operaciones:

#23 ops
itx = 1/(1+a+b)     #4
nx = -1/(itx+itx)   #4
c = -( 1/(1/(-nx) + 1/(1+nx))  +  1/(1/(a+nx) + 1/(b+nx)) ) #15

itxes 1 / (2 * x) y nxes -x. Una optimización final de la expresión 1/xcomo en itx+itxlugar de la plantilla 1/(-nx)corta un carácter y reduce la solución a 22 operaciones.

xnor
fuente
Hay una optimización fácil para 21 operaciones. itx + itxocurre dos veces, pero itxno ocurre en ningún otro contexto. Defina en su lugar ix = (1+1)/(1+a+b)y reemplace dos adiciones con una.
Peter Taylor
Y extrayendo m = -1es posible obtener 20:nx = (1+a+b)/(m+m); c = m/(m/nx + 1/(1+nx)) + m/(1/(a+nx) + 1/(b+nx))
Peter Taylor
3
Ah, ambas optimizaciones fallan porque la operación admitida es recíproca en lugar de división.
Peter Taylor
Si ay bestán separados uno por uno, entonces a + nx = 0o b + nx = 0, lo que hace que su solución se divida por cero.
MooseOnTheRocks
1
@MooseOnTheRocks Está bien, vea la "asignación" en el desafío de que el código puede fallar en un subconjunto de medida cero. Creo que el desafío es imposible de lo contrario.
xnor
26

23 operaciones

z = 1/(1/(1/(1/(a+1)+1/(b+1))-1+1/(a+b+1+1))-(1/a+1/b))
res = z+z

prueba por explosión:

z = 1/(1/(1/(1/(a+1)+1/(b+1))-1+1/(a+b+1+1))-(1/a+1/b))
             1/(a+1)+1/(b+1)                            == (a+b+2) / (ab+a+b+1)
          1/(1/(a+1)+1/(b+1))                           == (ab+a+b+1) / (a+b+2)
          1/(1/(a+1)+1/(b+1))-1                         == (ab - 1) / (a+b+2)
          1/(1/(a+1)+1/(b+1))-1+1/(a+b+1+1)             == ab / (a+b+2)
       1/(1/(1/(a+1)+1/(b+1))-1+1/(a+b+1+1))            == (a+b+2) / ab
                                              1/a+1/b   == (a+b) / ab
       1/(1/(1/(a+1)+1/(b+1))-1+1/(a+b+1+1))-(1/a+1/b)  == 2 / ab
    1/(1/(1/(1/(a+1)+1/(b+1))-1+1/(a+b+1+1))-(1/a+1/b)) == ab / 2

z = ab / 2 and therefore z+z = ab

Abusé de wolfram alpha para obtener esta hermosa imagen (wolfram alpha intentó que me suscribiera a pro para guardarla, pero luego ctrl-c ctrl-v ;-)):

puntuación (con suma +en la resta):

z = ////++/++-+/++++-/+/
res = +
orgulloso Haskeller
fuente
¡Felicidades por la solución más corta!
xnor
@xnor gracias por darme mi primera respuesta aceptada y mi primera recompensa!
orgulloso Haskeller
No debe ser quisquilloso, pero no debería ... (b + 1)) - 1 + 1 ... y ... 1)) - (1 / a + ... ser ... (b + 1 )) + - 1 + 1 ... y ... 1)) + - (1 / a + ... respectivamente?
tfitzger
@tfitzger Creo que es más fácil de esa manera. La pregunta dice que no importa. Tenga en cuenta que sí cuento la puntuación correctamente (cada menos es un dos)
orgulloso Haskeller
Wolfram Alpha tiene una prueba gratuita de 7 días, para tu información.
ghosts_in_the_code
13

29 operaciones

No funciona para el conjunto {(a, b) ∈ R 2 | a + b = 0 o a + b = -1 o ab = 0 o ab = -1}. Eso probablemente mide cero?

sum = a+b
nb = -b
diff = a+nb
rfc = 1/(1/(1/sum + -1/(sum+1)) + -1/(1/diff + -1/(diff+1)) + nb + nb)  # rfc = 1/4c
c = 1/(rfc + rfc + rfc + rfc)

# sum  is  2: =+
# nb   is  2: =-
# diff is  2: =+
# rfc  is 18: =///+-/++-//+-/+++
# c    is  5: =/+++
# total = 29 operations

La estructura de rfc(Reciprocal-Four-C) es más evidente si definimos una macro:

s(x) = 1/(1/x + -1/(x+1))              # //+-/+ (no = in count, macros don't exist)
rfc = 1/(s(sum) + - s(diff) + nb + nb) # =/s+-s++ (6+2*s = 18)

Hagamos los cálculos:

  • s(x), matemáticamente, es lo 1/(1/x - 1/(x+1))que está después de un poco de álgebra es x*(x+1)o x*x + x.
  • Cuando subes todo en rfc, es realmente lo 1/((a+b)*(a+b) + a + b - (a-b)*(a-b) - a + b + (-b) + (-b))que es justo 1/((a+b)^2 - (a-b)^2).
  • Después de diferencia de cuadrados, o simplemente la expansión normal, se obtiene que rfces 1/(4*a*b).
  • Finalmente, ces el recíproco de 4 veces rfc, por lo que se 1/(4/(4*a*b))convierte a*b.
Algoritmo de tiburón
fuente
2
+1, estaba en el medio de terminar este cálculo idéntico
Eric Tressler
1
Eso definitivamente mide cero; Es una unión de líneas.
xnor
No voy a hacer un comentario sobre la unión de líneas ... @algorithmshark ¿Puedes contarnos más cómo se te ocurrió esta identidad? ¿Cómo abordó el problema?
flawr
1
@flawr Recordé que las propiedades de s(x)los requisitos de la pregunta se ajustaban al cálculo, por lo que eso significaba que tenía una función cuadrada. Después de algunas dudas, descubrí que podía obtener un a*btérmino con el truco de diferencia de cuadrados. Una vez que tuve eso, fue cuestión de probar qué tareas guardaban operaciones.
algormshark
Dado que usas -1tres veces rfc, ¿no podrías jugar golf a un personaje asignándolo a una variable?
isaacg
9

27 operaciones

tmp = 1/(1/(1+(-1/(1/(1+(-a))+1/(1+b))))+1/(1/(1/b+(-1/a))+1/(a+(-b))))
res = tmp+tmp+(-1)

# tmp is 23: =//+-//+-+/++///+-/+/+-
# res is 4: =++-

No hay ninguna teoría detrás de esto. Sólo traté de conseguir (const1+a*b)/const2y empecé con (1/(1-a)+1/(1+b))y (-1/a+1/b).


fuente
Tu tmpes en realidad 23, haciendo que tu puntaje sea 27. Sin embargo, es un buen hallazgo.
algorithmshark