-
Notifications
You must be signed in to change notification settings - Fork 0
/
func.tcl
81 lines (65 loc) · 1.67 KB
/
func.tcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
proc I { x } { set x }
proc K { x y } { set x }
proc + { x y } { expr $x + $y }
proc * { x y } { expr $x * $y }
proc sum { lst } { foldl + 0 $lst }
proc sqr { x } { expr $x * $x }
proc max { x y } { expr $x > $y ? $x : $y }
proc iota { fr { to {} } { in 1 } } {
if { $to eq {} } {
set to $fr
set fr 0
}
set fr [expr $fr]
set to [expr $to]
for { set res {} } { $fr <= $to } { incr fr $in } {lappend res $fr }
set res
}
proc map { args } {
uplevel [subst {
set _[info frame] {}
foreach {*}[list [lrange $args 0 end-1]] { lappend _[info frame] \[[lindex $args end]] }
set _[info frame]
}]
}
proc pick { func list } {
set ret [list]
foreach item $list {
if {[eval $func [list $item]]} {
lappend ret $item
}
}
return $ret
}
proc foldl {func res list} {
foreach item $list { set res [eval $func [list $res $item]] }
set res
}
proc foldr {func res list} {
for {set i [llength $list]} {$i > 0} {incr i -1} {
set res [eval $func [list [lindex $list [expr {$i-1}]] $res]]
}
set res
}
proc lremove { list value } {
set indx [lsearch $list $value]
lreplace $list $indx $indx
}
proc shuffle list { # http://wiki.tcl.tk/941 shuffle10a
set len [llength $list]
while {$len} {
set n [expr {int($len*rand())}]
set tmp [lindex $list $n]
lset list $n [lindex $list [incr len -1]]
lset list $len $tmp
}
return $list
}
proc memo { proc } {
rename $proc _$proc
proc $proc { args } [subst -nocommands {
if { [info exists ::_${proc}(\$args)] } { return [set ::_${proc}(\$args)] }
set ::_${proc}(\$args) [_${proc} {*}\$args]
}]
}
memo iota