advent-of-code/2023/day18.py

55 lines
1.3 KiB
Python
Raw Normal View History

2023-12-04 18:32:41 +00:00
import sys
2023-12-18 10:40:09 +00:00
from typing import Literal, TypeAlias, cast
Direction: TypeAlias = Literal["R", "L", "U", "D"]
DIRECTIONS: list[Direction] = ["R", "D", "L", "U"]
MOVES: dict[Direction, tuple[int, int]] = {
"R": (0, +1),
"L": (0, -1),
"U": (-1, 0),
"D": (+1, 0),
}
def area(corners: list[tuple[int, int]], perimeter: int) -> int:
area = abs(
sum(c0[0] * c1[1] - c0[1] * c1[0] for c0, c1 in zip(corners, corners[1::])) // 2
)
return 1 + area - perimeter // 2 + perimeter
def polygon(values: list[tuple[Direction, int]]) -> tuple[list[tuple[int, int]], int]:
perimeter = 0
corners: list[tuple[int, int]] = [(0, 0)]
for direction, amount in values:
perimeter += amount
corners.append(
(
corners[-1][0] + amount * MOVES[direction][0],
corners[-1][1] + amount * MOVES[direction][1],
)
)
return corners, perimeter
2023-12-04 18:32:41 +00:00
lines = sys.stdin.read().splitlines()
2023-12-18 10:40:09 +00:00
2023-12-04 18:32:41 +00:00
# part 1
2023-12-18 10:40:09 +00:00
answer_1 = area(
*polygon([(cast(Direction, (p := line.split())[0]), int(p[1])) for line in lines])
)
2023-12-04 18:32:41 +00:00
print(f"answer 1 is {answer_1}")
# part 2
2023-12-18 10:40:09 +00:00
answer_2 = area(
*polygon(
[
(DIRECTIONS[int((p := line.split()[-1])[-2])], int(p[2:-2], 16))
for line in lines
]
)
)
2023-12-04 18:32:41 +00:00
print(f"answer 2 is {answer_2}")