Perl 6 - Curried 函数挂起

Perl 6 - Curried Function Hangs

所以,我希望能够编写一个函数,找出使用不同价值的硬币找零特定金额的所有方法。

所以,我写了一个函数 coin 告诉你对于给定的金额,你可以用多少种方法来改变这个价值,给定一个特定价值的硬币,以及一个函数来计算有多少种方法你可以做出改变,对下一个较小的硬币使用相同类型的参数。

然后我尝试编写一个函数 ladder 我想要 return 一个函数,对于硬币值的@array return 一个函数采用单个形式参数 $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);
        }
}

为了给出一个想法,&ladders 应该在下面的函数系列中产生与 &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 };

我想知道是否有人知道我做错了什么。

  • 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 );
    }
}