Do day 18.
This commit is contained in:
parent
5626205b2f
commit
30a8489313
@ -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
129
d18.py
Normal 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
11
lib.py
@ -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
|
||||
|
Reference in New Issue
Block a user