Wait the light to fall

🎄 8/25. 在 Raku 中加总偶数斐波纳契数

焉知非鱼

欢迎来到今年的 Raku One-Liner Advent Calendar 的第8天。 它大约是整个系列的 ¼,并且不要忘记你可以在 Raku 中键入 ¼ 而不是0.25!

今天,我们正在解决欧拉项目的问题2。 任务是找到所有偶数斐波纳契数都低于四百万的数字的总和。

这是完整的答案:

(1, 1, * + * ... * > 4_000_000).grep(* %% 2).sum.say

从左侧或右侧解析代码同样有趣。 我们从左边开始吧。

在第一个圆括号内,我们生成一个斐波纳契数序列,从两个1开始,每个跟随的数字是前两个数之和。 在 Raku 中,您可以使用 WhateverCode 块表达它:* + * 相当于 {$^a + $^b}

Raku 序列的一个鲜为人知的特征是最终条件。 在许多例子中,你会看到裸Inf。 在我们的示例中,我们使用显式的上边界限制序列。

请注意,您不能简单地写成这样:

1, 1, * + * ... 4_000_000

要更好地将其可视化,请尝试更小的限制,例如100:

> (1, 1, * + * ... 100)
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181

当序列越过我们想要的边界时,Raku 没有停止,并继续生成数字。 只有当序列的下一个计算元素完全等于给定数字时,它才会停止它,例如:

> (1, 1, * + * ... 144)
(1 1 2 3 5 8 13 21 34 55 89 144)

如果您不知道四百万之前的斐波纳契数,请使用另一个具有布尔条件的 WhateverCode 块:*> 4_000_000。 请注意,这里的条件与你在常规循环中所写的内容相反,因为我们要求超过四百万,而不是少于。 当你必须停止序列时,这是变为 True 的条件。 如果不用星号,您可以使用默认变量:{$_ > 4_000_000}

其余的代码会greps偶数数字并把它们起来。 有关这些操作的更详细说明,请参见第2天

听起来很棒! 让我们明天再多谈谈很酷的 Raku 单行程序吧。