-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday20.py
More file actions
115 lines (95 loc) · 3.19 KB
/
Copy pathday20.py
File metadata and controls
115 lines (95 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
from __future__ import annotations
from dataclasses import dataclass
from rich.console import Console
from typing import List, Tuple, Dict
@dataclass(order=True, frozen=True)
class Coords:
x: int
y: int
def __repr__(self) -> str:
return f"<{self.x},{self.y}>"
def get_neighbours_in_order(self) -> List[Coords]:
return [
Coords(self.x - 1, self.y - 1),
Coords(self.x, self.y - 1),
Coords(self.x + 1, self.y - 1),
Coords(self.x - 1, self.y),
Coords(self.x, self.y),
Coords(self.x + 1, self.y),
Coords(self.x - 1, self.y + 1),
Coords(self.x, self.y + 1),
Coords(self.x + 1, self.y + 1),
]
def read_input(lines: List[str]) -> Tuple[str, Dict[Coords, int], Coords, Coords]:
mapping = lines.pop(0)
lines.pop(0)
image = {}
maxX = 0
for yIndex, line in enumerate(lines):
for xIndex, item in enumerate(line):
if item == "#":
image[Coords(xIndex, yIndex)] = 1
maxX = max(maxX, xIndex)
return mapping, image, Coords(0, 0), Coords(maxX, yIndex)
def output_coords(coords: Dict[Coords, int], min_val: Coords, max_val: Coords):
for y in range(min_val.y, max_val.y + 1):
for x in range(min_val.x, max_val.x + 1):
char = "#" if Coords(x, y) in coords else "."
console.print(f"{char}", end="")
console.print()
console.print()
def isPixelLit(
pixel: Coords,
mapping: str,
image: Dict[Coords, int],
minCoord: Coords,
maxCoord: Coords,
iteration: int,
) -> bool:
num = 0
for neighbour in pixel.get_neighbours_in_order():
num <<= 1
if image.get(neighbour) is not None:
num |= 1
elif mapping[0] == "#":
if iteration % 2 == 0 and (
neighbour.x < minCoord.x
or neighbour.y < minCoord.y
or neighbour.x > maxCoord.x
or neighbour.y > maxCoord.y
):
num |= 1
return mapping[num] == "#"
def enhance(
mapping: str,
image: Dict[Coords, int],
origin_min: Coords,
origin_max: Coords,
iteration: int,
) -> Tuple[Dict[Coords, int], Coords, Coords]:
new_image = {}
minX = 1
maxX = 0
minY = 1
maxY = 0
for y in range(origin_min.y - 1, origin_max.y + 2):
for x in range(origin_min.x - 1, origin_max.x + 2):
loc = Coords(x, y)
if isPixelLit(loc, mapping, image, origin_min, origin_max, iteration):
new_image[loc] = 1
minX = min(minX, x)
minY = min(minY, y)
maxX = max(maxX, x)
maxY = max(maxY, y)
return new_image, Coords(minX, minY), Coords(maxX, maxY)
console = Console()
with open("day20.txt", "r") as file:
mapping, image, minCoords, maxCoords = read_input(file.readlines())
console.print("[b yellow]Day 20[/b yellow]")
for iteration in range(1, 51):
image, minCoords, maxCoords = enhance(
mapping, image, minCoords, maxCoords, iteration
)
if iteration == 2:
console.print(len(image))
console.print(len(image))