#naive - literal approach to the problem via a form of simulation (as attempted in https://www.youtube.com/watch?v=7fylNa2wZaU) #the proper solution is of course just a little bit of maths - but the list-manipulation is an interesting exercise. proc collapse lst { #puts stdout "lst:'$lst' len:[llength $lst]" foreach i $lst { #puts stderr "'$i len:[llength $i] len-el0:[llength [lindex $i 0]]'" if {[llength $i] == 2 && [llength [lindex $i 0]] ==2} { lappend out [list [list [lindex $i 0 0] [expr {[lindex $i 0 1] + [lindex $i 1 1]}] ] ] } else { lappend out $i } } return $out } #.=* list |h/0,t/tail> .=t>1*,h>end,h>end list |> punk::group_list_by {[lindex $item 0]} |> inspect |> .= collapse <q| {a 1} {b 1} {c 1} #usage: drinkx 0 n {a 1} {b 1}... pipealias drinkx .=* list {| h/0,t/tail >} .=t>1*,h>end,h>end list {| data2, nplus@end/1 >} {expr {$nsofar + $nplus}} {| nsofar >} {set data2} {| >} punk::group_list_by {[lindex $item 0]} {| >} .= collapse {| >} .=>2 lmap v {lindex $v 0} {| >} .=nsofar>1,n>2,data>end* list <q/2-end,nsofar/0,n/1| input.= list {sheldon 1} {leonard 1} {penny 1} {rajesh 1} {howard 1} pipealias xxx .= {list $nsofar $n {*}$q} {| , i/0, n/1 >} .=>. {set in $data; while {$i < $n } { #puts stdout "$i < $n" #puts stdout "drinkx $in" set in [drinkx {*}$in] lassign $in i n }; set in} {| >} inspect -channel null {| result/end >} {set result} <q/2-end,nsofar/0,n/1| #xxx 0 10010 {*}$input #howard #xxx 0 7230702951 {*}$input #(our result is at end of list) #leonard set js_solution { function whoIsNext(names, r){ let peopleInLine = names.length; let copiesOfEachPerson = 1; while (r > peopleInLine) { r -= peopleInLine; copiesOfEachPerson *= 2; peopleInLine *= 2; } return names[Math.floor((r - 1) / copiesOfEachPerson) % peopleInLine]; } } proc who_is_next {names n} { set peopleInLine [llength $names] set copiesOfEachPerson 1 while {$n > $peopleInLine} { set n [expr {$n - $peopleInLine}] set copiesOfEachPerson [expr {$copiesOfEachPerson * 2}] set peopleInLine [expr {$peopleInLine * 2}] } set idx [expr {int(floor(($n -1)/$copiesOfEachPerson)) % $peopleInLine}] #puts "idx:$idx names: $names" set result [lindex $names $idx] }