If the OP wants any single valid set, then this seems to work. If he wants all valid sets, no joy. I added a 10.00 and a 0.22 to the $values array and varied the position of the 10.00 (before and after 3.76) and it seems to pull the first set where the first member in the $values array is a member of the set. For a second there, I thought it pulled the set where the largest possible member in the $values array is also in the set. Maybe it meets the needs of the OP? > Date: Tue, 9 Oct 2007 18:34:25 -0700 > From: lists@xxxxxxxxx > To: jblanchard@xxxxxxxxxx > CC: php-general@xxxxxxxxxxxxx > Subject: Re: Looking for help with a complex algorithm > > Jay Blanchard wrote: > > [snip] > > what is it suppose to return if it cannot find records that the exact > > total do not match the total > > you are looking for? should it return nothing? > > [/snip] > > > > Correct. It should say that there are no records that generate a match. > > > > Ok, so based off what you were asking for, here is a function that I > think does what you are looking to do. > > So, test for false on the returned value and if it is false, the > function could not find any matches that together would total the amount > you are asking for. Otherwise, it returns the array of items that will > total the amount that you are trying to match. > > Let me know if it works for you. > > <plaintext><?php > > function getTotal($total, $values, &$currentValue) { > $items = array(); > > foreach ( $values AS $row ) { > list($id, $value) = $row; > $items[] = array('id' => $id, 'value' => round($value, 2)); > $currentValue += round($value, 2); > > if ( round($currentValue, 2) > round($total, 2) ) { > $currentValue -= round($value, 2); > array_pop($items); > continue; > } > > if ( round($currentValue, 2) == round($total, 2) ) { > $stack = array(); > foreach ($items AS $id => $val) { > if ( in_array($val['id'], $stack) ) { > unset($items[$id]); > } else { > $stack[] = $val['id']; > } > } > return $items; > } > > if ( ( $new = getTotal(round($total, 2), array_slice($values, 1), > round($currentValue, 2)) ) === false ) { > $currentValue -= round($value, 2); > array_pop($items); > } else { > $items = array_merge($items, $new); > } > } > $tv = 0; > foreach ( $items AS $tmp_value ) { > $tv += round($tmp_value, 2); > } > if ( round($tv, 2) != round($total, 2) ) { > return false; > } > $testing = array(); > foreach ( $items AS $row ) { > $testing[$row['id']] = $row['value']; > } > return $testing; > } > > $values[] = array(1,3.98); > $values[] = array(2,9.77); > $values[] = array(3,3.76); > $values[] = array(4,4.13); > $values[] = array(5,7.86); > $values[] = array(6,1.45); > $values[] = array(7,12.87); > $values[] = array(8,10.01); > $values[] = array(9,0.88); > > var_dump(getTotal(10.22, $values, $value)); > > ?> > > my results are > > <plaintext>array(4) { > [0]=> > array(2) { > ["id"]=> > int(3) > ["value"]=> > float(3.76) > } > [1]=> > array(2) { > ["id"]=> > int(4) > ["value"]=> > float(4.13) > } > [2]=> > array(2) { > ["id"]=> > int(6) > ["value"]=> > float(1.45) > } > [3]=> > array(2) { > ["id"]=> > int(9) > ["value"]=> > float(0.88) > } > } > > > > -- > Jim Lucas > > > "Perseverance is not a long race; > it is many short races one after the other" > > Walter Elliot > > > > "Some men are born to greatness, some achieve greatness, > and some have greatness thrust upon them." > > Twelfth Night, Act II, Scene V > by William Shakespeare > > -- > PHP General Mailing List (http://www.php.net/) > To unsubscribe, visit: http://www.php.net/unsub.php > _________________________________________________________________ Peek-a-boo FREE Tricks & Treats for You! http://www.reallivemoms.com?ocid=TXT_TAGHM&loc=us