How do I ask a teller for money at the bank? I need to go to the bank and withdraw some money.  I need to withdraw $30, $22 to pay my roommate for the internet and $8 for laundry.  Since neither of these can make change, I need my $30 to be split into two partitions of the two sizes.  That means when the teller asks me how I want my $30 I am going to have to make a request.  I could tell them I want it in a twenty, a fiver, and five ones.  But I want to make my request as simple as possible as to avoid having to repeat myself.  To make my request simpler I could ask that my cash contain a twenty and at least 2 ones because the 8 is implied by the total, but better yet I could simply request that one of the bills I receive be a one dollar bill (If you are not convinced of this just try to make 29 dollars without making 8).

So that's all fine and dandy but I need to do this calculation every time I go to the bank so I thought I would write a program to do this (have you write a program to do this for me).

Your program or function should take a list of integers representing all the payments I need to make and a set of integers representing the denominations of bills available at the bank, and you must output the smallest list of denominations such that every way to make the total that includes that list of denominations can be cleanly divided into the list of payments.

Extra rules


You may assume that the denomination list will always contain a 1 or you may add it to each list yourself.
Some inputs will have multiple minimal solutions. In these cases you may output either one. 


This is code-golf so answers will be scored in bytes with less bytes being better.

Test Cases

Payments, denominations    -&gt; requests
{22,8}    {1,2,5,10,20,50} -&gt; {1} or {2}
{2,1,2}   {1,5}            -&gt; {1}
{20,10}   {1,2,5,10,20,50} -&gt; {}
{1,1,1,1} {1,2}            -&gt; {1,1,1}
{20,6}    {1,4,5}          -&gt; {1}
{2,6}     {1,2,7}          -&gt; {2}
{22, 11}  {1, 3, 30, 50}   -&gt; {1, 3}
{44, 22}  {1, 3, 30, 50}   -&gt; {1, 3, 3, 30}
JavaScript (ES6), 485 476 bytes

Alright ... this is a monster. :-(
But it's a rather fast monster that solves all test cases almost instantly.

I may attempt some more advanced golfing later, but I've already spent far too much time on it.

f=(b,a,L=[...a])=&gt;L.reduce((a,x)=&gt;[...a,...a.map(y=&gt;[x,...y])],[[]]).sort((a,b)=&gt;a[b.length]||-1).find(L=&gt;(Y=G(U(b)-U(L),L.sort((a,b)=&gt;a-b)),Y[0]&amp;&amp;!Y.some(a=&gt;P(b.map(a=&gt;G(a,[]))).every(b=&gt;b+''!=a))),U=a=&gt;~~eval(a.join`+`),P=(e,C=[],R=[])=&gt;e[0].map(v=&gt;R=(c=v.map((x,i)=&gt;x+(C[i]|0)),e[1])?[...P(e.slice(1),c),...R]:[c,...R])&amp;&amp;R,G=(n,l)=&gt;(S=[],g=(n,l)=&gt;n?a.map(x=&gt;x&lt;l[0]|x&gt;n||g(n-x,[x,...l])):S=[l.map(v=&gt;s[a.indexOf(v)]++,s=[...a].fill(0))&amp;&amp;s,...S])(n,l)&amp;&amp;S)||f(b,a,[...a,...L])


Test cases



f=(b,a,L=[...a])=&gt;L.reduce((a,x)=&gt;[...a,...a.map(y=&gt;[x,...y])],[[]]).sort((a,b)=&gt;a[b.length]||-1).find(L=&gt;(Y=G(U(b)-U(L),L.sort((a,b)=&gt;a-b)),Y[0]&amp;&amp;!Y.some(a=&gt;P(b.map(a=&gt;G(a,[]))).every(b=&gt;b+''!=a))),U=a=&gt;~~eval(a.join`+`),P=(e,C=[],R=[])=&gt;e[0].map(v=&gt;R=(c=v.map((x,i)=&gt;x+(C[i]|0)),e[1])?[...P(e.slice(1),c),...R]:[c,...R])&amp;&amp;R,G=(n,l)=&gt;(S=[],g=(n,l)=&gt;n?a.map(x=&gt;x&lt;l[0]|x&gt;n||g(n-x,[x,...l])):S=[l.map(v=&gt;s[a.indexOf(v)]++,s=[...a].fill(0))&amp;&amp;s,...S])(n,l)&amp;&amp;S)||f(b,a,[...a,...L])

console.log(JSON.stringify(f([22,8], [1,2,5,10,20,50])))
console.log(JSON.stringify(f([2,1,2], [1,5])))
console.log(JSON.stringify(f([20,10], [1,2,5,10,20,50])))
console.log(JSON.stringify(f([1,1,1,1], [1,2])))
console.log(JSON.stringify(f([20,6], [1,4,5])))
console.log(JSON.stringify(f([2,6], [1,2,7])))
console.log(JSON.stringify(f([22,11], [1,3,30,50])))
console.log(JSON.stringify(f([44,22], [1,3,30,50])))




How?

NB: This is not matching the current version anymore, but is much easier to read that way.

// b = list of payments, a = list of bills,
// L = list from which the requested bills are chosen
f = (b, a, L = [...a]) =&gt; (
  // U = helper function that computes the sum of an array
  U = a =&gt; ~~eval(a.join`+`),

  // P = function that computes the summed Cartesian products of arrays of integers
  // e.g. P([[[1,2],[3,4]], [[10,20],[30,40]]]) --&gt; [[33,44], [13,24], [31,42], [11,22]]
  P = (e, C = [], R = []) =&gt; e[0].map(v =&gt; R =
    (c = v.map((x, i) =&gt; x + (C[i] | 0)), e[1]) ? [...P(e.slice(1), c), ...R] : [c, ...R]
  ) &amp;&amp; R,

  // G = function that takes a target amount and a list of requested bills and returns
  // all combinations that contain the requested bills and add up to this amount;
  // each combination is translated into a list of number of bills such as [2,0,0,1,0]
  G = (n, l) =&gt; (
    S = [],
    g = (n, l) =&gt; n ?
      a.map(x =&gt; x &lt; l[0] | x &gt; n || g(n - x, [x, ...l])) :
      S = [l.map(v =&gt; s[a.indexOf(v)]++, s = [...a].fill(0)) &amp;&amp; s, ...S]
  )(n, l) &amp;&amp; S,

  // compute X = list of possible bill combinations to process all payments
  X = P(b.map(a =&gt; G(a, []))),

  // compute the powerset of L and sort it from shortest to longest list
  L.reduce((a, x) =&gt; [...a, ...a.map(y =&gt; [x, ...y])], [[]])
  .sort((a, b) =&gt; a[b.length] || -1)

  .find(L =&gt; (
    // compute Y = list of possible combinations to reach the total amount,
    // using the requested bills
    Y = G(U(b) - U(L), L.sort((a, b) =&gt; a - b)),

    // exit if Y is not empty and all combinations in Y allow to generate all payments
    Y[0] &amp;&amp; !Y.some(a =&gt; X.every(b =&gt; b + '' != a)))
  )

  // if no solution was found, enlarge the set of requested bills and try again
  || f(b, a, [...a, ...L])
)