Moltiplicare per operazioni limitate


44

C'è una generosità non ufficiale di 500 rappresentanti per battere la migliore risposta attuale .

Obbiettivo

Il tuo obiettivo è moltiplicare due numeri usando solo un insieme molto limitato di operazioni aritmetiche e assegnazione di variabili.

  1. aggiunta x,y -> x+y
  2. Reciproco x -> 1/x( non divisione x,y -> x/y)
  3. Negazione x -> -x( non sottrazione x,y -> x-y, sebbene sia possibile farlo come due operazioni x + (-y))
  4. La costante 1(non sono consentite altre costanti, ad eccezione di quelle prodotte dalle operazioni da 1)
  5. Assegnazione variabile [variable] = [expression]

Punteggio: i valori iniziano in variabili ae b. Il tuo obiettivo è salvare il loro prodotto a*bnella variabile cusando il minor numero di operazioni possibile. Ogni operazione e assegnazione +, -, /, =costa un punto (equivalentemente, ogni utilizzo di (1), (2), (3) o (4)). Le costanti 1sono gratuite. Vince la soluzione con il minor numero di punti. Tiebreak è il primo post.

Indennità: la tua espressione deve essere aritmeticamente corretta per i reali "casuali" ae b. Può fallire su un sottoinsieme di zero di misura di R 2 , cioè un insieme che non ha area se tracciato nel piano a- bcartesiano. (È probabile che ciò sia necessario a causa dei reciproci di espressioni che potrebbero essere 0simili 1/a.)

Grammatica:

Questo è un . Non è possibile utilizzare altre operazioni. In particolare, ciò significa nessuna funzione, condizionali, loop o tipi di dati non numerici. Ecco una grammatica per le operazioni consentite (le possibilità sono separate da |). Un programma è una sequenza di <statement>s, dove a <statement>è dato come segue.

<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

In realtà non è necessario inserire il codice in questa grammatica esatta, purché sia ​​chiaro cosa stai facendo e il conteggio delle operazioni sia corretto. Ad esempio, è possibile scrivere a-bper a+(-b)e contare come due operazioni, o definire le macro per brevità.

(C'era una domanda precedente Moltiplica senza moltiplica , ma consentiva una serie di operazioni molto più rilassate.)


4
È possibile?
Ypnypn,

1
@Ypnypn Sì, e ho scritto un esempio per esserne sicuro.
xnor

2
Sembra una sfida in cui è probabile che si trovi una soluzione ottimale (una volta trovata una soluzione). Allora, qual è il pareggio in quel caso?
Martin Ender,

1
@ MartinBüttner Tiebreak è la prima pubblicazione in quel caso. Penso che ci sia un buon margine di ottimizzazione, quindi non penso che sarà solo una corsa per trovarne uno che funzioni e scriverlo in modo pulito. Almeno, è quello che ho trovato provandolo; forse qualcuno troverà una soluzione chiaramente minima.
xnor

2
Ok, dato che non tutti pensavano che la mia risposta fosse divertente come me, l'ho cancellata e commentata qui: la regola sull'insieme di misure zero non è scelta molto saggiamente poiché i numeri razionali sono una misura di zero relativa alla misura di Lebesgue, suggerirei usando invece una certa percentuale. (O un altro tipo) Ma mi piace assolutamente l'idea di questa sfida!
flawr

Risposte:


34

22 operazioni

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

Provalo online!

Le operazioni sono 10 aggiunte, 7 inverse, 2 negazioni e 3 assegnazioni.

Quindi, come ho ottenuto questo? Ho iniziato con il modello dall'aspetto promettente della somma di due frazioni a due piani, un motivo che era apparso in molti tentativi precedenti.

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

Quando limitiamo la somma a x+y+z+w=0, si verificano belle cancellazioni, che danno:

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

che contiene un prodotto. (Spesso è più facile ottenere t*u/vpiuttosto che t*uperché il primo ha un grado 1.)

C'è un modo più simmetrico di pensare a questa espressione. Con la restrizione x+y+z+w=0, i loro valori sono specificati da tre parametri p,q,rdelle loro somme a coppie.

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

e abbiamo c=-q*r/p. La somma psi distingue per essere nel denominatore corrispondente alle coppie (x,y)e (z,w)alle variabili che si trovano nella stessa frazione.

Questa è una bella espressione per cin p,q,r, ma la frazione a due piani è in, x,y,z,wquindi dobbiamo esprimere la prima in termini di seconda:

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

Ora, vogliamo scegliere in p,q,rmodo che sia c=-q*r/puguale a*b. Una scelta è:

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

Quindi, i valori raddoppiati per qe rvengono opportunamente dimezzati in:

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

Salvare 2come variabile te collegarle all'equazione per cfornisce una soluzione a 24 operazioni.

#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

Ci sono 12 aggiunte, 6 inverse, 4 negazioni e 2 assegnazioni.

Si spendono molte operazioni espresse x,y,z,win termini di 1,a,b. Per salvare ops, invece di esprimere xin p,q,r(e quindi a,b,1) e poi scrivere y,z,win termini di x.

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

scelta

p = 1
q = a
r = b

ed esprimendo ccon una negazione come c=-q*r/p, otteniamo

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

Sfortunatamente, dimezzarsi xè costoso. Deve essere fatto invertendo, aggiungendo il risultato a se stesso e invertendolo di nuovo. Neghiamo anche la produzione nxper -x, dal momento che è quello che y,z,wserve. Questo ci offre la soluzione 23-op:

#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

itxè 1 / (2 * x) ed nxè -x. Un'ottimizzazione finale dell'espressione 1/xcome itx+itxinvece del modello 1/(-nx)modellato taglia un personaggio e porta la soluzione a 22 operazioni.


C'è una facile ottimizzazione per 21 operazioni. itx + itxsi verifica due volte, ma itxnon si verifica in nessun altro contesto. Definisci invece ix = (1+1)/(1+a+b)e sostituisci due aggiunte con una.
Peter Taylor,

E estraendo m = -1è possibile ottenere 20:nx = (1+a+b)/(m+m); c = m/(m/nx + 1/(1+nx)) + m/(1/(a+nx) + 1/(b+nx))
Peter Taylor il

3
Ah, entrambe queste ottimizzazioni falliscono perché l'operazione supportata è reciproca piuttosto che divisione.
Peter Taylor,

Se ae bsono solo uno a parte, quindi uno a + nx = 0o b + nx = 0, causando la divisione della soluzione per zero.
MooseOnTheRocks

1
@MooseOnTheRocks Va bene, vedi la "tolleranza" nella sfida che il codice può fallire su un sottoinsieme di misura zero. Penso che la sfida sia impossibile altrimenti.
xnor

26

23 operazioni

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

prova di esplosione:

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

Ho abusato di wolfram alpha per ottenere questa bellissima immagine (wolfram alpha ha cercato di farmi iscrivere a pro per salvarlo, ma poi ctrl-c ctrl-v ;-)):

punteggio (con aggiunta +sulla sottrazione):

z = ////++/++-+/++++-/+/
res = +

Complimenti per la soluzione più breve!
xnor

@xnor grazie per avermi dato la mia prima risposta accettata e la mia prima taglia!
orgoglioso haskeller l'

Non essere pignolo, ma non dovrebbe ... (b + 1)) - 1 + 1 ... e ... 1)) - (1 / a + ... be ... (b + 1 )) + - 1 + 1 ... e ... 1)) + - (1 / a + ... rispettivamente?
tfitzger

@tfitzger Penso che sia più facile in questo modo. La domanda dice che non importa. Nota conto il punteggio correttamente (ogni meno è un due)
orgoglioso haskeller

Wolfram Alpha ha una prova gratuita di 7 giorni, fyi.
ghosts_in_the_code il

13

29 operazioni

Non funziona per il set {(a, b) ∈ R 2 | a + b = 0 o a + b = -1 o ab = 0 o ab = -1}. È probabilmente misura zero?

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 struttura di rfc(Reciprocal-Four-C) è più evidente se definiamo 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)

Facciamo la matematica:

  • s(x), matematicamente, è 1/(1/x - 1/(x+1))che è dopo che un po 'di algebra è x*(x+1)o x*x + x.
  • Quando subisci tutto in rfc, è davvero ciò 1/((a+b)*(a+b) + a + b - (a-b)*(a-b) - a + b + (-b) + (-b))che è giusto 1/((a+b)^2 - (a-b)^2).
  • Dopo differenza di quadrati, o solo l'espansione pianura, si ottiene che rfcè 1/(4*a*b).
  • Infine, cè il reciproco di 4 volte rfc, così 1/(4/(4*a*b))diventa a*b.

2
+1, ero nel bel mezzo del completamento di questo identico calcolo
Eric Tressler,

1
Questo è sicuramente misura zero; è un'unione di linee.
xnor

Non farò un commento sull'unione delle linee ... @algorithmshark Puoi dirci di più come hai avuto questa identità? Come hai affrontato il problema?
flawr

1
@flawr Ho ricordato che le proprietà di s(x)adattano i requisiti della domanda, dal calcolo, quindi ciò significava che avevo una funzione quadrata. Dopo un po 'di dissolvenza, ho scoperto che avrei potuto ottenere un a*btermine con la differenza del trucco dei quadrati. Una volta che l'ho avuto, si trattava di provare quali incarichi salvassero le operazioni.
algoritmo

Dato che usi -1tre volte in entrata rfc, non puoi golfare un personaggio assegnandolo a una variabile?
Isaacg,

9

27 operazioni

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: =++-

Non c'è teoria dietro questo. Ho appena provato a iniziare (const1+a*b)/const2e ho iniziato con (1/(1-a)+1/(1+b))e (-1/a+1/b).


In tmprealtà il tuo è 23, facendo il tuo punteggio 27. Bella scoperta, però.
algoritmo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.