如何计算Perl 6中整数的交替和?

Eug*_*sky 5 perl6

如果数字的交替总和可被11整除,则数字可被11整除.

所以,例如,如果数字是1595,+1 -5 +9 -5 == 0那么1595可被11整除.如何实现这样的总和?这是我的解决方案,但它太复杂,只有在数字位数是偶数时才有效.

my $number = 1595;
say [+] $number.comb.map({$^a - $^b});
Run Code Online (Sandbox Code Playgroud)

最好的方法是什么?

mor*_*itz 6

say [+] 1595.comb Z* (1, -1, 1 ... *)
Run Code Online (Sandbox Code Playgroud)

要打破它:.comb返回一个字符列表,Z*将该列表与RHS上的序列按元素相乘.

该序列是几何序列,...系列运算符可以从三个元素中推导出.由于zip操作符Z以最短的顺序停止,因此我们不必小心终止RHS上的序列.

编写相同内容的另一种方法是:

say [+] 1595.comb Z* (1, -* ... *)
Run Code Online (Sandbox Code Playgroud)

哪个-*是前一个值的显式否定,应用于初始元素以生成下一个元素.

你也可以把它写成

say [+] 1595.comb Z* (1, &prefix:<-> ... *)
Run Code Online (Sandbox Code Playgroud)


bri*_*foy 5

Moritz使用的十字架很有趣(也很令人愉快),但你也可以拿一个列表的块.这与你最初尝试的很接近.我想你要走向rotor:

my $number = 1595;
say  [+] $number.comb.rotor(2, :partial).map: { $^a.[0] - ($^a.[1] // 0) }
Run Code Online (Sandbox Code Playgroud)

请注意,您的块有一个参数.这就是清单.它有点难看,因为奇数位的情况$^a.[1] Nil会产生警告.

现在我已经玩了这个,我用签名来处理它,所以我可以给出$b一个默认值.这要好得多:

my $number = 1595;
say  [+] $number
    .comb
    .rotor(2, :partial)
    .map: -> ( $a, $b = 0 ) { $a - $b }
Run Code Online (Sandbox Code Playgroud)

但是你甚至不需要它,rotor因为它map会根据需要获取尽可能多的位置参数(h/t到评论中的timotimo).这意味着你真的很亲密,只是错过了签名:

my $number = 1595;
say  [+] $number
    .comb
    .map: -> ( $a, $b = 0 ) { $a - $b }
Run Code Online (Sandbox Code Playgroud)

您在评论中使用的解决方案对于奇数个数字的情况并不适用:

say [+] $number.comb.rotor(2, :partial).map({[-] $_});
Run Code Online (Sandbox Code Playgroud)

并且,我知道这个问题并不是真的与除数有关,但我很高兴Perl 6有一个"可分"的运算符,%%:

$ perl6
> 121 %% 11
True
> 122 %% 11
False
> 1595 %% 11
True
> 1596 %% 11
False
Run Code Online (Sandbox Code Playgroud)

  • 没有必要使用`.rotor(2,:partial).map(($ a,$ b = 0) - > {})`这里,只需使用`.map( - > $ a,$ b = 0 {})`应该表现得一样. (2认同)

Sci*_*mon 3

say [+] 1595.comb >>*>> (1,-1)
Run Code Online (Sandbox Code Playgroud)

与 Z* 版本类似,但在右侧使用超元运算符循环效果(如果左侧的数字少于 2 位则没问题)。