Tcl
どう書く
yhpg

多段階選抜 (Tcl)

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


tyama_hena24_enum.tcl

#!/usr/bin/env tclsh

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

### tclsh >= 8.6 ###

proc isqrt {n} {
if {$n<=0} {return 0}
if {$n<4} {return 1}
set x 0
set y $n
while {$x!=$y&&$x+1!=$y} {
set x $y
set y [expr ($n/$y+$y)/2]
}
return $x
}

proc icbrt {n} {
if {$n<0} {return [icbrt -$n]}
if {$n==0} {return 0}
if {$n<8} {return 1}
set x 0
set y $n
while {$x!=$y&&$x+1!=$y} {
set x $y
set y [expr ($n/$y/$y+$y*2)/3]
}
return $x
}

proc generate {g} {
proc func {} {
yield [info coroutine]
set i 1
while {true} {
yield $i
incr i
}
}
coroutine $g func
}

proc drop_prev {g check prev} {
proc func {check prev} {
yield [info coroutine]
set a [$prev]
set b [$prev]
while {true} {
if {![$check $b]} {yield $a}
set a $b
set b [$prev]
}
}
coroutine $g func $check $prev
}

proc drop_next {g check prev} {
proc func {check prev} {
yield [info coroutine]
set a [$prev]
set b [$prev]
yield $a
while {true} {
if {![$check $a]} {yield $b}
set a $b
set b [$prev]
}
}
coroutine $g func $check $prev
}

proc drop_n {g check n prev} {
proc func {check n prev} {
yield [info coroutine]
set i 0
while {true} {
incr i
set a [$prev]
if {![$check $i $n]} {yield $a}
}
}
coroutine $g func $check $n $prev
}

proc is_sq {n} {
set x [isqrt $n]
return [expr $x*$x==$n]
}

proc is_cb {n} {
set x [icbrt $n]
return [expr $x*$x*$x==$n]
}

proc is_multiple {i n} {return [expr $i%$n==0]}
proc is_le {i n} {return [expr $i<=$n]}

array set f {
"S" {{g prev} {drop_next $g is_sq $prev}}
"s" {{g prev} {drop_prev $g is_sq $prev}}
"C" {{g prev} {drop_next $g is_cb $prev}}
"c" {{g prev} {drop_prev $g is_cb $prev}}
"h" {{g prev} {drop_n $g is_le 100 $prev}}
"2" {{g prev} {drop_n $g is_multiple 2 $prev}}
"3" {{g prev} {drop_n $g is_multiple 3 $prev}}
"4" {{g prev} {drop_n $g is_multiple 4 $prev}}
"5" {{g prev} {drop_n $g is_multiple 5 $prev}}
"6" {{g prev} {drop_n $g is_multiple 6 $prev}}
"7" {{g prev} {drop_n $g is_multiple 7 $prev}}
"8" {{g prev} {drop_n $g is_multiple 8 $prev}}
"9" {{g prev} {drop_n $g is_multiple 9 $prev}}
}
#2..9: Tcl does not have capturing.

set s [gets stdin]
while {$s!=""} {
set lst [list hena24]
generate [lindex $lst 0]
for {set i 0} {$i < [string length $s]} {incr i} {
set x [string index $s $i]
lappend lst [lindex $lst $i]$x
apply $f($x) [lindex $lst [expr $i+1]] [lindex $lst $i]
}
for {set j 0} {$j < 10} {incr j} {
if {$j>0} {
puts -nonewline ","
}
puts -nonewline [[lindex $lst $i]]
}
puts ""
flush stdout
set s [gets stdin]
}