Let us call this problem the Slinger-Bird problem (actually the Slinger is analogous to a server and the bird to a request but I was having a nervous breakdown thinking abou
I suggest using bitmaps for the slingers and birds, i.e.
S1 = B1 = 1, S2 = B2 = 2, S3 = B3 = 4, B4 = 8
Then the input data can be written as
bird_data = [[3, 0, 1], [7, 1, 12], [8, 3, 0], [0, 12, 15]]
The cost function can now be written like this:
def cost(shots):
hit = units = 0
for show, shot in zip(bird_data, shots):
units += 1
for n, birds in enumerate(show):
if shot & 1:
units += 1
hit |= birds
if hit == 15: # all are hit
return units
shot >>= 1
return 99 # penalty when not all are hit
Now it's easy to find the optimal shots by calculating the minimum of the cost function:
from itertools import product
shot_sequences = product(*([range(7)]*len(bird_data)))
print min((cost(shots), shots) for shots in shot_sequences)
This prints
(4, (0, 5, 0, 0))
which means the optimum is 4 units, when S1 and S3 (5 = 1 + 4) fire at t=2. Of course your solution is also possible, where S1 fires at t=1 and S3 at t=2, both have the same cost.
However, since the algorithm is using brute force, running over all possible shot sequences, it is only fast and feasible when the data sets are very small, like in your example.