多段階選抜 (Perl6)

多段階選抜
解答日
シリーズ:yieldの練習/ジェネレータを入れ子に/整数平方根・立方根の実装

問題
 

http://nabetani.sakura.ne.jp/hena/ord24eliseq/
https://qiita.com/Nabetani/items/1c83005a854d2c6cbb69

Ruby
2014/8/2(当日)
https://qiita.com/cielavenir/items/9f15e29b73ecf98968a5

C#/Python
2014/8/4
https://qiita.com/cielavenir/items/a1156e6a4f71ddbe5dcb

 
ここから上はdrop_prev_square/drop_prev_cubicをまとめる前の答案

Go/C#/Ruby/Python
2014/8/5
https://qiita.com/cielavenir/items/2a685d3080862f2c2c47

PHP/JavaScript
2014/9/9
https://qiita.com/cielavenir/items/28d613ac3823afbf8407

VB
2014/9/10
https://qiita.com/cielavenir/items/cb7266abd30eadd71c04

D
2015/12/21
https://qiita.com/cielavenir/items/47c9e50ee60bef2847ec

Perl
2017/3/10
https://qiita.com/cielavenir/items/6dfbff749d833c0fd423

Lua
2017/3/13
https://qiita.com/cielavenir/items/c60fe7e8da73487ba062

C++20(TS)
2017/3/15

https://qiita.com/cielavenir/items/e1129ca185008f49cbab (MSVC)
https://qiita.com/cielavenir/items/1cfa90d73d11bb7dc3d4 (clang)

F#
2017/3/17
https://qiita.com/cielavenir/items/a698d6a26824ff53de81

Boo/Nemerle
2017/5/13
https://qiita.com/cielavenir/items/e2a783f0fe4b0fe0ed48

Perl6
2017/5/15
https://qiita.com/cielavenir/items/656ea17fa96c865c4498

Kotlin
2017/5/25
https://qiita.com/cielavenir/items/9c46ce8d9d12e51de285

Crystal
2018/5/8
https://qiita.com/cielavenir/items/1815bfa6a860fd1f90db

MoonScript
2018/6/16
https://qiita.com/cielavenir/items/8b03cce0386f4537b5ad

Julia/Rust
2018/12/20
https://qiita.com/cielavenir/items/3ddf72b06d625da0c4a5

Nim
2018/12/26
https://qiita.com/cielavenir/items/5728944867e609fd52a7

Tcl
2018/12/31
https://qiita.com/cielavenir/items/76cbd9c2022b48c9a2c9

Pascal/Cobra
2019/1/16
https://qiita.com/cielavenir/items/81b81baf8dfc1f877903

Icon
2019/1/17
https://qiita.com/cielavenir/items/889622dcc721f5a4da24

(icbrtの実装に関する)補題
2017/5/11
整数除算であってもn/(x*y)はn/x/yに等しい(ことの証明)
https://qiita.com/cielavenir/items/21a6711afd6be8c18c55

15言語到達。

てかいままでジェネレータの作り方把握してなかったのは主として名前のせいだと思う…

Perl(Generator::Object)はgenerator$_->yield($val)

Perl6はgathertake $val

これはわからんでしょ…

http://ryota-ka.hatenablog.com/entry/2015/12/30/000000

に感謝。

(JavaやRustやSwiftはyieldがないので当面対象外なのです)

#!/usr/bin/env perl6

#http://qiita.com/Nabetani/items/1c83005a854d2c6cbb69
#http://nabetani.sakura.ne.jp/hena/ord24eliseq/

sub isqrt($n){
if $n <= 0 {return 0;}
if $n < 4 {return 1;}
my $x=0;my $y=$n;
loop (;$x != $y && $x+1 != $y;) {$x=$y;$y=(($n div $y)+$y) div 2;}
return $x;
}

sub icbrt($n){
if $n < 0 {return icbrt(-$n);}
if $n == 0 {return 0;}
if $n < 8 {return 1;}
my $x=0;my $y=$n;
loop (;$x != $y && $x+1 != $y;) {$x=$y;$y=(($n div $y div $y)+$y*2) div 3;}
return $x;
}

sub generate{
return lazy gather {
my $i=1;
loop (;;) {
take $i;
$i++;
}
}
}

sub drop_prev($check,@prev){
return lazy gather {
my $a=@prev[0];
my $b=@prev[1];
my $i=2;
loop (;;) {
take $a if !$check($b);
$a=$b;
$b=@prev[$i];
$i++;
}
}
}
sub drop_next($check,@prev){
return lazy gather {
my $a=@prev[0];
my $b=@prev[1];
my $i=2;
take $a;
loop (;;) {
take $b if !$check($a);
$a=$b;
$b=@prev[$i];
$i++;
}
}
}
sub drop_n($check,$n,@prev){
return lazy gather {
my $i=0;
loop (;;) {
my $a=@prev[$i];
$i+=1;
take $a if !$check($i,$n);
}
}
}
sub is_sq($n){
#my $x=int(sqrt($n));
my $x=isqrt($n);
return $x*$x == $n;
}
sub is_cb($n){
#my $x=int(cbrt($n));
my $x=icbrt($n);
return $x*$x*$x == $n;
}
sub is_multiple($i,$n){
return $i%$n == 0;
}
sub is_le($i,$n){
return $i <= $n;
}

my %f=(
'S'=>sub (@enum) {return drop_next(&is_sq,@enum);},
's'=>sub (@enum) {return drop_prev(&is_sq,@enum);},
'C'=>sub (@enum) {return drop_next(&is_cb,@enum);},
'c'=>sub (@enum) {return drop_prev(&is_cb,@enum);},
'h'=>sub (@enum) {return drop_n(&is_le,100,@enum);},
);
loop (my $i=2;$i <= 9;$i++) {%f{"$i"}=sub ($i) {sub (@enum) {return drop_n(&is_multiple,$i,@enum);}}($i);}

loop (;my $line=get();) {
chomp($line);
#cS => $f['S']->($f['c']->(generate()))
my @z=reduce {%f{$^b}($^a)},generate(),|$line.split("",:skip-empty);
my $cnt=10;
my @a;
loop (my $i=0;$i < $cnt;$i++) {
push(@a,shift(@z));
}
say join(',',@a);
$*OUT.flush();
}