Wait the light to fall

🎄 6/25. 在 Raku 中测试回文数字

焉知非鱼

欢迎来到 Raku One-Liner Advent Calendar 的第6天! 正如昨天所承诺的那样,今天我们将解决欧拉项目的问题4。 让我再次提醒您,您可以先自己暂停阅读并自行解决问题。 我的目的是展示Raku和Perl的美妙之处。

因此,任务是找到最大的回文数(从两端读取的数字,例如1551),这是两个三位数的乘积。

换句话说,我们必须扫描999×999以下的数字,并且可以优化解决方案,但实际上,我们只需要允许数字,即乘积,因此,我们不要跳过乘法部分。

这是我们今天的单行程序:

(((999...100) X* (999...100)).grep: {$^a eq $^a.flip}).max.say

如果你正在阅读这个 advent 日历,那么你已经准备好了链式方法调用在Raku单行中使用非常方便的事实。

我们在第2天早些时候也看到了 grep 的冒号形式,但这次我们使用了一个带占位符变量的代码块。 目前还不清楚你是否可以在这里使用星号,因为我们需要在块中使用两次变量。

该行的第一部分使用十字运算符 X*,我们将在几天内回到本系列中。 它生成所有三位数字的乘积。 由于我们需要最大的数字,从右到左开始是有意义的,这就是为什么序列 999 ... 100,而不是 100 ... 999

让我们看看 grepped 乘积序列中的前几个数字:

580085 514415 906609 119911 282282 141141 853358 650056

单行并不总是非常理想。 在我们的例子中,我们需要生成整个乘积序列以找到它们中的最大值。 答案位于第三个位置,因此将 max 替换为 first 将是错误的。 但好的部分是,如果你先使用,Raku将不会生成所有数字。 还有另一个有用的方法,head,它也可以防止生成超过必要结果的方法。

以下代码运行得更快,并提供正确的结果:

(((999...100) X* (999...100)).grep:
    {$^a eq $^a.flip}).head(10).max.say

让我们今天就到此为止。 敬请关注!