Edited at

多段階選抜 (VB)

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


VB

うまくテストできなかったので、WinでコンパイルしたexeをOSXに転送してテストした。

なので細かい部分が怪しいですが、気にしない。

ちなみにWinで直接実行した限りでは、DllImportは msvcr120 にしないといけなかった。びっくり。


hena24_enum.vb

' http://qiita.com/Nabetani/items/1c83005a854d2c6cbb69

' http://nabetani.sakura.ne.jp/hena/ord24eliseq/

imports System
imports System.Linq
imports System.Collections.Generic
'imports System.Runtime.InteropServices

module Hena24
'<DllImport("c")>
'private function cbrt(ByVal d as double) as double
'end function

private function isqrt(ByVal n as integer) as integer
if n<=0
return 0
end if
if n<4
return 1
end if
dim x as integer=0
dim y as integer=n
while x<>y andalso x+1<>y
x=y
y=((n\y)+y)\2
end while
return x
end function
private function icbrt(ByVal n as integer) as integer
if n<0
return icbrt(-n)
end if
if n=0
return 0
end if
if n<8
return 1
end if
dim x as integer=0
dim y as integer=n
while x<>y andalso x+1<>y
x=y
y=((n\y\y)+y*2)\3
end while
return x
end function

private function is_sq(ByVal n as integer) as boolean
dim x as integer=isqrt(n)
'cint(Math.Sqrt(n))
return x*x=n
end function

private function is_cb(ByVal n as integer) as boolean
dim x as integer=icbrt(n)
'cint(cbrt(n))
return x*x*x=n
end function

private function is_multiple(ByVal i as integer,ByVal n as integer) as boolean
return i mod n=0
end function
private function is_le(ByVal i as integer,ByVal n as integer) as boolean
return i<=n
end function

iterator function generate() as IEnumerable(of integer)
dim i as integer=1
while true
yield i
i+=1
end while
end function

iterator function drop_prev(ByVal check as Func(of integer,boolean),ByVal _prev as IEnumerable(of integer)) as IEnumerable(of integer)
dim prev as IEnumerator(of integer)=_prev.GetEnumerator()
prev.MoveNext()
dim a as integer=prev.Current
prev.MoveNext()
dim b as integer=prev.Current
while true
if not check(b)
yield a
end if
a=b
prev.MoveNext()
b=prev.Current
end while
end function

iterator function drop_next(ByVal check as Func(of integer,boolean),ByVal _prev as IEnumerable(of integer)) as IEnumerable(of integer)
dim prev as IEnumerator(of integer)=_prev.GetEnumerator()
prev.MoveNext()
dim a as integer=prev.Current
prev.MoveNext()
dim b as integer=prev.Current
yield a
while true
if not check(a)
yield b
end if
a=b
prev.MoveNext()
b=prev.Current
end while
end function

iterator function drop_n(ByVal check as Func(of integer,integer,boolean),ByVal n as integer,ByVal _prev as IEnumerable(of integer)) as IEnumerable(of integer)
dim prev as IEnumerator(of integer)=_prev.GetEnumerator()
dim i as integer=0
while true
i+=1
prev.MoveNext()
dim a as integer=prev.Current
if not check(i,n)
yield a
end if
end while
end function

sub Main()
dim f as new Dictionary(of char,Func(of IEnumerable(of integer),IEnumerable(of integer))) from {
{"S"c,Function(e) drop_next(addressof is_sq,e)},
{"s"c,Function(e) drop_prev(addressof is_sq,e)},
{"C"c,Function(e) drop_next(addressof is_cb,e)},
{"c"c,Function(e) drop_prev(addressof is_cb,e)},
{"h"c,Function(e) drop_n(addressof is_le,100,e)}
}
for i as integer=2 to 9
dim j as integer=i
f(chr(48+j)) = Function(e) drop_n(addressof is_multiple,j,e)
next
dim line as string=Console.ReadLine()
while line isnot nothing
dim first as boolean=true
'cS => f("S"c)(f("c"c)(generate()))
for each n as integer in line.Aggregate(generate(),Function(s,e) f(e)(s)).Take(10)
if not first
Console.Write(","c)
end if
first=false
Console.Write(n)
next
Console.WriteLine()
Console.Out.Flush()
line=Console.ReadLine()
end while
end sub
end module