多段階選抜 (V)


|多段階選抜|解答日|シリーズ: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|

30言語到達(**全て無限リストです**)。

ずっとウォッチしてました(正直疲れた)が、https://github.com/vlang/v/commit/863cf8af60e37c6145f64aa48419fd43c2b3f95d でようやくChannelが実装されたようです。ようやく解くことができました(closureかchannelが必須なので)。

5月にコルーチン実装するという話はどこへ行ったんですかね？^^;;;

vlang eab0974e7d55b95328a969e85cf41cbb9b26cf71 で動作確認。互換性崩れる可能性はありそう〜
(でもZigよりはまし…)

あと、無名関数が今は使えないようだけど後で使えるようになりますよね…？

```v
//usr/bin/env v run $0 $@;exit

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

fn isqrt(n int) int{
	if n<=0 {return 0}
	if n<4 {return 1}
	mut x:=0
	mut y:=n
	for x!=y && x+1!=y {x=y y=(n/y+y)/2}
	return x
}
fn icbrt(n int) int{
	if n<0 {return -icbrt(-n)}
	if n==0 {return 0}
	if n<8 {return 1}
	mut x:=0
	mut y:=n
	for x!=y && x+1!=y {x=y y=(n/y/y+y*2)/3}
	return x
}

fn is_sq(n int) bool{
	x:=isqrt(n)
	return x*x==n
}
fn is_cb(n int) bool{
	x:=icbrt(n)
	return x*x*x==n
}
fn is_multiple(i int,n int) bool{ return i%n==0 }
fn is_le(i int,n int) bool{ return i<=n }

fn generate_impl(ch chan int){
	mut i:=1
	for {
		ch <- i
		i++
	}
}

fn generate() chan int{
	ch := chan int{}
	go generate_impl(ch)
	return ch
}

fn drop_prev_impl(check fn(int)bool,prev chan int,ch chan int){
	mut a:=<-prev
	mut b:=<-prev
	for {
		if !check(b) { ch<-a }
		a=b
		b=<-prev
	}
}

fn drop_prev(check fn(int)bool,prev chan int) chan int{
	ch := chan int{}
	go drop_prev_impl(check,prev,ch)
	return ch
}

fn drop_next_impl(check fn(int)bool,prev chan int,ch chan int){
	mut a:=<-prev
	mut b:=<-prev
	ch<-a
	for {
		if !check(a) { ch<-b }
		a=b
		b=<-prev
	}
}
	
fn drop_next(check fn(int)bool,prev chan int) chan int{
	ch := chan int{}
	go drop_next_impl(check,prev,ch)
	return ch
}

fn drop_n_impl(check fn(int,int)bool,n int,prev chan int,ch chan int){
	mut i:=0
	for {
		i++
		a:=<-prev
		if !check(i,n) { ch<-a }
	}
}

fn drop_n(check fn(int,int)bool,n int,prev chan int) chan int{
	ch := chan int{}
	go drop_n_impl(check,n,prev,ch)
	return ch
}

fn f_capital_s(prev chan int)chan int{return drop_next(is_sq,prev)}
fn f_small_s(prev chan int)chan int{return drop_prev(is_sq,prev)}
fn f_capital_c(prev chan int)chan int{return drop_next(is_cb,prev)}
fn f_small_c(prev chan int)chan int{return drop_prev(is_cb,prev)}
fn f_small_h(prev chan int)chan int{return drop_n(is_le,100,prev)}
fn f_2(prev chan int)chan int{return drop_n(is_multiple,2,prev)}
fn f_3(prev chan int)chan int{return drop_n(is_multiple,3,prev)}
fn f_4(prev chan int)chan int{return drop_n(is_multiple,4,prev)}
fn f_5(prev chan int)chan int{return drop_n(is_multiple,5,prev)}
fn f_6(prev chan int)chan int{return drop_n(is_multiple,6,prev)}
fn f_7(prev chan int)chan int{return drop_n(is_multiple,7,prev)}
fn f_8(prev chan int)chan int{return drop_n(is_multiple,8,prev)}
fn f_9(prev chan int)chan int{return drop_n(is_multiple,9,prev)}

fn main(){
	mut f:=map[string]fn(_ chan int)chan int{}
	f['S']=f_capital_s
	f['s']=f_small_s
	f['C']=f_capital_c
	f['c']=f_small_c
	f['h']=f_small_h
	f['2']=f_2
	f['3']=f_3
	f['4']=f_4
	f['5']=f_5
	f['6']=f_6
	f['7']=f_7
	f['8']=f_8
	f['9']=f_9

	//this anonymous function somehow causes C error.
	//f['S']=fn(prev chan int)chan int{return drop_next(is_sq,prev)}
/*
	f['s']=fn(prev chan int)chan int{return drop_prev(is_sq,prev)}
	f['C']=fn(prev chan int)chan int{return drop_next(is_cb,prev)}
	f['c']=fn(prev chan int)chan int{return drop_prev(is_cb,prev)}
	f['h']=fn(prev chan int)chan int{return drop_n(is_le,100,prev)}

	for i:=2;i<10;i++ {
		j:=i
		f[j.str()]=fn(prev chan int)chan int{return drop_n(is_multiple,j.int(),prev)}
	}
*/

	mut line:=get_line()
	for line!="" {
		//cS => f['S'](f['c'](generate()))
		mut ch := generate()
		for c in line {
			//somehow I need to assign first or the source will not compile.
			z:=f[c.str()]
			ch=z(ch)
		}
		for i:=0;i<10;i++ {
			if i>0 { print(',') }
			print(<-ch)
		}
		println('')
		flush()
		line=get_line()
	}
}
```