所以,我希望能够编写一个功能,使用不同价值的硬币,找出你可以用特定金额进行更改的所有方法。
所以,我写了一个函数coin
,它告诉你一个给定的数量,你可以用多少种方法改变这个值,给定一个特定的值硬币,以及一个函数来计算你能用多少种方法使用与下一个较小硬币相同的参数进行更改。
然后我尝试编写一个函数ladder
,我希望返回一个函数,对于某个硬币值的@array将返回一个函数需要一个正式参数$amt
来计算方式的数量考虑到数组中指定的硬币值,您可以对该金额进行更改。
我尝试使用&coin
函数和.assuming
方法添加硬币值并构建适当的梯形图。不幸的是,当我尝试运行生成的函数时,它会挂起。
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);
}
}
要想一想,它和梯子应该在下面的一系列功能中产生相当于& twopd。
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 };
我想知道是否有人可能知道我做错了什么。
答案 0 :(得分:11)
sub () { return @values.shift }
每次调用时都会从@values
中移除一个值,这不是您想要的。
&coin.assuming(*,$_,&base)
需要对&base
执行某些操作,以便它获取&base
中的当前值,而不是循环结束时的剩余内容。一种选择是在其前面添加|
,另一种选择是使用<>
对值进行去包容。
向coin
添加一些缓存可能是个好主意,因为对于较大的值,它会多次使用相同的参数进行调用。
sub ladder ( +@ ($initial, *@values) ) {
my &base = -> $ { $initial };
for @values {
&base = &coin.assuming: *, $_, &base<>;
}
return &base;
}
use experimental :cached;
sub coin ( $amt, $value, &lesser ) is cached {
if $amt >= $value {
coin( $amt - $value, $value, &lesser ) + lesser($amt);
} else {
lesser( $amt );
}
}