So, I wanted to be able to write a function that will figure out all the ways that you could make change for a specific amount of money, using coins of different values.
So, I wrote a function coin
that tells you for a given amount, how many ways you can make change for that value, given a certain value coin, and a function that will calculate how many ways you could make change, with the same kinds of parameters for the next smaller coin.
I then tried to write a function ladder
that I want to return a function that for an @array of coin values will return a function takes a single formal parameter $amt
that calculates the number of ways that you could make change for that amount given the values of the coins specified in the array.
I tried to use the &coin
function with an .assuming
method to add in the values of coins and build up the appropriate ladder. Unfortunately, it hangs when I try to run the resulting function.
my @values = 2, 5, 10, 20, 50, 100, 200;
#the coin of value 1 is assumed as a base case
my &test = ladder(@values);
say &test(5);
sub ladder(@values) {
my &base = sub () { return @values.shift };
for @values {
&base = &coin.assuming(*,$_,&base);
}
return &base;
}
sub coin($amt,$value,&lesser) {
if $amt >= $value {
return &coin($amt-$value,$value,&lesser) + &lesser($amt);
} else {
return &lesser($amt);
}
}
To give an idea it &ladders should produce the equivalent of &twopd in the below series of functions.
sub twopd($amt) { return &coin($amt,200,&onepd) };
sub onepd($amt) { return &coin($amt,100,&fifp) };
sub fifp($amt) { return &coin($amt,50,&twep) };
sub twep($amt) { return &coin($amt,20,&tenp) };
sub tenp($amt) { return &coin($amt,10,&fivp) };
sub fivp($amt) { return &coin($amt,5,&twop) };
sub twop($amt) { return &coin($amt,2,&onep) };
sub onep($amt) { return 1 };
I was wondering if anyone might have an idea what I am doing wrong.