在Raku中计算质数的代码问题

6

我在RosettaCode上找到了这段代码。

constant @primes = 2, 3, { first * %% none(@_), (@_[* - 1], * + 2 ... Inf) } ... Inf;
say @primes[^10];

在显式生成器块内:
1- @_指的是哪个序列?
2- 第一个*指的是什么?
3- @_[* - 1]中的*和下一个*指的是什么?
4- 序列(@_[* - 1], * + 2 ... Inf)如何用于查找质数?
谢谢。
1个回答

10

外部序列运算符可以理解为:以2和3开始序列,然后运行块中的代码计算出每个后续值,并保持不断进行直到无穷。

序列运算符将该块作为它所请求的参数传递。例如,斐波那契数列表示为1, 1, * + * ... Inf,其中* + *是lambda的简写,即-> $a, $b { $a + $b };因为这需要两个参数,所以它将得到序列中前两个值。

当我们在块中使用@_时,就好像我们编写了一个lambda,例如-> *@_ { },它是一个slurpy类型。与...一起使用时,意味着我们希望获得序列中所有之前的值。

子程序first接受一个谓词(我们评估并返回true或false的东西)和要搜索的值列表,并返回匹配谓词的第一个值。(阅读此类内容的提示:每当我们执行类似于function-name arg1,arg2的调用时,我们总是解析参数的术语,这意味着我们知道*不能是乘法运算符。)

我们给first的谓词是* %% none(@_)。这是一个闭包,它需要一个参数并检查它是否无法被序列中以前的任何值整除-因为如果是,它就不可能是质数!

接下来的序列 @_[* - 1], * + 2 ... Inf 是需要搜索的值,直到找到下一个质数为止。它采用以下形式:第一个值,如何获取下一个值,一直保持搜索直到无穷大。
第一个值是上次我们找到的质数。再次提醒,* - 1 是一个闭包,接受一个参数并从中减去1。当我们将代码传递给数组索引器时,它会带有元素的数量被调用。因此,@arr[* - 1] 是指“数组中的最后一个元素”,@arr[* - 2] 就是指“数组中的倒数第二个元素”,以此类推。 * + 2 计算出序列中的下一个值,并且是一个闭包,接受一个参数并将其加上2。虽然我们实际上可以简单地使用范围 @_[* - 1] .. Inf 来获得正确的结果,但检查所有偶数会浪费时间,因此 * + 2 可以产生一个奇数序列。
因此,直观地讲,这意味着:下一个质数是前面任何一个质数都不能整除的第一个(奇数)值。

谢谢你的回答。看到它是first子程序的闭包已经是一个突破点了。我不知道first会采取闭包。现在代码看起来更容易理解了。 - Lars Malmsteen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接