Wait the light to fall

🎄 11/25. 在 Raku 中解决34号问题

焉知非鱼

欢迎来到 Raku One-Liner Advent Calendar 的第11天! 今天,日历文章完全致力于解决欧拉计划的问题34。 如果你想在看到我的答案之前找到自己的答案,请再次暂停阅读。

因此,任务是找到所有数字的总和,它们等于其数字的阶乘的总和。 听起来很清楚? 🙂 你可以看一下单行程序的解决方案,以便更好地理解它。

say [+] (3..50_000).grep({$_ == [+] .comb.map({[*] 2..$_})})

让我们从……开始吧。

我们循环范围 3 .. 50_000。上边界是基于某些要考虑因素的猜测。我不会在这里解释,但如果你好奇,你可能会试着找到答案。基本上,在某些时候你会理解这个数字要么包含太多数字,要么本身就太大了。请参阅有关 Project Euler 的讨论以获得纯理论的解释。

第二步是 grep。我们正在搜索与总和相等的数字($_ ==)。它是通过第二个化简加号 [+] 计算出来的,但你可以使用 sum 方法代替:

{$_ == .comb.map({[*] 2..$_}).sum}

请注意 .comb 是一个在默认变量 $_ 上调用的方法。 comb 方法将数字拆分为单独的数字(作为字符)。 map 方法将每个数字转换为阶乘(再次使用化简运算符 [*],就像我们昨天所做的那样)。

最后,最外层的 [+] 将所有 grepped 的数字相加,并将结果传递给 say 例程。

虽然主要想法是展示一个单行,但在实际操作中,在使用它们之前准备因子是更明智的:

my @f = (0..9).map({[*] 1..$_});
say [+] (3..50_000).grep({$_ == [+] .comb.map({@f[$_]})});

这就是今天故事的结局。这个日历的其余部分还有更多内容!