Version 5 of Random worklist generator

Updated 2008-09-18 06:56:53 by Googie

TV

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 $ret
 }

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