BrainF***-optimize a series of numbers An often-used trick in BF-golfing is something I call "multiply then add."  Let's say that you want to initialize the memory to contain a series of numbers, like 87 75 68 96.  The simplest way to do this is to simply write out a long series of 326 + signs.  A better method, however is below.

++++++++++[&gt;+++++++++&gt;+++++++&gt;+++++++&gt;++++++++++&lt;&lt;&lt;&lt;-]&gt;---&gt;+++++&gt;--&gt;----


(I write this by hand, I hope it works correctly)

The basic idea is that you create a series of numbers (9,7,7,10), multiply them by a constant (10), and then add another series of numbers (-3,5,-2,-4).  My invented form of notation writes this as (10;9,7,7,10;-3,5,-2,-4) which directly corresponds to the BF code.

There is a lot of importance placed in how the numbers are divided.  If I were to pick a larger constant, then the first series of numbers would be much smaller, yet there will tend to be larger remainders after the multiplication.  If I were to pick a smaller constant, then the first series would be larger, but the second series smaller.

Your goal is to write the shortest program to find the best possible way to write a series of numbers in BF using the multiply-then-add strategy.  

Your program will recieve a series of non-negative integers.  It should find the best way to generate these numbers.

For example, lets say that it receives the series (3,16,8,4), as an easy example.  The best way to represent this is by the set of numbers (4;1,4,2,1;-1,0,0,0), which is what your program is expected to output (the exact formatting isn't as important).  This corresponds to the following program:

++++[&gt;+&gt;++++&gt;++&gt;+&lt;&lt;&lt;&lt;-]&gt;-&gt;&gt;&gt;
Python, 205 characters

def o(l):
    d=lambda l,a:[(d+1,m-a)if m&gt;a/2 else(d,m) for d,m in(divmod(x,a)for x in l)]
    a,x=min((a+sum(abs(x)+abs(y)for x,y in d(l,a)),a,d(l,a))for a in range(1,max(l)+1))[1:]
    return [a]+zip(*x)


Examples:

&gt;&gt;&gt; o([3,16,8,4])
[4, (1, 4, 2, 1), (-1, 0, 0, 0)]
&gt;&gt;&gt; o([87,75,68,96])
[11, (8, 7, 6, 9), (-1, -2, 2, -3)]
&gt;&gt;&gt; o([4,4,4])
[4, (1, 1, 1), (0, 0, 0)]
&gt;&gt;&gt; o([1,2,3,4,5,6,7,8])
[4, (0, 0, 1, 1, 1, 1, 2, 2), (1, 2, -1, 0, 1, 2, -1, 0)]


As a bonus for a very long solution, the BF formater:

def bf(l):
    N,f,s=o(l)
    return ('%s[%s%s-]%s'%(N*'+',
                           ''.join('&gt;' + x*'+' for x in f),
                           ''.join('&lt;' for _ in f),
                           ''.join('&gt;' + abs(x)*('+' if x&gt;0 else '-')for x in s)))

&gt;&gt;&gt; bf([3,16,8,4])
'++++[&gt;+&gt;++++&gt;++&gt;+&lt;&lt;&lt;&lt;-]&gt;-&gt;&gt;&gt;'