100までの素数 Perl6 / pugs 版

Perl6 (pugs) で動くようにしてみた。

#!/usr/bin/pugs
my $max = @*ARGS.pop || 100;
my @primes = (2);

for (3..$max) -> $n {
    @primes.push($n)
        if @primes.before_incl:{ sqrt $n <= $_ }.all:{ $n % $_ };
}
@primes.join(' ').say;

sub all (@list, $test){
    return if @list.elems == 0;
    for (@list) -> $_ {
        return unless $test($_);
    }
    return 1;
}

sub before_incl (@list, $test) {
    my $keepgoing = 1;
    my $lag       = 1;
    @list.grep:{ $keepgoing &&= do { my $x = $lag; $lag = !$test($_); $x } };
}

all, before_incl の実装は、List::MoreUtils のソースコードから頂いてきた。
perl5 用の List::MoreUtils を "use perl5:List::MoreUtils <all before_incl>;" で動かせるかな、と思って試してみたのが、実行時に Segmentation fault で落ちる。

しかし実行速度は遅いですな…

$ time pugs primes.p6
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

real    0m11.669s
user    0m11.605s
sys     0m0.056s

100 までで 11秒 (Fedora Core 5 / Pugs 6.2.12 / Opteron 2.0GHz)。しかも不思議なことに、before_incl で絞り込まないほうが速い。

$ time pugs primes.p6
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

real    0m4.746s
user    0m3.384s
sys     0m0.060s