Do day 18.

This commit is contained in:
felixm 2023-12-19 15:52:36 -05:00
parent 5626205b2f
commit 30a8489313
3 changed files with 145 additions and 2 deletions

View File

@ -14,6 +14,9 @@
- Day 12: 52:00 and 22:00 for leaderboard; had the right idea and I am good at this type of problem
- ...
- Day 16: 00:27:30 745; best placement so far, of course still horribly slow
- Day 17: a couple of hours... realized that I need A* after a while; reused
- Day 17: a couple of hours; I realized that I need A* after a while; reused
implementation from Project Euler but improved with heapq which was super fun
- Day 18: a couple of hours; I realized that I need shoelace algo for part two
but didn't realize that I have to compute the outer edges for a while and
after I did, I still got clockwise/counter-clockwise issues. They could have
made it meaner by using different clock directions for example and input.

129
d18.py Normal file
View File

@ -0,0 +1,129 @@
from lib import *
EXAMPLE = """
R 6 (#70c710)
D 5 (#0dc571)
L 2 (#5713f0)
D 2 (#d2c081)
R 2 (#59c680)
D 2 (#411b91)
L 5 (#8ceee2)
U 2 (#caa173)
L 1 (#1b58a2)
U 2 (#caa171)
R 2 (#7807d2)
U 3 (#a77fa3)
L 2 (#015232)
U 2 (#7a21e3)
"""
m = {
"R": Grid2D.E,
"D": Grid2D.S,
"L": Grid2D.W,
"U": Grid2D.N,
}
def solve(i: Input, second=False):
lines = i.lines()
ins = []
for l in lines:
if not l:
continue
d, l, c = l.split()
ins.append((int(l), m[d]))
c = (0, 0)
coords: list[tuple[int, int]] = [c]
for count, d in ins:
for _ in range(count):
c = add2(c, d)
coords.append(c)
to_visit: list[tuple[int, int]] = [(1, 1)]
while to_visit:
c = to_visit.pop()
for n in [Grid2D.S, Grid2D.E, Grid2D.W, Grid2D.N]:
nc = add2(c, n)
if nc not in coords:
coords.append(nc)
to_visit.append(nc)
return len(set(coords))
def calc(ins):
c = (0, 0)
corners = []
for i, (count, d) in enumerate(ins):
c = (c[0] + count * d[0], c[1] + count * d[1])
nd = ins[(i + 1) % len(ins)][1]
if d == nd:
raise Exception("Dirs should not be equal!")
# XXX: This mapping only works when going clockwise!
match d, nd:
case Grid2D.W, Grid2D.N:
c_log = (c[0] + 1, c[1])
case Grid2D.W, Grid2D.S:
c_log = (c[0] + 1, c[1] + 1)
case Grid2D.E, Grid2D.N:
c_log = (c[0], c[1])
case Grid2D.E, Grid2D.S:
c_log = (c[0], c[1] + 1)
case Grid2D.N, Grid2D.E:
c_log = (c[0], c[1])
case Grid2D.N, Grid2D.W:
c_log = (c[0] + 1, c[1])
case Grid2D.S, Grid2D.E:
c_log = (c[0], c[1] + 1)
case Grid2D.S, Grid2D.W:
c_log = (c[0] + 1, c[1] + 1)
case d, nd:
raise Exception(f"Uncoverred {d=} -> {nd=}")
corners.append(c_log)
return int(shoelace_area(corners))
def solve2(i: Input, second=False):
lines = i.lines()
ins = []
for line in lines:
if not line:
continue
_, _, c = line.split()
c = c.replace("(#", "").replace(")", "")
d = int(c[:5], 16)
m = {"0": Grid2D.E, "1": Grid2D.S, "2": Grid2D.W, "3": Grid2D.N}[c[5]]
ins.append((d, m))
return calc(ins)
def debug():
ins = [
( 3, Grid2D.S,),
( 2, Grid2D.E,),
( 1, Grid2D.N,),
( 1, Grid2D.E,),
( 1, Grid2D.N,),
( 1, Grid2D.W,),
( 1, Grid2D.N,),
( 2, Grid2D.W,),
]
# Should be 14 but is 2 because it's going counter-clockwise, but mapping
# only works for clockwise.
print(calc(ins))
def main():
DAY_INPUT = "i18.txt"
print("Example 1:", solve(Input(EXAMPLE)))
print("Solution 1:", solve(Input(DAY_INPUT)))
print("Example 2:", solve2(Input(EXAMPLE), True))
print("Solution 2:", solve2(Input(DAY_INPUT), True))
return
if __name__ == "__main__":
main()

11
lib.py
View File

@ -31,6 +31,8 @@ class Grid2D:
NE = (-1, 1)
SE = (1, 1)
SW = (1, -1)
COORDS_ORTH = (N, E, S, W)
COORDS_DIAG = (NW, NE, SE, SW)
def __init__(self, text: str):
lines = [line for line in text.splitlines() if line.strip() != ""]
@ -222,3 +224,12 @@ class A_Star(object):
g_score[neighbor] = tentative_g_score
f_score = g_score[neighbor] + h(neighbor)
heapq.heappush(open_set, (f_score, neighbor))
def shoelace_area(corners):
n = len(corners)
area = 0
for i in range(n):
x1, y1 = corners[i]
x2, y2 = corners[(i + 1) % n]
area += (x1 * y2) - (x2 * y1)
return abs(area) / 2.0