Advertisement
Guest User

dogs.tcl

a guest
Oct 16th, 2014
15
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
TCL 5.99 KB | None | 0 0
  1.  
  2.  
  3. set dogNames {Abby Angel Annie Bailey Bailey Bandit Baxter Bear Beau Bella Belle Bentley Boomer \
  4. Brandy Bruno Buddy Buster Casey Casey Charlie Chloe Coco Cody Cooper Daisy Dakota Dakota Dixie \
  5. Duke Emma Ginger Gizmo Gracie Gus Harley Heidi Henry Holly Honey Hunter Jack Jackson Jake Jasmine \
  6. Joey Katie Lady Lexi Lilly Lily Lola Louie Lucky Lucy Luke Lulu Luna Madison Maggie Max Maximus \
  7. Mia Milo Missy Molly Murphy Oliver Oscar Penny Pepper Princess Riley Rocco Rocky Romeo Rosie Roxie \
  8. Roxy Ruby Rudy Rusty Sadie Sam Samantha Sammy Samson Sandy Sasha Shadow Shelby Sophie Sparky Stella \
  9. Teddy Toby Tucker Winston Zeus Zoe Zoey}
  10.  
  11. proc sortDogs {dogs} {
  12.     set pop [llength $dogs]
  13.     # first split the dogs into groups of 5 and race them
  14.     # then take the winners of each group and race them
  15.     # and so on until we know the fastest dog
  16.  
  17.     puts "#-------------STAGE 1----------------#"
  18.     puts "#----------RACE ALL DOGS-------------#"
  19.  
  20.     set topDog [rankDogs $dogs]
  21.  
  22.     puts ""
  23.     puts "Top Dog: [dogString $topDog]"
  24.     puts "#------------------------------------#"
  25.  
  26.     # the dogs are now roughly sorted in a tree structure
  27.     # we need to "zip" the tree together into a single thread
  28.     # that represents the order of the dogs
  29.  
  30.     puts "#---------------STAGE 2--------------#"
  31.     puts "#--------SORT THESE BITCHES----------#"
  32.  
  33.     set fastestDog $topDog
  34.     set sortedDogs {}
  35.     while 1 {
  36.  
  37.         puts ""
  38.         puts "Determining dogs to race..."
  39.         # find the next 5 dogs and race them
  40.         set dogsToRace [dogsToRace $fastestDog]
  41.         puts "dogs found. They are:"
  42.         foreach dog $dogsToRace {
  43.             set slowerDogs {}
  44.             foreach slowerDog $rank($dog) {lappend slowerDogs [dogString $slowerDog]}
  45.             switch -- $slowerThan($dog) {
  46.             0 {
  47.                 puts "[dogString $dog] is not known to be faster than any other dogs"
  48.             }
  49.             1 {
  50.                 puts "[dogString $dog] is faster than [lindex $slowerDogs 0]"
  51.             }
  52.             default {
  53.                 puts "[dogString $dog] is faster than [join $slowerDogs ", "] and [expr {$slowerThan($dog)-1}] other dogs"
  54.             }
  55.             }
  56.         }
  57.  
  58.         set dogs [race5Dogs $dogsToRace]
  59.  
  60.         set lastDog $fastestDog
  61.         foreach dog $dogs {
  62.             set newRank {}
  63.             foreach slowerDog $rank($lastDog) {
  64.                 if {[lsearch $dogs $slowerDog]<0} {
  65.                     lappend newRank $slowerDog
  66.                 }
  67.             }
  68.             lappend newRank $dog
  69.             set rank($lastDog) $newRank
  70.  
  71.             set lastDog $dog
  72.         }
  73.  
  74.         while {[llength $rank($fastestDog)]==1} {
  75.             lappend sortedDogs $fastestDog
  76.             set fastestDog [lindex $rank($fastestDog) 0]
  77.             if {$rank($fastestDog)=={}} {
  78.                 lappend sortedDogs $fastestDog
  79.                 puts "took $::raceCount races"
  80.                 foreach dog $sortedDogs {puts "[incr i]. [dogString $dog]"}
  81.                 return $sortedDogs
  82.             }
  83.         }
  84.  
  85.         # recalculate slowerThan
  86.         foreach dog [lreverse [lrange $dogs 0 end-1]] {
  87.             set slowerThan($dog) 0
  88.             foreach slowerDog $rank($dog) {
  89.                 incr slowerThan($dog)
  90.                 incr slowerThan($dog) $slowerThan($slowerDog)
  91.             }
  92.         }
  93.  
  94.         set sortedDogStrings {}
  95.         foreach dog $sortedDogs {
  96.             lappend sortedDogStrings "[dogString $dog]"
  97.         }
  98.         puts "Sorted [expr {[llength $sortedDogs]+1}] dogs so far: [join $sortedDogStrings " > "] > [dogString $fastestDog]"
  99.     }
  100. }
  101.  
  102. proc dogsToRace {fastestDog} {
  103.     upvar rank rank
  104.     upvar slowerThan slowerThan
  105.  
  106.     set dogs {}
  107.     set fastestDogs {}
  108.     while {[llength $dogs]<5} {
  109.  
  110.         if {[llength $dogs]+[llength $rank($fastestDog)]>5} {
  111.             while {[llength $dogs]<5} {
  112.                 set maxDepth -1
  113.                 set bestDog {}
  114.                 foreach dog $rank($fastestDog) {
  115.                     if {$slowerThan($dog)>$maxDepth} {
  116.                         set maxDepth $slowerThan($dog)
  117.                         set bestDog $dog
  118.                     }
  119.                 }
  120.                 lappend dogs $bestDog
  121.             }
  122.             break
  123.         } elseif {$rank($fastestDog)!={}} {
  124.             set dogs [concat $dogs $rank($fastestDog)]
  125.         }
  126.  
  127.         set dogsAdded 0
  128.         foreach dog $rank($fastestDog) {
  129.             if {$rank($dog) != {}} {
  130.                 lappend fastestDogs [list $dog $slowerThan($dog)]
  131.                 set dogsAdded 1
  132.             }
  133.         }
  134.         if {!$dogsAdded} break
  135.  
  136.         set fastestDogs [lsort -index end -integer -decreasing $fastestDogs]
  137.         set fastestDog [lindex [lindex $fastestDogs 0] 0]
  138.         set fastestDogs [lrange $fastestDogs 1 end]
  139.     }
  140.  
  141.     return $dogs
  142. }
  143.  
  144. proc rankDogs {dogs} {
  145.     upvar rank rank
  146.     upvar slowerThan slowerThan
  147.  
  148.     set noOfDogs [llength $dogs]
  149.     if {$noOfDogs>25} {
  150.         set leaders {}
  151.         for {set p 0} {$p<5} {incr p} {
  152.             set from [expr {($noOfDogs*$p)/5}]
  153.             set to [expr {($noOfDogs*($p+1))/5 - 1}]
  154.             lappend leaders [rankDogs [lrange $dogs $from $to]]
  155.         }
  156.         set sortedDogs [race5Dogs $leaders]
  157.         set index 5
  158.     } elseif {$noOfDogs>5} {
  159.         set leaders {}
  160.         for {set from 0; set to 4} {$from<$noOfDogs} {incr from 5; incr to 5} {
  161.             lappend leaders [rankDogs [lrange $dogs $from $to]]
  162.         }
  163.         set sortedDogs [race5Dogs $leaders]
  164.         set index [llength $leaders]
  165.     } else {
  166.         set sortedDogs [race5Dogs $dogs]
  167.         set rank([lindex $sortedDogs end]) {}
  168.         set slowerThan([lindex $sortedDogs end]) 0
  169.         set index $noOfDogs
  170.     }
  171.  
  172.     foreach dog [lreverse [lrange $sortedDogs 0 end-1]] {
  173.         set slowerDog [lindex $sortedDogs [incr index -1]]
  174.         incr slowerThan($dog)
  175.         incr slowerThan($dog) $slowerThan($slowerDog)
  176.         lappend rank($dog) $slowerDog
  177.     }
  178.  
  179.     return [lindex $sortedDogs 0]
  180. }
  181.  
  182. proc randomDogs {howManyDogs} {
  183.     global dogNames
  184.  
  185.     set dogs {}
  186.     array set usedNames {}
  187.  
  188.     while {[llength $dogs]<$howManyDogs} {
  189.         set dogName [lindex $dogNames [expr {int(rand()*[llength $dogNames])}]]
  190.         if {[info exists usedNames($dogName)]} continue
  191.         set usedNames($dogName) 1
  192.  
  193.         set speed [expr {rand()}]
  194.         lappend dogs [list $dogName $speed]
  195.     }
  196.  
  197.     return $dogs
  198. }
  199.  
  200. proc dogString {dog} {
  201.     lassign $dog name speed
  202.     return "$name ([format %.1f [expr {$speed*100}]])"
  203. }
  204.  
  205. proc race5Dogs { dogs } {
  206.     global raceCount
  207.     incr raceCount
  208.     puts "race #$raceCount:"
  209.     foreach dog $dogs {lappend racers [dogString $dog]}
  210.     puts "[join $racers " v "]"
  211.     puts ""
  212.  
  213.     set sortedDogs [lsort -real -decreasing -index end $dogs]
  214.  
  215.     puts "result:"
  216.     set rank 0
  217.     foreach dog $sortedDogs {puts "[incr rank]. [dogString $dog]"}
  218.     puts ""
  219.  
  220.     return $sortedDogs
  221. }
  222.  
  223. set raceCount 0
  224. set allDogs [randomDogs 25]
  225. sortDogs $allDogs
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement