summaryrefslogtreecommitdiff
path: root/23_2022.py
blob: d5625ba4e85b57168020fdf880bab20e68897c01 (plain)
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
import sys
from collections import defaultdict

infile = sys.argv[1] if len(sys.argv) > 1 else "data/23_2022.txt"
data = open(infile).read()
lines = [x for x in data.split("\n")]
dir_list = ["N", "S", "W", "E"]
E = set()
G = lines
for r, row in enumerate(G):
    for c, ch in enumerate(row):
        if ch == "#":
            E.add((r, c))


def show(E):
    r1 = min(r for (r, c) in E)
    r2 = max(r for (r, c) in E)
    c1 = min(c for (r, c) in E)
    c2 = max(c for (r, c) in E)
    for r in range(r1, r2 + 1):
        row = ""
        for c in range(c1, c2 + 1):
            row += "#" if (r, c) in E else "."
        print(row)
    print("=" * 80)


for t in range(10000):
    any_moved = False
    P = defaultdict(list)
    for r, c in E:
        has_nbr = False
        for dr in [-1, 0, 1]:
            for dc in [-1, 0, 1]:
                if (dr != 0 or dc != 0) and (r + dr, c + dc) in E:
                    has_nbr = True
        if not has_nbr:
            continue
        moved = False
        for dir_ in dir_list:
            if (
                dir_ == "N"
                and (not moved)
                and (r - 1, c) not in E
                and (r - 1, c - 1) not in E
                and (r - 1, c + 1) not in E
            ):
                P[(r - 1, c)].append((r, c))
                moved = True
            elif (
                dir_ == "S"
                and (not moved)
                and (r + 1, c) not in E
                and (r + 1, c - 1) not in E
                and (r + 1, c + 1) not in E
            ):
                P[(r + 1, c)].append((r, c))
                moved = True
            elif (
                dir_ == "W"
                and (not moved)
                and (r, c - 1) not in E
                and (r - 1, c - 1) not in E
                and (r + 1, c - 1) not in E
            ):
                P[(r, c - 1)].append((r, c))
                moved = True
            elif (
                dir_ == "E"
                and (not moved)
                and (r, c + 1) not in E
                and (r - 1, c + 1) not in E
                and (r + 1, c + 1) not in E
            ):
                P[(r, c + 1)].append((r, c))
                moved = True
    dir_list = dir_list[1:] + [dir_list[0]]
    for k, vs in P.items():
        if len(vs) == 1:
            any_moved = True
            E.discard(vs[0])
            E.add(k)
    if not any_moved:
        print(t + 1)
        break
    if t == 9:
        r1 = min(r for (r, c) in E)
        r2 = max(r for (r, c) in E)
        c1 = min(c for (r, c) in E)
        c2 = max(c for (r, c) in E)
        ans = 0
        for r in range(r1, r2 + 1):
            for c in range(c1, c2 + 1):
                if (r, c) not in E:
                    ans += 1
        print(ans)