Skip to content

Commit

Permalink
Day 18
Browse files Browse the repository at this point in the history
  • Loading branch information
aastrand committed Dec 18, 2023
1 parent 081175c commit 6374150
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 5 deletions.
65 changes: 65 additions & 0 deletions day18/day18.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python3

import sys

from utils import io
from utils.grid import BOTTOM, LEFT, RIGHT, TOP
from utils.math import poly_area

instructions = {
"R": RIGHT,
"L": LEFT,
"U": TOP,
"D": BOTTOM,
}


def to_instr(i):
if i == 0:
return "R"
elif i == 1:
return "D"
elif i == 2:
return "L"
elif i == 3:
return "U"
else:
raise Exception("Unknown instruction", i)


def get_outline(lines, part2=False):
pos = (0, 0)
corners = [pos]
outline = 0
for line in lines:
if not part2:
instr = line.split("()")[0].strip().split(" ")
dir = instr[0]
length = int(instr[1])
else:
instr = line.split("#")[1].strip()[:-1]
length = int(instr[:-1], 16)
dir = to_instr(int(instr[-1]))

pos = (pos[0] + instructions[dir][0] * length, pos[1] + instructions[dir][1] * length)
outline += length
corners.append(pos)

return corners, outline


def solve(filename, part2=False):
corners, outline = get_outline(io.get_lines(filename), part2)
return int(poly_area(corners)) + outline // 2 + 1


def main():
assert solve("example.txt") == 62
print(solve("../input/2023/day18.txt"))

assert solve("example.txt", True) == 952408144115
print(solve("../input/2023/day18.txt", True))


if __name__ == "__main__":
sys.exit(main())
14 changes: 14 additions & 0 deletions day18/example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
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)
2 changes: 1 addition & 1 deletion input
Submodule input updated from 400c9f to 9759ad
2 changes: 1 addition & 1 deletion test/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def test_flood_fill(self):
grid = Grid.from_lines(lines)

visitor_set = set()
visited = grid.flood_fill((0, 0), lambda g, p: visitor_set.add(p))
visited = grid.flood_fill((0, 0), ".", lambda g, p: visitor_set.add(p))

self.assertTrue((5, 4) in visited)
self.assertTrue((1, 1) not in visited)
Expand Down
25 changes: 24 additions & 1 deletion test/math.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import unittest

from utils.math import manhattan_dist, sign
from utils.math import manhattan_dist, poly_area, sign


class TestMath(unittest.TestCase):
Expand All @@ -12,6 +12,29 @@ def test_sign(self):
def test_manhattan_dist(self):
self.assertEqual(1 + 10, manhattan_dist(0, 4, -10, 3))

def test_poly_area(self):
poly = [(0, 0), (0, 10), (10, 10), (10, 0)]
self.assertEqual(100.0, poly_area(poly))

poly = [
(0, 0),
(461937, 0),
(461937, 56407),
(818608, 56407),
(818608, 919647),
(1186328, 919647),
(1186328, 1186328),
(609066, 1186328),
(609066, 356353),
(497056, 356353),
(497056, 1186328),
(5411, 1186328),
(5411, 500254),
(0, 500254),
(0, 0),
]
self.assertEqual(952404941483.0, poly_area(poly))


if __name__ == "__main__":
unittest.main()
4 changes: 2 additions & 2 deletions utils/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def walk(self, visitor=lambda *a, **kw: 0):

visitor(self, pos, val)

def flood_fill(self, pos, visitor=lambda *a, **kw: 0):
def flood_fill(self, pos, val=".", visitor=lambda *a, **kw: 0):
q = [pos]
visited = set()
visited.add(pos)
Expand All @@ -105,7 +105,7 @@ def flood_fill(self, pos, visitor=lambda *a, **kw: 0):

for o in OFFSETS_STRAIGHT:
neighbour = (pos[0] + o[0], pos[1] + o[1])
if self.get(neighbour) == "." and neighbour not in visited:
if self.get(neighbour) == val and neighbour not in visited:
q.append(neighbour)
visited.add(neighbour)

Expand Down
8 changes: 8 additions & 0 deletions utils/math.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@ def manhattan_dist(x1, y1, x2, y2):

def sign(a):
return (a > 0) - (a < 0)


def poly_area(p):
return 0.5 * abs(sum(x0 * y1 - x1 * y0 for ((x0, y0), (x1, y1)) in segments(p)))


def segments(p):
return zip(p, p[1:] + [p[0]])

0 comments on commit 6374150

Please sign in to comment.