Skip to content

Commit a88ce05

Browse files
committed
⭐⭐ Merry Christmas
1 parent 7221b73 commit a88ce05

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed

2020/day24.py

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from util import Day
2+
from aocd import submit
3+
from collections import Counter
4+
5+
# east, southeast, southwest, west, northwest, and northeast
6+
# e, se, sw, w, nw, and ne
7+
# pointy hex
8+
9+
10+
def preprocess(row):
11+
return row.replace("", " ").strip().replace("n ", "n").replace("s ", "s").split(" ")
12+
13+
directions = {
14+
"ne": 1 + 0.5j,
15+
"e": 1j,
16+
"se": -1 + 0.5j,
17+
"sw": -1 - 0.5j,
18+
"w": -1j,
19+
"nw": 1 - 0.5j,
20+
}
21+
22+
23+
def flip(row):
24+
return sum((directions[char] for char in row))
25+
26+
27+
def get_neighbours(tile):
28+
return [tile + val for val in directions.values()]
29+
30+
31+
def möve(state):
32+
new_state = set()
33+
34+
around = Counter()
35+
for tile in state:
36+
neighbours = get_neighbours(tile)
37+
count = 0
38+
for n in neighbours:
39+
if n in state:
40+
count += 1 # neighbour black of this black tile
41+
else:
42+
around[n] += 1 # counts up one for the neighbouring tiles if white
43+
# Any black tile with zero or more than 2 black tiles immediately adjacent to it is flipped to white.
44+
if 0 < count < 3:
45+
new_state.add(tile)
46+
47+
# Any white tile with exactly 2 black tiles immediately adjacent to it is flipped to black.
48+
for k, v in around.items():
49+
if v == 2:
50+
new_state.add(k)
51+
52+
return new_state
53+
54+
55+
def hex_of_lyfe(state, moves):
56+
for i in range(moves):
57+
state = möve(state)
58+
print(f"Move {i+1}: {len(state)}")
59+
return len(state)
60+
61+
62+
def main(day, part=1):
63+
day.apply(preprocess)
64+
day.apply(flip)
65+
count = Counter(day.data)
66+
if part == 1:
67+
out = sum((1 for _, v in count.items() if (v % 2)))
68+
if part == 2:
69+
start = set((k for k, v in count.items() if (v % 2)))
70+
out = hex_of_lyfe(start, 100)
71+
return out
72+
73+
74+
if __name__ == "__main__":
75+
day = Day(24)
76+
day.download()
77+
78+
day.load(typing=str)
79+
p1 = main(day)
80+
print(p1)
81+
submit(p1, part="a", day=24, year=2020)
82+
83+
day.load(typing=str)
84+
p2 = main(day, part=2)
85+
print(p2)
86+
submit(p2, part="b", day=24, year=2020)

2020/tests/test_day24.py

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import sys
2+
import pytest
3+
4+
sys.path.insert(0, ".")
5+
from util import Day
6+
from day24 import *
7+
8+
@pytest.fixture(scope="function")
9+
def example():
10+
day = Day(24)
11+
data = """sesenwnenenewseeswwswswwnenewsewsw
12+
neeenesenwnwwswnenewnwwsewnenwseswesw
13+
seswneswswsenwwnwse
14+
nwnwneseeswswnenewneswwnewseswneseene
15+
swweswneswnenwsewnwneneseenw
16+
eesenwseswswnenwswnwnwsewwnwsene
17+
sewnenenenesenwsewnenwwwse
18+
wenwwweseeeweswwwnwwe
19+
wsweesenenewnwwnwsenewsenwwsesesenwne
20+
neeswseenwwswnwswswnw
21+
nenwswwsewswnenenewsenwsenwnesesenew
22+
enewnwewneswsewnwswenweswnenwsenwsw
23+
sweneswneswneneenwnewenewwneswswnese
24+
swwesenesewenwneswnwwneseswwne
25+
enesenwswwswneneswsenwnewswseenwsese
26+
wnwnesenesenenwwnenwsewesewsesesew
27+
nenewswnwewswnenesenwnesewesw
28+
eneswnwswnwsenenwnwnwwseeswneewsenese
29+
neswnwewnwnwseenwseesewsenwsweewe
30+
wseweeenwnesenwwwswnew"""
31+
32+
day.load(data, typing=str)
33+
return day
34+
35+
@pytest.fixture(scope="function")
36+
def day():
37+
day = Day(24)
38+
day.load(typing=str)
39+
return day
40+
41+
def test_example(example):
42+
assert main(example, part=1) == 10
43+
44+
def test_example_p2(example):
45+
assert main(example, part=2) == 2208
46+
47+
def test_part1(day):
48+
assert main(day, part=1) == 326
49+
50+
def test_part2(day):
51+
assert main(day, part=2) == 3979

0 commit comments

Comments
 (0)