How much weight can you lift? With all the gyms closed down with the COVID-19 situation, we have to exercise with the weight we have lying around at home. The problem is, we have a small selection of plates at varying weights, and can't immediately determine if we can create a setup at the desired weight. 

Given an unsorted array of weighted plates and an unsorted array of barbells of different weights, determine the fewest amount of plates you need to put on a barbell to reach the desired weight, in ascending order mirrored at the halfway point, basically mirroring how it would be loaded on a real barbell (see example output). The plates have to be in pairs; you cannot use a particular plate an odd number of times since you put one plate on each side for equilibrium (e.g. every plate of a certain weight on one side should have a counterpart of the same weight on the otherside). If the desired weight cannot be achieved, approximate as closely as possible (while still maintaining equilibrium on both sides).


Examples:


Input (3 barbells, a set of plates, and goal weight): [[10, 45, 6], [3.5,37,20,15,2.5,15,2.5,3.5,5,7], 47]

Output (exact match, barbell and plate arrangement): [10, [3.5,15,15,3.5]



Input (3 barbells, a set of plates, and goal weight): [[10, 45, 6], [3.5,37,20,15,2.5,15,2.5,3.5,5,7], 45]

Output (exact match, barbell and plate arrangement): [45, []]



Input (3 barbells, a set of plates, and goal weight): [[10, 45, 6], [3.5,37,20,15,2.5,15,2.5,3.5,5,7], 0]

Output (closest approximation, barbell and plate arrangement): [6, []]



Input (3 barbells, a set of plates, and goal weight): [[10, 45, 6], [3.5,37,20,15,2.5,15,2.5,3.5,5,7], 9001]

Output (closest approximation, barbell and plate arrangement): [45, [2.5,3.5,15,15,3.5,2.5]]

Winners will be selected first by time complexity, then character count for tie-breaker.
Python 2, \$ O(2^{\frac{|W|}2} \cdot |B| \cdot |W| + |W|^2) \$, 203 bytes

Naive implementation, looks at all combinations of possible weights \$W\$ and barbells \$B\$.



lambda B,W,T:min([(w+w[::-1],b)for w in p(sorted(sum([W.count(x)/2*[x]for x in set(W)],[])))for b in B],key=lambda(a,b):((T-sum(a)-b)**2,len(a)))
p=lambda l:l and[l[:1]+x for x in p(l[1:])]+p(l[1:])or[l]


Try it online!

Ungolfed



def f(Barbells, Weights, Target):
  # For every pair of same weights keep one, order them ascending
  usable_weights = concat([Weights.count(x)/2 * [x] for x in set(Weights)])
  usable_weights = sorted(usable_weights)

  # list all possible combinations of symmetric weights and barbells
  possible_setups = [(w+w[::-1], b)for w in powerset(usable_weights)for b in Barbells]

  # Find the one with the weight being the closest to the target,
  # on a tie take the one with the lowest number of weights
  return min(possible_setups, key=lambda(a,b): ((Target - sum(a) - b)**2, len(a)))

concat = lambda ls:sum(ls, [])
powerset = lambda l:l and [l[:1]+x for x in powerset(l[1:])]+powerset(l[1:]) or [[]]


Try it online!