Compare commits

...

4 Commits

Author SHA1 Message Date
magical f1e2dc0d24 slightly more idiomatic tcl?
lmul is a more idiomatic name than product.
using join+eval is probably slower than foreach but the lists are small
so i don't care.
2023-12-06 07:06:20 +00:00
magical 905dee030f day 6 tcl solution 2023-12-06 06:52:26 +00:00
magical ed146f7fe1 day 6 fancy solution + cleanup 2023-12-06 06:20:12 +00:00
magical b480088127 day 6 solution 2023-12-06 05:11:23 +00:00
4 changed files with 115 additions and 0 deletions

2
day06/input 100644
View File

@ -0,0 +1,2 @@
Time: 48 87 69 81
Distance: 255 1288 1117 1623

2
day06/sample1.in 100644
View File

@ -0,0 +1,2 @@
Time: 7 15 30
Distance: 9 40 200

75
day06/sol.py 100644
View File

@ -0,0 +1,75 @@
from math import sqrt
sample = {
"time": [7, 15, 30],
"distance": [9, 40, 200],
}
input = {
"time": [ 48, 87, 69, 81,],
"distance": [ 255, 1288, 1117, 1623,],
}
def solve(data):
time = data["time"]
dist = data["distance"]
part1 = 1
for t, best in zip(time, dist):
ways = 0
for i in range(t):
v = i
d = (t-i)*v
if d > best:
ways += 1
part1 *= ways
return part1
def fancy_solve(data):
time = data["time"]
dist = data["distance"]
for t, best in zip(time, dist):
# the distance traveled if the boat is released at time i
# is equal to (t-i)*i
# we want to know the range of values of i for which this
# exceeds the best time
# (t-i)*i > best
# a little rearranging gets us the quadratic equation
# i^2 - ti + best <= 0
# which we can determine the crossing points for
# using the quadratic formula (the good one, not the
# one you learned in school)
h = t/2
s = sqrt(h*h - best)
#print(h-s, h+s)
# in general these will not be at integer values,
# so we probe the floor and ceiling of each crossing
# point to determine exactly where the condition is met
a = int(h-s)
b = int(h+s)
if (t-a)*a <= best:
a += 1
if (t-b)*b > best:
b += 1
ways = b - a
return ways
print(solve(sample))
print(solve(input))
def part2(data):
return {"time": [int("".join(str(x) for x in data["time"]))],
"distance": [int("".join(str(x) for x in data["distance"]))]}
print(solve(part2(sample)))
print(fancy_solve(part2(sample)))
print(fancy_solve(part2(input)))

36
day06/sol.tcl 100755
View File

@ -0,0 +1,36 @@
#!/usr/bin/env tclsh
package require Tcl 8.6
set input stdin
regexp {Time: (.*)} [gets $input] _ time
regexp {Distance: (.*)} [gets $input] _ dist
proc solve {t d} {
# the distance traveled if the boat is released at time i
# is equal to (t-i)*i
# we want to know the range of values of i for which this
# exceeds the best time (d)
# (t-i)*i > d
# a little rearranging gets us the quadratic equation
# i^2 - ti + d <= 0
# which we can determine the crossing points for
# using the quadratic formula (the good one, not the
# one you learned in school)
#puts "solve $t $d"
set h [expr {$t / 2.0}]
set s [expr {sqrt($h*$h - $d)}]
set a [expr {int($h-$s)}]
set b [expr {int($h+$s)}]
# in general these will not be at integer values,
# so we probe the floor and ceiling of each crossing
# point to determine exactly where the condition is met
if {($t-$a)*$a <= $d} { incr a }
if {($t-$b)*$b > $d} { incr b }
#puts "a=$a b=$b"
return [expr {$b - $a}]
}
proc lmul {list} { return [expr [join $list *]] }
proc smush {list} { return [join $list ""] }
puts "Part 1: [lmul [lmap t $time d $dist {solve $t $d}]]"
puts "Part 2: [solve [smush $time] [smush $dist]]"