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.
95 lines
2.8 KiB
95 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] |
|
} |
|
|
|
|
|
|
|
|