What is at issue is that the obvious "greedy" algorithm for making change that proceeds by doling out as many coins as possible in decreasing order of value does not always work. Given only a 5 cent and a 2 cent coin, we cannot make 16 cents in change by first taking three 5's and then proceeding to dole out 2's. In fact we must use two 5's and three 2's to make 16 cents. Here's a method that works for any set of coins:With that in mind, I have written something in Perl that parallels his solution as closely as I could:The idea is to proceed greedily, but if we get "stuck", we undo the most recent greedy decision and proceed again from there. Simulate evaluation of the example of change [5,2] 16 to see how the code works.exception Change fun change _ 0 = nil | change nil _ = raise Change | change (coin::coins) amt = if coin > amt then change coins amt else (coin :: change (coin::coins) (amt-coin)) handle Change => change coins amt
use strict; use warnings; my $amount = 16; my $coinset = [5,2]; { my $Exception = 0; sub change { my ($cset, $amt) = @_; if ($amt == 0) { return [] } if (@$cset == 0) { $Exception = 1; return [] } my $coin = shift @$cset; if ($coin > $amt) { print "$coin > $amt\n"; return [change($cset, $amt)]; } else { print "Checking $amt - $coin\n"; my $rval = [$coin, @{change( [$coin, @$cset], $amt - $coin )}]; if ($Exception) { print "Exception forces backing up to $amt\n"; $Exception = 0; $rval = [@{change($cset, $amt)}]; } return $rval; } } } use Data::Dumper; print Dumper(change($coinset, $amount)), "\n";
In reply to Re: pathsearch/backtracking in Perl - how to solve a problem apparently requiring it? (comparison of Perl with Standard ML)
by Roy Johnson
in thread pathsearch/backtracking in Perl - how to solve a problem apparently requiring it? (comparison of Perl with Standard ML)
by metaperl
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |