【问题标题】:Questions on the prime number calculating code in Raku关于Raku中素数计算代码的问题
【发布时间】:2020-03-09 12:14:59
【问题描述】:

我在RosettaCode看到了这段代码

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

在显式生成器块内:

1- @_ 指的是什么或哪个序列?

2- 第一个* 指的是什么?

3- @_[* - 1] 和下一个 * 中的 * 指的是什么?

4- 序列(@_[* - 1], * + 2 ... Inf) 如何用于查找素数?

谢谢。

【问题讨论】:

    标签: sequence primes raku


    【解决方案1】:

    外层序列算子可以理解为:以2和3开始序列,然后运行block中的代码,计算出下面的每一个值,一直到无穷大。

    序列运算符将传递该块所需的尽可能多的参数。例如,斐波那契数列表示为1, 1, * + * ... Inf,其中* + * 是lambda -> $a, $b { $a + $b } 的简写;由于这需要两个参数,因此它将被赋予序列中的前两个值。

    当我们在一个块中使用@_ 时,就好像我们写了一个像-> *@_ { } 这样的lambda,这是一个slurpy。当与... 一起使用时,表示我们希望传递所有序列中之前的值。

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

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

    接下来,@_[* - 1], * + 2 ... Inf,是要搜索的值序列,直到我们找到下一个素数。这采取以下形式:第一个值,如何获得下一个值,并一直持续到无穷大。

    第一个值是我们找到的最后一个素数。再一次,* - 1 是一个闭包,它接受一个参数并从中减去 1。当我们将代码传递给数组索引器时,它会使用元素的数量来调用。因此,@arr[* - 1] 是 Raku 习语,表示“数组中的最后一件事”,@arr[* - 2] 是“数组中倒数第二个”,等等。

    * + 2 计算序列中的下一个值,它是一个闭包,它接受一个参数并将其加 2。虽然我们实际上可以只做一个简单的范围 @_[* - 1] .. Inf 并得到正确的结果,但检查所有偶数是很浪费的,因此 * + 2 可以产生一个奇数序列。

    所以,直观地说,这一切都意味着:下一个素数是第一个(奇数)值,之前的素数都没有分成。

    【讨论】:

    • 感谢您的回答。看到它是first 子的闭包,这就是断点。我不知道first会关闭。代码现在看起来更容易理解了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多