This solution acts pretty much the same way humans act: It starts with the big number (the quarters), and once it determines that adding another quarter will put it past the target value, it moves on to the next smaller denomination and tries it. ...at least that's how I do it. ;)
use strict; use warnings; my $a_coins = [ 25, 25, 25, 10, 10, 10 , 5, 1, 1, 1, 1 ]; my $wanted = 72; my @needed = @{ make_change( $a_coins, $wanted ) }; print "@needed = $wanted\n"; sub make_change { my( $a_coins, $dest ) = @_; my @coins = sort { $b <=> $a } @{ $a_coins }; my @need; my $tally = 0; while ( @coins ) { my $current = shift @coins; next if $tally + $current > $dest; $tally += $current; push @need, $current; return \@need if $tally == $dest; } shift ( @{$a_coins} ); @need = @{ make_change( $a_coins, $dest ) }; my $check=0; foreach ( @need ) { $check += $_; } if( $check == $dest ) { return \@need; } else { die "Can't make change.\n"; } }
Updated: I've updated make_change() to use recursion to support cases such as @coins = ( 25, 10, 10, 10 ) and $wanted = 30. Now, if it is found that 25+10 exceeds 30 (which it does), 25 is discarded from the change queue, and the sub is re-run without the quarter getting in the way.
Dave
In reply to Re: making change
by davido
in thread pathsearch/backtracking in Perl - how to solve a problem apparently requiring it? (comparison of Perl with Standard ML)
by metaperl
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |