advent-of-code/2021/13/python/main.py
2022-11-28 23:08:59 +01:00

102 lines
2.1 KiB
Python

#!/usr/bin/env python
from os.path import dirname, join
from typing import Tuple
# Day 13
# Common
def read_input(filename):
data = join(dirname(__file__), '..', filename)
with open(data) as f:
return f.read().strip()
test = read_input('test.txt')
data = read_input('input.txt')
class Paper:
def __init__(self, points: set[tuple[int, int]], folds=list[tuple[bool, int]]):
self.points = points
self.folds = folds
def __str__(self):
max_x = 0
max_y = 0
for x, y in self.points:
max_x = max(max_x, x)
max_y = max(max_y, y)
# Init grid
grid = [
['.' for _ in range(max_x+1)]
for _ in range(max_y+1)
]
# Fill grid
for x, y in self.points:
grid[y][x] = '#'
return '\n'.join([
''.join(row)
for row in grid
])
def fold_all(self):
for fold in self.folds:
self.fold(fold)
def fold(self, fold):
x, threshold = fold
i = 0 if x else 1
for point in list(self.points):
value = point[i]
if value < threshold:
continue
new_value = 2*threshold - value
self.points.remove(point)
p = list(point)
p[i] = new_value
self.points.add(tuple(p))
def flag_1(self):
self.fold(self.folds[0])
print(len(self.points))
def flag_2(self):
self.fold_all()
print(self)
@staticmethod
def parse(data: str) -> 'Paper':
header, footer = data.split('\n\n')
points = {
tuple(map(int, point.split(',')))
for point
in header.split('\n')
}
folds = [
(fold[11] == 'x', int(fold[13:]))
for fold in footer.split('\n')
]
return Paper(points, folds)
# 1
print('1.')
paper = Paper.parse(test)
paper.flag_1()
paper = Paper.parse(data)
paper.flag_1()
# 2
print('\n2.')
paper = Paper.parse(test)
paper.flag_2()
paper = Paper.parse(data)
paper.flag_2()