多段階選抜 (Boo/Nemerle)


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

## Boo

処理系 https://github.com/boo-lang/boo/releases

```
#!/usr/bin/env booi
#http://qiita.com/Nabetani/items/1c83005a854d2c6cbb69
#http://nabetani.sakura.ne.jp/hena/ord24eliseq/
import System
import System.Linq.Enumerable
import System.Collections.Generic

def isqrt(n as int) as int:
	if n<=0: return 0
	if n<4: return 1
	x,y=0,n
	while x!=y and x+1!=y:
		x,y=y,(n/y+y) / 2
	return x
def icbrt(n as int) as int:
	if n<0: return -icbrt(-n)
	if n==0: return 0
	if n<8: return 1
	x,y=0,n
	while x!=y and x+1!=y:
		x,y=y,(n/y / y+y*2) / 3
	return x

def generate() as IEnumerable[of int]:
	i=1
	while true:
		yield i
		i+=1

def drop_prev(check as Func[of int,bool],_prev as IEnumerable[of int]) as IEnumerable[of int]:
	prev=_prev.GetEnumerator()
	prev.MoveNext()
	a=prev.Current
	prev.MoveNext()
	b=prev.Current
	while true:
		if not check(b): yield a
		prev.MoveNext()
		a,b=b,prev.Current

def drop_next(check as Func[of int,bool],_prev as IEnumerable[of int]) as IEnumerable[of int]:
	prev=_prev.GetEnumerator()
	prev.MoveNext()
	a=prev.Current
	prev.MoveNext()
	b=prev.Current
	yield a
	while true:
		if not check(a): yield b
		prev.MoveNext()
		a,b=b,prev.Current

def drop_n(check as Func[of int,int,bool],n as int,_prev as IEnumerable[of int]) as IEnumerable[of int]:
	prev=_prev.GetEnumerator()
	i=0
	while true:
		i+=1
		prev.MoveNext()
		a=prev.Current
		if not check(i,n): yield a

is_sq={n as int|(x=isqrt(n))*x==n}
is_cb={n as int|(x=icbrt(n))*x*x==n}
is_multiple={i as int,n as int|i%n==0}
is_le={i as int,n as int|i<=n}

f=Dictionary[of char,Func[of IEnumerable[of int],IEnumerable[of int]]]()
f[char('S')]={x|drop_next(is_sq,x)}
f[char('s')]={x|drop_prev(is_sq,x)}
f[char('C')]={x|drop_next(is_cb,x)}
f[char('c')]={x|drop_prev(is_cb,x)}
f[char('h')]={x|drop_n(is_le,100,x)}

for e in range(2,10):f[48+e]={x|{n|drop_n(is_multiple,x,n)}}(e)

while true:
	line=Console.ReadLine()
	if line==null: break
	first=true
	#cS => f['S'](f['c'](generate()))
	for n in line.Aggregate(generate(),{s,e|f[e](s)}).Take(10):
		if not first: Console.Write(',')
		first=false
		Console.Write(n)
	Console.WriteLine()
	Console.Out.Flush()
```

## Nemerle

- Monoのバージョンとの食い合わせがひどいっぽいです
- nccの出力が **out.exe** になるので注意(mcs/boocと違うので割とはまった)

処理系 http://nemerle.org/Downloads
v1.1.1119.0 Binaries for .NET 4.0 (.zip) で確認しました。v1.2ではコンパイラの内部エラーで動きませんでした。

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

using System;
using System.Linq;
using System.Collections.Generic;
module hena24{
	isqrt(n:int):int{
		if(n<=0)0;
		else if(n<4)1;
		else{
			mutable x,y:int;
			x=0;y=n;
			while(x!=y&&x+1!=y){x=y;y=(n/y+y)/2;}
			x;
		}
	}
	icbrt(n:int):int{
		if(n<0)-icbrt(-n);
		else if(n==0)0;
		else if(n<8)1;
		else{
			mutable x,y:int;
			x=0;y=n;
			for(;x!=y&&x+1!=y;){x=y;y=(n/y/y+y*2)/3;}
			x;
		}
	}
	is_sq(n:int):bool{
		def x=isqrt(n);
		x*x==n;
	}
	is_cb(n:int):bool{
		def x=icbrt(n);
		x*x*x==n;
	}
	is_multiple(i:int,n:int):bool{i%n==0;}
	is_le(i:int,n:int):bool{i<=n;}

	generate():IEnumerable.[int]{
		mutable i:int;
		i=1;
		for(;;){
			yield i;
			i+=1;
		}
	}
	drop_prev(check:Func.[int,bool],_prev:IEnumerable.[int]):IEnumerable.[int]{
		def prev=_prev.GetEnumerator();
		_=prev.MoveNext();
		mutable a,b:int;
		a=prev.Current;
		_=prev.MoveNext();
		b=prev.Current;
		for(;;){
			when(!check(b))yield a;
			a=b;
			_=prev.MoveNext();
			b=prev.Current;
		}
	}
	drop_next(check:Func.[int,bool],_prev:IEnumerable[int]):IEnumerable.[int]{
		def prev=_prev.GetEnumerator();
		_=prev.MoveNext();
		mutable a,b:int;
		a=prev.Current;
		_=prev.MoveNext();
		b=prev.Current;
		yield a;
		for(;;){
			when(!check(a))yield b;
			a=b;
			_=prev.MoveNext();
			b=prev.Current;
		}
	}
	drop_n(check:Func.[int,int,bool],n:int,_prev:IEnumerable.[int]):IEnumerable.[int]{
		def prev=_prev.GetEnumerator();
		mutable i,a:int;
		i=0;
		for(;;){
			i++;
			_=prev.MoveNext();
			a=prev.Current;
			when(!check(i,n))yield a;
		}
	}
	Main():void{
		def f=Dictionary.[char,Func.[IEnumerable.[int],IEnumerable.[int]]]();
		f['S']=e => drop_next(is_sq,e);
		f['s']=e => drop_prev(is_sq,e);
		f['C']=e => drop_next(is_cb,e);
		f['c']=e => drop_prev(is_cb,e);
		f['h']=e => drop_n(is_le,100,e);
		for(mutable i=2;i<10;i++){
			def j=i; //寿命が短いスコープを作ることで、ラムダ式のキャプチャでバグらないようにする。
			f[('0'+j) :> char] = e=>drop_n(is_multiple,j,e);
		}
		mutable line:string;
		line=Console.ReadLine();
		for(;line!=null;){
			mutable first=true;
			//cS => f['S'](f['c'](generate()))
			foreach(n:int in line.Aggregate(generate(),(s,e)=>f[e](s)).Take(10)){
				when(!first)Console.Write(',');
				first=false;
				Console.Write(n);
			}
			Console.WriteLine();
			Console.Out.Flush();
			line=Console.ReadLine();
		}
	}
}
```