Multiply with restricted operations There's a 500 rep unofficial bounty for beating the current best answer.


Goal 

Your goal is to multiply two numbers using only a very limited set of arithmetic operations and variable assignment. 


Addition x,y -&gt; x+y
Reciprocal x -&gt; 1/x (not division x,y -&gt; x/y)
Negation x -&gt; -x (not subtraction x,y -&gt; x-y, though you can do it as two operations x + (-y))
The constant 1 (no other constants allowed, except as produced by operations from 1)
Variable assignment [variable] = [expression]  


Scoring: The values start in variables a and b. Your goal is to save their product a*b into the variable c using as few operations as possible. Each operation and assignment +, -, /, = costs a point (equivalently, each use of (1), (2), (3), or (4)). Constants 1 are free. The fewest-point solution wins. Tiebreak is earliest post.

Allowance: Your expression has to be arithmetically correct for "random" reals a and b. It can fail on a measure-zero subset of R2, i.e. a set that has no area if plotted in the a-b Cartesian plane. (This is likely to be needed due to reciprocals of expressions that might be 0 like 1/a.)

Grammar: 

This is an atomic-code-golf. No other operations may be used. In particular, this means no functions, conditionals, loops, or non-numerical data types. Here's a grammar for the allowed operations (possibilities are separated by |). A program is a sequence of &lt;statement&gt;s, where a &lt;statement&gt; is given as following.

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


You don't actually have to post code in this exact grammar, as long as it's clear what you're doing and your operation count is right. For example, you can write a-b for a+(-b) and count it as two operations, or define macros for brevity.

(There was a previous question Multiply without Multiply, but it allowed a much looser set of operations.)
22 operations



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


Try it online!

The ops are 10 additions, 7 inverses, 2 negations, and 3 assignments.

So, how did I get this? I started with the promising-looking template of the sum of two double-decker fractions, a motif that had appeared in many previous attempts.

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

When we restrict the sum to x+y+z+w=0, a beautiful cancellations occur, giving:

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

which contains a product. (It's often easier to get t*u/v rather than t*u because the first has degree 1.)

There's a more symmetric way to think about this expression. With the restriction x+y+z+w=0, their values are specified by three parameters p,q,r of their pairwise sums.

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


and we have c=-q*r/p. The sum p is distinguished as being in the denominator by corresponding to the pairs (x,y) and (z,w) of variables that are in the same fraction.

This is a nice expression for c in p,q,r, but the double-decker fraction is in x,y,z,w so we must express the former in terms of the latter:

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


Now, we want to choose p,q,r so that c=-q*r/p equals a*b. One choice is:

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


Then, the doubled values for q and r are conveniently halved in:

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


Saving 2 as a variable t and plugging these into the equation for c gives a 24-op solution.

#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


There's 12 additions, 6 inverses, 4 negations, and 2 assignments.

A lot of ops are spent expressing x,y,z,w in terms of 1,a,b. To save ops, instead express x in p,q,r (and thus a,b,1) and then write y,z,w in terms of x.

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


Choosing

p = 1
q = a
r = b


and expressing c with a negation as c=-q*r/p, we get

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


Unfortunately, halving in x is costly. It needs to be done by inverting, adding the result to itself, and inverting again. We also negate to produce nx for -x, since that's what y,z,w use. This gives us the 23-op solution: 

#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 is 1/(2*x) and nx is -x. A final optimization of expressing 1/x as itx+itx instead of the templated1/(-nx) cuts a character and brings the solution down to 22 ops.