You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.8 KiB

#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]
}