-
Notifications
You must be signed in to change notification settings - Fork 0
/
day24.py
114 lines (91 loc) · 3.19 KB
/
day24.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
110
111
112
113
114
# vi: set shiftwidth=4 tabstop=4 expandtab:
import datetime
import os
import collections
top_dir = os.path.dirname(os.path.abspath(__file__)) + "/../../"
def get_directions_from_file(file_path=top_dir + "resources/year2020_day24_input.txt"):
with open(file_path) as f:
return [l.strip() for l in f]
def sum_elementwise(it1, it2):
return tuple(sum(x) for x in zip(it1, it2))
# https://www.redblobgames.com/grids/hexagons/#coordinates
DIRECTIONS = {
"e": (1, 0),
"w": (-1, 0),
"se": (1, 1),
"sw": (0, 1),
"ne": (0, -1),
"nw": (-1, -1),
}
assert DIRECTIONS["nw"] == tuple(sum_elementwise(DIRECTIONS["ne"], DIRECTIONS["w"]))
assert DIRECTIONS["ne"] == tuple(sum_elementwise(DIRECTIONS["nw"], DIRECTIONS["e"]))
assert DIRECTIONS["sw"] == tuple(sum_elementwise(DIRECTIONS["se"], DIRECTIONS["w"]))
assert DIRECTIONS["se"] == tuple(sum_elementwise(DIRECTIONS["sw"], DIRECTIONS["e"]))
def get_tile_from_direction_string(s):
dirs = list()
prev = ""
for c in s:
pair = prev + c
direct = DIRECTIONS.get(pair, None)
if direct is not None:
dirs.append(direct)
prev = ""
else:
prev = c
assert prev == ""
return tuple(sum(x) for x in zip(*dirs))
def get_tiles_flipped(strings):
c = collections.Counter(get_tile_from_direction_string(s) for s in strings)
return set(tile for tile, count in c.items() if count % 2)
def one_day(tiles):
c = collections.Counter(
sum_elementwise(t, n) for t in tiles for n in DIRECTIONS.values()
)
return set(
tile
for tile, count in c.items()
if count in ((1, 2) if tile in tiles else (2,))
)
def n_days(tiles, n):
for _ in range(n):
tiles = one_day(tiles)
return len(tiles)
def run_tests():
assert get_tile_from_direction_string("esew") == (1, 1)
assert get_tile_from_direction_string("nwwswee") == (0, 0)
example1 = [
"sesenwnenenewseeswwswswwnenewsewsw",
"neeenesenwnwwswnenewnwwsewnenwseswesw",
"seswneswswsenwwnwse",
"nwnwneseeswswnenewneswwnewseswneseene",
"swweswneswnenwsewnwneneseenw",
"eesenwseswswnenwswnwnwsewwnwsene",
"sewnenenenesenwsewnenwwwse",
"wenwwweseeeweswwwnwwe",
"wsweesenenewnwwnwsenewsenwwsesesenwne",
"neeswseenwwswnwswswnw",
"nenwswwsewswnenenewsenwsenwnesesenew",
"enewnwewneswsewnwswenweswnenwsenwsw",
"sweneswneswneneenwnewenewwneswswnese",
"swwesenesewenwneswnwwneseswwne",
"enesenwswwswneneswsenwnewswseenwsese",
"wnwnesenesenenwwnenwsewesewsesesew",
"nenewswnwewswnenesenwnesewesw",
"eneswnwswnwsenenwnwnwwseeswneewsenese",
"neswnwewnwnwseenwseesewsenwsweewe",
"wseweeenwnesenwwwswnew",
]
tiles = get_tiles_flipped(example1)
assert len(tiles) == 10
assert n_days(tiles, 100) == 2208
def get_solutions():
directions = get_directions_from_file()
tiles = get_tiles_flipped(directions)
print(len(tiles) == 282)
print(n_days(tiles, 100) == 3445)
if __name__ == "__main__":
begin = datetime.datetime.now()
run_tests()
get_solutions()
end = datetime.datetime.now()
print(end - begin)