Do make sure certain chores get no prevalence over other chores, association-wise, I made a little worklist randomizer.
Lets say I have a number of chores in a list:
set w { {washing up} {cut the grass} {shave (very important!)} {watch CNN} {finish some Tcl programs} {work in computer field} {buy tickets in a lottery} {go voting (even more important!)} {etc (whatever else comes up)} }
Now we want a random iten from the list, or a random permutation of the list, with no priorities:
lindex $w [expr int(9*rand())]
Of course we could do the same with the rest of the list.
Googie 17.09.2008 - I'd upgrade method of retrieving random entry:
lindex $w [expr { int([llength $w]*rand()) }]
But there is still missing solution for removing from list jobs that are already done. So we need a procedure for that:
proc lremove {varName idx} { upvar $varName lst set val [lindex $lst $idx] set lst [lreplace $lst $idx $idx] return $val }
and finally:
lremove w [expr { int([llength $w]*rand()) }]
TV I had made this:
proc randout l { set i [expr int([llength $l]*rand())] ; return [list [lindex $l $i] [lrange $l 0 [expr $i-1] ] [lrange $l [expr $i+1] end ]] }
This is a list shuffler which can be made recursive, but it escaped me how to make a flat combined list...
( Example: (Tcl) 62 % randout $w
{go voting (even more important!)} {{washing up} {cut the grass} {shave (very important!)} {watch CNN} {finish some Tcl programs} {work in computer field} {buy tickets in a lottery}} {{etc (whatever else comes up)}}
)
Of course I know how to do that:
proc randout l { set i [expr int([llength $l]*rand())] ; return "[lindex $l $i] [lrange $l 0 [expr $i-1] ] [lrange $l [expr $i+1] end]" }
And then make that recursive for fun. But no:
Tcl) 106 % list a b c a b c (Tcl) 107 % list a {b c} a {b c} (Tcl) 108 % list [list a {b c}] {a {b c}} (Tcl) 109 % list [list a b c] {a b c} (Tcl) 110 % list {v} v (Tcl) 111 % list {v} b v b
That *is* neatly solvable, but for the same reasdon I felt bwise being bogged down, this type of system-correct list processing just doesn't stick with my consciousness easily enough. Maybe later.
Googie 18.09.2008 - To make a flat of:
proc randout l { set i [expr int([llength $l]*rand())] ; return [list [lindex $l $i] [lrange $l 0 [expr $i-1] ] [lrange $l [expr $i+1] end ]] }
use just concat command:
proc randout l { set i [expr int([llength $l]*rand())] ; return [concat [list [lindex $l $i]] [lrange $l 0 [expr $i-1] ] [lrange $l [expr $i+1] end ]] }
I put lindex $l $i into a single list, because concat would understeand it as a separate list - if it was a correct Tcl list - and join it to other lists. Anyway, I'd do that like this:
proc randout l { set i [expr int([llength $l]*rand())] ; set ret [lindex $l $i] set l [linsert [lreplace $l $i $i] 0 $ret] return $l }
I think it's easier to read it and I think it's faster, since there is no additional calls to expr. NOTE: use brackets to enclose expresions in expr, like this:
expr {$i+1}
or
expr {$i + 1}
It makes them working faster.
enter categories here |
---|