多段階選抜 (Perl6)


|多段階選抜|解答日|シリーズ:yieldの練習/ジェネレータを入れ子に/整数平方根・立方根の実装|
|:--|:--|:--|
|問題|　|http://nabetani.sakura.ne.jp/hena/ord24eliseq/<br>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)<br>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|
|Swift|2020/5/31|https://qiita.com/cielavenir/items/3b0b84a218e35d538f7f|
|Java/Groovy/Scala|2020/5/31|https://qiita.com/cielavenir/items/7f058203a8fd03b65870|
|V|2020/10/17|https://qiita.com/cielavenir/items/df30a6c101a97a713df5|
|Zig/Zen|2020/10/17|https://qiita.com/cielavenir/items/9cced9e4a94dcd70df0f|
|Pike|2020/11/2|https://qiita.com/cielavenir/items/3a8248f41611302b34fd|
|Vala/Smalltalk|2020/11/29|https://qiita.com/cielavenir/items/085dabe593cd916af5e8|
|Objective-C|2020/11/30|https://qiita.com/cielavenir/items/a1736e38789a3dd5cc5a|
|Ruby(Ractor)|2021/1/2|https://qiita.com/cielavenir/items/f493c6d512b63cc571cc|
|Python(_xxsubinterpreters)|2021/6/29|https://qiita.com/cielavenir/items/f1f581a055db918954f1|
|Falcon/Scheme|2021/9/5|https://qiita.com/cielavenir/items/c13d12cf44f0d17f4a94|
|Clojure/Lisp|2021/9/7|https://qiita.com/cielavenir/items/7458ba076f4e5bc0f196|
|(icbrtの実装に関する)補題|2017/5/11|整数除算であってもn/(x*y)はn/x/yに等しい(ことの証明)<br>https://qiita.com/cielavenir/items/21a6711afd6be8c18c55|

15言語到達。

てかいままでジェネレータの作り方把握してなかったのは主として名前のせいだと思う…
Perl(Generator::Object)は`generator`と`$_->yield($val)`。
Perl6は`gather`と`take $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();
}
```