Do day 14 and 15.
This commit is contained in:
@@ -13,4 +13,6 @@
|
|||||||
- Day 11: 45:00 and 18:00 for leaderboard; arg, it was doable man
|
- Day 11: 45:00 and 18:00 for leaderboard; arg, it was doable man
|
||||||
- Day 12: 39:45 and 9:46 for leaderboard; the people are ready for there searches :D
|
- Day 12: 39:45 and 9:46 for leaderboard; the people are ready for there searches :D
|
||||||
- Day 13: 44:00 and 12:56 for leaderboard; these people are just good, seriously
|
- Day 13: 44:00 and 12:56 for leaderboard; these people are just good, seriously
|
||||||
- Day 14:
|
- Day 14: 35:00 and 14:54; I just have to get that much quicker... 2D code!
|
||||||
|
- Day 15: 150:00 and 27:00; I didn't use Manhatten dist initially, lot's of debugging
|
||||||
|
- Day 16:
|
||||||
|
|||||||
104
d14.py
Normal file
104
d14.py
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import lib
|
||||||
|
|
||||||
|
EXAMPLE = """
|
||||||
|
498,4 -> 498,6 -> 496,6
|
||||||
|
503,4 -> 502,4 -> 502,9 -> 494,9
|
||||||
|
"""
|
||||||
|
|
||||||
|
def solve(lines: list[str]):
|
||||||
|
c = set()
|
||||||
|
for (i, line) in enumerate(lines):
|
||||||
|
coords = [list(map(int, c.split(","))) for c in line.split(" -> ")]
|
||||||
|
for i in range(len(coords) - 1):
|
||||||
|
a, b = coords[i:i + 2]
|
||||||
|
a_x, a_y = a
|
||||||
|
b_x, b_y = b
|
||||||
|
if a_x == b_x and a_y < b_y:
|
||||||
|
for y in range(a_y, b_y + 1):
|
||||||
|
c.add((a_x, y))
|
||||||
|
elif a_x == b_x and a_y > b_y:
|
||||||
|
for y in range(b_y, a_y + 1):
|
||||||
|
c.add((a_x, y))
|
||||||
|
elif a_y == b_y and a_x < b_x:
|
||||||
|
for x in range(a_x, b_x + 1):
|
||||||
|
c.add((x, a_y))
|
||||||
|
elif a_y == b_y and a_x > b_x:
|
||||||
|
for x in range(b_x, a_x + 1):
|
||||||
|
c.add((x, a_y))
|
||||||
|
else:
|
||||||
|
raise Exception(f"unexpected {a=} {b=}")
|
||||||
|
|
||||||
|
largest_y = max(c, key=lambda c: c[1])[1]
|
||||||
|
s = (500, 0)
|
||||||
|
s_count = 0
|
||||||
|
while s[1] < largest_y:
|
||||||
|
if not (ns := (s[0], s[1] + 1)) in c:
|
||||||
|
s = ns
|
||||||
|
elif not (ns := (s[0] - 1, s[1] + 1)) in c:
|
||||||
|
s = ns
|
||||||
|
elif not (ns := (s[0] + 1, s[1] + 1)) in c:
|
||||||
|
s = ns
|
||||||
|
else:
|
||||||
|
c.add(s)
|
||||||
|
s = (500, 0)
|
||||||
|
s_count += 1
|
||||||
|
return s_count
|
||||||
|
|
||||||
|
def solve2(lines: list[str]):
|
||||||
|
c = set()
|
||||||
|
for (i, line) in enumerate(lines):
|
||||||
|
coords = [list(map(int, c.split(","))) for c in line.split(" -> ")]
|
||||||
|
for i in range(len(coords) - 1):
|
||||||
|
a, b = coords[i:i + 2]
|
||||||
|
a_x, a_y = a
|
||||||
|
b_x, b_y = b
|
||||||
|
if a_x == b_x and a_y < b_y:
|
||||||
|
for y in range(a_y, b_y + 1):
|
||||||
|
c.add((a_x, y))
|
||||||
|
elif a_x == b_x and a_y > b_y:
|
||||||
|
for y in range(b_y, a_y + 1):
|
||||||
|
c.add((a_x, y))
|
||||||
|
elif a_y == b_y and a_x < b_x:
|
||||||
|
for x in range(a_x, b_x + 1):
|
||||||
|
c.add((x, a_y))
|
||||||
|
elif a_y == b_y and a_x > b_x:
|
||||||
|
for x in range(b_x, a_x + 1):
|
||||||
|
c.add((x, a_y))
|
||||||
|
else:
|
||||||
|
raise Exception(f"unexpected {a=} {b=}")
|
||||||
|
|
||||||
|
largest_y = max(c, key=lambda c: c[1])[1]
|
||||||
|
for x in range(-10000, 10000):
|
||||||
|
c.add((x, largest_y + 2))
|
||||||
|
|
||||||
|
s = (500, 0)
|
||||||
|
s_count = 1
|
||||||
|
while True:
|
||||||
|
if not (ns := (s[0], s[1] + 1)) in c:
|
||||||
|
s = ns
|
||||||
|
elif not (ns := (s[0] - 1, s[1] + 1)) in c:
|
||||||
|
s = ns
|
||||||
|
elif not (ns := (s[0] + 1, s[1] + 1)) in c:
|
||||||
|
s = ns
|
||||||
|
elif s[1] == 0:
|
||||||
|
return s_count
|
||||||
|
else:
|
||||||
|
c.add(s)
|
||||||
|
s_count += 1
|
||||||
|
s = (500, 0)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
lines = lib.str_to_lines_no_empty(EXAMPLE)
|
||||||
|
print("Example 1:", solve(lines))
|
||||||
|
|
||||||
|
lines = lib.str_to_lines_no_empty(open("i14.txt").read())
|
||||||
|
print("Solution 1:", solve(lines))
|
||||||
|
|
||||||
|
lines = lib.str_to_lines_no_empty(EXAMPLE)
|
||||||
|
print("Example 2:", solve2(lines))
|
||||||
|
|
||||||
|
lines = lib.str_to_lines_no_empty(open("i14.txt").read())
|
||||||
|
print("Solution 2:", solve2(lines))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
151
d15.py
Normal file
151
d15.py
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
import lib
|
||||||
|
import math
|
||||||
|
|
||||||
|
EXAMPLE = """
|
||||||
|
Sensor at x=2, y=18: closest beacon is at x=-2, y=15
|
||||||
|
Sensor at x=9, y=16: closest beacon is at x=10, y=16
|
||||||
|
Sensor at x=13, y=2: closest beacon is at x=15, y=3
|
||||||
|
Sensor at x=12, y=14: closest beacon is at x=10, y=16
|
||||||
|
Sensor at x=10, y=20: closest beacon is at x=10, y=16
|
||||||
|
Sensor at x=14, y=17: closest beacon is at x=10, y=16
|
||||||
|
Sensor at x=8, y=7: closest beacon is at x=2, y=10
|
||||||
|
Sensor at x=2, y=0: closest beacon is at x=2, y=10
|
||||||
|
Sensor at x=0, y=11: closest beacon is at x=2, y=10
|
||||||
|
Sensor at x=20, y=14: closest beacon is at x=25, y=17
|
||||||
|
Sensor at x=17, y=20: closest beacon is at x=21, y=22
|
||||||
|
Sensor at x=16, y=7: closest beacon is at x=15, y=3
|
||||||
|
Sensor at x=14, y=3: closest beacon is at x=15, y=3
|
||||||
|
Sensor at x=20, y=1: closest beacon is at x=15, y=3
|
||||||
|
"""
|
||||||
|
|
||||||
|
def unify_ranges(ranges):
|
||||||
|
# aaaaaaaaaaa
|
||||||
|
# bbbb
|
||||||
|
#
|
||||||
|
# aaa
|
||||||
|
# bbb
|
||||||
|
#
|
||||||
|
# aaa
|
||||||
|
# bbb
|
||||||
|
ranges = sorted(ranges)
|
||||||
|
while True:
|
||||||
|
for i in range(len(ranges) - 1):
|
||||||
|
a, b = ranges[i], ranges[i + 1]
|
||||||
|
if a == b:
|
||||||
|
del ranges[i]
|
||||||
|
break
|
||||||
|
elif a[0] == b[0]:
|
||||||
|
ranges[i] = (a[0], max(a[1], b[1]))
|
||||||
|
del ranges[i + 1]
|
||||||
|
break
|
||||||
|
elif a[1] == b[1]:
|
||||||
|
ranges[i] = (min(a[0], b[0]), b[1])
|
||||||
|
del ranges[i + 1]
|
||||||
|
break
|
||||||
|
elif a[0] < b[0] and a[1] > b[1]:
|
||||||
|
del ranges[i + 1]
|
||||||
|
break
|
||||||
|
elif a[0] > b[0] and a[1] < b[1]:
|
||||||
|
del ranges[i]
|
||||||
|
break
|
||||||
|
elif a[1] < b[0]:
|
||||||
|
pass
|
||||||
|
elif a[0] <= b[1] and a[1] >= b[0]:
|
||||||
|
ranges[i] = (a[0], b[1])
|
||||||
|
del ranges[i + 1]
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise Exception("uhoh", a, b)
|
||||||
|
else:
|
||||||
|
return ranges
|
||||||
|
return ranges
|
||||||
|
|
||||||
|
def mdist(dx, dy):
|
||||||
|
return abs(dx) + abs(dy)
|
||||||
|
|
||||||
|
def xdist(dm, dy):
|
||||||
|
x = dm - abs(dy)
|
||||||
|
if x <= 0:
|
||||||
|
return 0
|
||||||
|
return x
|
||||||
|
|
||||||
|
def solve(lines: list[str], yt):
|
||||||
|
sensors = []
|
||||||
|
bacons = set()
|
||||||
|
for (i, line) in enumerate(lines):
|
||||||
|
digits = lib.str_to_int_list(line)
|
||||||
|
sx, sy, bx, by = digits
|
||||||
|
sm = mdist(bx - sx, by - sy)
|
||||||
|
sensors.append([sx, sy, sm])
|
||||||
|
bacons.add((bx, by))
|
||||||
|
|
||||||
|
ranges = []
|
||||||
|
for (sx, sy, sm) in sensors:
|
||||||
|
x_range = xdist(sm, yt - sy)
|
||||||
|
if x_range == 0:
|
||||||
|
continue
|
||||||
|
r = (sx - x_range, sx + x_range)
|
||||||
|
# print(f"{sx=} {sy=} {r=}")
|
||||||
|
ranges.append(r)
|
||||||
|
|
||||||
|
ranges = unify_ranges(ranges)
|
||||||
|
r = 0
|
||||||
|
for (a, b) in ranges:
|
||||||
|
r += b - a + 1
|
||||||
|
for (bx, by) in list(bacons):
|
||||||
|
if by == yt and bx >= a and bx <= b:
|
||||||
|
r -= 1
|
||||||
|
# 140:00 I don't know what a Manhattan distance is.
|
||||||
|
return r
|
||||||
|
|
||||||
|
def solve2(lines: list[str], xymax):
|
||||||
|
sensors = []
|
||||||
|
bacons = set()
|
||||||
|
for (i, line) in enumerate(lines):
|
||||||
|
digits = lib.str_to_int_list(line)
|
||||||
|
sx, sy, bx, by = digits
|
||||||
|
sm = mdist(bx - sx, by - sy)
|
||||||
|
sensors.append([sx, sy, sm])
|
||||||
|
bacons.add((bx, by))
|
||||||
|
|
||||||
|
finds = []
|
||||||
|
for yt in range(0, xymax):
|
||||||
|
ranges = []
|
||||||
|
for (sx, sy, sm) in sensors:
|
||||||
|
x_range = xdist(sm, yt - sy)
|
||||||
|
if x_range == 0:
|
||||||
|
continue
|
||||||
|
r = (sx - x_range, sx + x_range)
|
||||||
|
ranges.append(r)
|
||||||
|
ranges = unify_ranges(ranges)
|
||||||
|
|
||||||
|
if ranges[0][0] > 0:
|
||||||
|
raise Exception("Bacon at 0.")
|
||||||
|
elif ranges[-1][-1] < xymax:
|
||||||
|
raise Exception("Bacon at xymax.")
|
||||||
|
|
||||||
|
for i in range(len(ranges) - 1):
|
||||||
|
if ranges[i + 1][0] - ranges[i][1] > 1:
|
||||||
|
finds.append((ranges[i][1] + 1, yt))
|
||||||
|
if len(finds) != 1:
|
||||||
|
raise Exception("TOO MANY FINDS")
|
||||||
|
else:
|
||||||
|
x, y = finds[0]
|
||||||
|
return x * 4000000 + y
|
||||||
|
# 10:00
|
||||||
|
|
||||||
|
def main():
|
||||||
|
lines = lib.str_to_lines_no_empty(EXAMPLE)
|
||||||
|
print("Example 1:", solve(lines, 10))
|
||||||
|
|
||||||
|
lines = lib.str_to_lines_no_empty(open("i15.txt").read())
|
||||||
|
print("Solution 1:", solve(lines, 2000000))
|
||||||
|
|
||||||
|
lines = lib.str_to_lines_no_empty(EXAMPLE)
|
||||||
|
print("Example 2:", solve2(lines, 20))
|
||||||
|
|
||||||
|
lines = lib.str_to_lines_no_empty(open("i15.txt").read())
|
||||||
|
print("Solution 2:", solve2(lines, 4000000))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
4
lib.py
4
lib.py
@@ -2,13 +2,13 @@ import re
|
|||||||
|
|
||||||
def str_to_single_int(line: str) -> int:
|
def str_to_single_int(line: str) -> int:
|
||||||
line = line.replace(" ", "")
|
line = line.replace(" ", "")
|
||||||
r = re.compile(r"\d+")
|
r = re.compile(r"-?\d+")
|
||||||
for m in r.findall(line):
|
for m in r.findall(line):
|
||||||
return int(m)
|
return int(m)
|
||||||
raise Exception("No single digit sequence in '{line}'")
|
raise Exception("No single digit sequence in '{line}'")
|
||||||
|
|
||||||
def str_to_int_list(line: str) -> list[int]:
|
def str_to_int_list(line: str) -> list[int]:
|
||||||
r = re.compile(r"\d+")
|
r = re.compile(r"-?\d+")
|
||||||
return list(map(int, r.findall(line)))
|
return list(map(int, r.findall(line)))
|
||||||
|
|
||||||
def str_to_lines_no_empty(text: str) -> list[str]:
|
def str_to_lines_no_empty(text: str) -> list[str]:
|
||||||
|
|||||||
Reference in New Issue
Block a user