78
day13/day13.py
Executable file
78
day13/day13.py
Executable file
@@ -0,0 +1,78 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
import dataclasses
|
||||||
|
import re
|
||||||
|
from typing import Sequence, Set, Tuple
|
||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
|
|
||||||
|
FOLD_RE = re.compile(r"fold along (?P<dir>[xy])=(?P<off>[0-9]+)")
|
||||||
|
Point = Tuple[int, int]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class Fold:
|
||||||
|
direction: str
|
||||||
|
offset: int
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_str(s: str) -> "Fold":
|
||||||
|
match = FOLD_RE.match(s)
|
||||||
|
assert match
|
||||||
|
return Fold(match["dir"], int(match["off"]))
|
||||||
|
|
||||||
|
|
||||||
|
class Grid:
|
||||||
|
def __init__(self, points: Set[Point]):
|
||||||
|
self.rows = max(y for x, y in points) + 1
|
||||||
|
self.cols = max(x for x, y in points) + 1
|
||||||
|
self.points = points
|
||||||
|
|
||||||
|
def apply_fold(self, fold: Fold):
|
||||||
|
if fold.direction == "y":
|
||||||
|
# Find all points that are below this line
|
||||||
|
below = {(x, y) for x, y in self.points if y > fold.offset}
|
||||||
|
# Find their new positions and then remove the old ones
|
||||||
|
self.points -= below
|
||||||
|
self.points |= {(x, self.rows - y - 1) for (x, y) in below}
|
||||||
|
self.rows //= 2
|
||||||
|
else:
|
||||||
|
# Find all points that are to the right of this line
|
||||||
|
right = {(x, y) for x, y in self.points if x > fold.offset}
|
||||||
|
# Find their new positions and then remove the old ones
|
||||||
|
self.points -= right
|
||||||
|
self.points |= {(self.cols - x - 1, y) for (x, y) in right}
|
||||||
|
self.cols //= 2
|
||||||
|
|
||||||
|
def display(self) -> Sequence[str]:
|
||||||
|
grid = [["." for _ in range(self.cols)] for _ in range(self.rows)]
|
||||||
|
for x, y in self.points:
|
||||||
|
grid[y][x] = "#"
|
||||||
|
return ["".join(line) for line in grid]
|
||||||
|
|
||||||
|
|
||||||
|
def part1(grid: Grid, folds: Sequence[Fold]):
|
||||||
|
grid = deepcopy(grid)
|
||||||
|
grid.apply_fold(folds[0])
|
||||||
|
print(len(grid.points))
|
||||||
|
|
||||||
|
|
||||||
|
def part2(grid: Grid, folds: Sequence[Fold]):
|
||||||
|
for fold in folds:
|
||||||
|
grid.apply_fold(fold)
|
||||||
|
print("\n".join(grid.display()))
|
||||||
|
|
||||||
|
|
||||||
|
points_str, folds_str = sys.stdin.read().split("\n\n")
|
||||||
|
points = {
|
||||||
|
(int(a), int(b))
|
||||||
|
for a, b in map(lambda line: line.split(","), points_str.split("\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
grid = Grid(points)
|
||||||
|
folds = [Fold.from_str(line) for line in folds_str.split("\n")]
|
||||||
|
|
||||||
|
print("Part 1")
|
||||||
|
part1(grid, folds)
|
||||||
|
print("Part 2")
|
||||||
|
part2(grid, folds)
|
||||||
21
day13/example.txt
Normal file
21
day13/example.txt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
6,10
|
||||||
|
0,14
|
||||||
|
9,10
|
||||||
|
0,3
|
||||||
|
10,4
|
||||||
|
4,11
|
||||||
|
6,0
|
||||||
|
6,12
|
||||||
|
4,1
|
||||||
|
0,13
|
||||||
|
10,12
|
||||||
|
3,4
|
||||||
|
3,0
|
||||||
|
8,4
|
||||||
|
1,10
|
||||||
|
2,14
|
||||||
|
8,10
|
||||||
|
9,0
|
||||||
|
|
||||||
|
fold along y=7
|
||||||
|
fold along x=5
|
||||||
1138
day13/input.txt
Normal file
1138
day13/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user