This is a combinatorial problem. Basically, you want to be generating a list of all possible distinct combinations of numbers from your list. That is to say:
Lets say you have five transactions in an array ([] is standard notation for an array):
[10, 20, 30, 40, 50]
You want to find all possible combinations of transactions from this list, and sum each combination. To do that, you need to loop through your transaction list, choosing R items from your list of N transactions (aka your "alphabet"). For R = 2, you'll have the following list:
10, 20
10, 30
10, 40
10, 50
20, 30
20, 40
20, 50
30, 40
30, 50
40, 50
NOTE - The formula to calculate the total number of combinations is:
n!/(r!(n-r)!)
So it should be immediately obvious that as N and R increase, the number of combinations can get extremely big, extremely quick.
On to the algorithm...
1. First you want to begin selecting elements from the set. Since you don't know how many elements you're going to require to form your total, you should begin with a selection R = 1, working your way up to R = N. The smaller R is, the less expensive the computation, so that's why we begin at R = 1.
2. Next, you have to add R elements to a new set and calculate the sum, halting the program if you encounter your target number. I personally would choose recursion for an N < 100 and R < 20 or so, otherwise I'd choose an iterative approach. Explaining recursion and iteration is too big of a task to accomplish in one post, but there's a wealth of information on the internet about it.
However, here's a quick and dirty example in Ruby, which is super helpful and natively provides the Array#combination instance method, which generates all possible combinations for us:
Code:
<li># the silly arithmetic on line 4 is to round off the float error in ruby 1.8 and lower</li><ol><li>values = [2859.34, 128.33, 483.44, 592.22, 1820.00, 500.00, 719.19, 1400.00, 300.00]</li>
<li>target = 5278.53</li>
<li>1.upto(values.size) { |n|</li>
<li> values.combination(n) { |c|</li>
<li> p c if (100*c.reduce(:+)).round.to_f/100 == (100*target).round.to_f/100</li>
<li> }</li>
<li>}</li></ol>