多段階選抜 (Boo/Nemerle)

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


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();
}
}
}