->\k{?first ->(\i,\j){k==i*i+j*j+i*j},(0..k X 0..k)}
->\k{?grep ->(\i,\j){k==i*i+j*j+i*j},(0..k X 0..k)}
{?grep ->(\i,\j){$_==i*i+j*j+i*j},(0..$_ X 0..$_)}
说明:
{
# Turn the following into a Bool
# ( Technically not necessary as a list of 1 or more values is truthy )
?
# find all where the code block returns a truthy value
grep
# pointy block that takes one value (list of 2 values)
# and gives each of the values in it a name
->
$ ( \i, \j )
{
# return true if the definition matches
$_ == i*i + j*j + i*j
},
# a list of 2 element lists (possible i and j values)
( 0..$_ X 0..$_ )
}
测试:
use v6.c;
use Test;
my @true = 0, 1, 4, 7, 12, 13, 108, 109, 192, 516, 999;
my @false = 2, 5, 10, 42, 101, 102, 128, 150, 501, 1000;
plan (@true + @false) * 2;
my &is-loeschian = {?grep ->(\i,\j){$_==i*i+j*j+i*j},(0..$_ X 0..$_)}
for |(@true X True), |(@false X False) -> ( $input, $expected ) {
my ($result,$seconds) = $input.&time-it;
is $result, $expected, ~$input;
cmp-ok $seconds, &[<], 60, "in $seconds seconds"
}
sub time-it ( $input ) {
my $start = now;
my $result = $input.&is-loeschian;
my $finish = now;
return ( $result, $finish - $start )
}
1..42
ok 1 - 0
ok 2 - in 0.00111763 seconds
ok 3 - 1
ok 4 - in 0.00076766 seconds
...
ok 19 - 516
ok 20 - in 0.19629727 seconds
ok 21 - 999
ok 22 - in 0.1126715 seconds
ok 23 - 2
ok 24 - in 0.0013301 seconds
ok 25 - 5
ok 26 - in 0.00186610 seconds
...
ok 37 - 150
ok 38 - in 0.83877554 seconds
ok 39 - 501
ok 40 - in 9.2968558 seconds
ok 41 - 1000
ok 42 - in 37.31434146 seconds