-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday20.py
109 lines (86 loc) · 2.76 KB
/
day20.py
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
"""Solution for Advent of Code day 20."""
from pathlib import Path
import doctest
import click
def read_input(filename: Path) -> tuple[str, set[int, int]]:
"""read the input from the scanners.
Args:
filename (Path): filename
Returns:
str : rules
set[int,int]: input image
"""
with filename.open("r") as file:
data = file.read().strip()
rule, start = data.split("\n\n")
rule = rule.strip()
input_image = set()
for row, line in enumerate(start.strip().split("\n")):
for col, x in enumerate(line.strip()):
if x == "#":
input_image.add((row, col))
return rule, input_image
def apply_image_enhancement(image: set[int, int], on: bool, rule: str) -> set[int, int]:
"""Applies the image enhancement to the image.
Args:
image (set[int,int]): input image
on (bool): Flag that indicates if the pixel in image indecates on or off
rule(str): image engancement rules
Returns:
set[int,int] processed image
"""
result = set()
row_low = min([row for row, _ in image])
row_high = max([row for row, _ in image])
col_low = min([col for _, col in image])
col_high = max([col for _, col in image])
for row in range(row_low - 5, row_high + 10):
for col in range(col_low - 5, col_high + 10):
row_col_str = 0
bit = 8
for delta_row in [-1, 0, 1]:
for delta_col in [-1, 0, 1]:
if ((row + delta_row, col + delta_col) in image) == on:
row_col_str += 2 ** bit
bit -= 1
assert 0 <= row_col_str < 512
if (rule[row_col_str] == "#") != on:
result.add((row, col))
return result
@click.group()
def main():
"""CLI for the solution of day 20
Advent of code 2021 (https://adventofcode.com/2021/day/20)
"""
@main.command()
@click.argument(
"filename",
required=False,
type=Path,
default=Path("test_data/day_20.data"),
)
def part_1(filename: Path):
"""Part one of day 20. (2 runs)"""
rule, image = read_input(filename)
for i in range(2):
image = apply_image_enhancement(image, i % 2 == 0, rule)
print(f"{len(image)} pixels are lit after 2 rounds")
@main.command()
@click.argument(
"filename",
required=False,
type=Path,
default=Path("test_data/day_20.data"),
)
def part_2(filename: Path):
"""Part two of day 20. (50 runs)"""
rule, image = read_input(filename)
for i in range(50):
image = apply_image_enhancement(image, i % 2 == 0, rule)
print(f"{len(image)} pixels are lit after 50 rounds")
@main.command()
def test():
"""run doctest."""
print(doctest.testmod())
if __name__ == "__main__":
main()