🎄 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[$_]})});
这就是今天故事的结局。这个日历的其余部分还有更多内容!