Skip to content

Commit 0a02cc1

Browse files
committed
Added solutions for day 24
1 parent 5c88bf1 commit 0a02cc1

File tree

3 files changed

+202
-1
lines changed

3 files changed

+202
-1
lines changed

advent2020/day24.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# MIT License
2+
#
3+
# Copyright (c) 2021 Andrew Krepps
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in all
13+
# copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
# SOFTWARE.
22+
23+
24+
from enum import Enum
25+
26+
from . import util
27+
28+
29+
class Direction(Enum):
30+
EAST = 0
31+
WEST = 1
32+
NORTHEAST = 2
33+
NORTHWEST = 3
34+
SOUTHEAST = 4
35+
SOUTHWEST = 5
36+
37+
def get_movement_amount(self):
38+
if self == Direction.EAST:
39+
return 2, 0
40+
elif self == Direction.WEST:
41+
return -2, 0
42+
elif self == Direction.NORTHEAST:
43+
return 1, 1
44+
elif self == Direction.NORTHWEST:
45+
return -1, 1
46+
elif self == Direction.SOUTHEAST:
47+
return 1, -1
48+
elif self == Direction.SOUTHWEST:
49+
return -1, -1
50+
else:
51+
raise ValueError(f"Unknown direction {self}")
52+
53+
54+
def extract_directions(line):
55+
idx = 0
56+
directions = []
57+
while idx < len(line):
58+
c = line[idx]
59+
idx += 1
60+
if c == 'e':
61+
directions.append(Direction.EAST)
62+
elif c == 'w':
63+
directions.append(Direction.WEST)
64+
else:
65+
c2 = line[idx]
66+
idx += 1
67+
if c == 'n':
68+
if c2 == 'e':
69+
directions.append(Direction.NORTHEAST)
70+
elif c2 == 'w':
71+
directions.append(Direction.NORTHWEST)
72+
elif c == 's':
73+
if c2 == 'e':
74+
directions.append(Direction.SOUTHEAST)
75+
elif c2 == 'w':
76+
directions.append(Direction.SOUTHWEST)
77+
return directions
78+
79+
80+
def parse_input(lines):
81+
return [extract_directions(line) for line in lines]
82+
83+
84+
def move_coordinates(coordinates, direction):
85+
move_x, move_y = direction.get_movement_amount()
86+
return coordinates[0] + move_x, coordinates[1] + move_y
87+
88+
89+
def initialize_tiles(direction_sets):
90+
flipped_tiles = set()
91+
for directions in direction_sets:
92+
current_tile = (0, 0)
93+
for direction in directions:
94+
current_tile = move_coordinates(current_tile, direction)
95+
if current_tile in flipped_tiles:
96+
flipped_tiles.remove(current_tile)
97+
else:
98+
flipped_tiles.add(current_tile)
99+
return flipped_tiles
100+
101+
102+
def get_next_tile_set(flipped_tiles):
103+
flipped_neighbor_counts = {tile: 0 for tile in flipped_tiles}
104+
for tile in flipped_tiles:
105+
for direction in Direction:
106+
neighbor = move_coordinates(tile, direction)
107+
if neighbor not in flipped_neighbor_counts.keys():
108+
flipped_neighbor_counts[neighbor] = 1
109+
else:
110+
flipped_neighbor_counts[neighbor] += 1
111+
112+
next_flipped_tiles = set()
113+
for tile, flipped_neighbors in flipped_neighbor_counts.items():
114+
if tile in flipped_tiles and not (flipped_neighbors == 0 or flipped_neighbors > 2):
115+
next_flipped_tiles.add(tile)
116+
elif tile not in flipped_tiles and flipped_neighbors == 2:
117+
next_flipped_tiles.add(tile)
118+
return next_flipped_tiles
119+
120+
121+
def get_part1_answer(flipped_tiles):
122+
return len(flipped_tiles)
123+
124+
125+
def get_part2_answer(flipped_tiles):
126+
for day in range(100):
127+
flipped_tiles = get_next_tile_set(flipped_tiles)
128+
return len(flipped_tiles)
129+
130+
131+
def run():
132+
lines = util.get_input_file_lines("day24.txt")
133+
directions_sets = parse_input(lines)
134+
flipped_tiles = initialize_tiles(directions_sets)
135+
print(f"The answer to part 1 is {get_part1_answer(flipped_tiles)}")
136+
print(f"The answer to part 2 is {get_part2_answer(flipped_tiles)}")

main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
from advent2020 import day21
4747
from advent2020 import day22
4848
from advent2020 import day23
49+
from advent2020 import day24
4950

5051

5152
day_runners = [
@@ -71,7 +72,8 @@
7172
lambda: day20.run(),
7273
lambda: day21.run(),
7374
lambda: day22.run(),
74-
lambda: day23.run()
75+
lambda: day23.run(),
76+
lambda: day24.run()
7577
]
7678

7779

test/test_day24.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# MIT License
2+
#
3+
# Copyright (c) 2021 Andrew Krepps
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in all
13+
# copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
# SOFTWARE.
22+
23+
24+
import unittest
25+
26+
from advent2020.day24 import get_part1_answer
27+
from advent2020.day24 import get_part2_answer
28+
from advent2020.day24 import initialize_tiles
29+
from advent2020.day24 import parse_input
30+
from advent2020.util import get_input_data_lines
31+
32+
33+
data = """
34+
sesenwnenenewseeswwswswwnenewsewsw
35+
neeenesenwnwwswnenewnwwsewnenwseswesw
36+
seswneswswsenwwnwse
37+
nwnwneseeswswnenewneswwnewseswneseene
38+
swweswneswnenwsewnwneneseenw
39+
eesenwseswswnenwswnwnwsewwnwsene
40+
sewnenenenesenwsewnenwwwse
41+
wenwwweseeeweswwwnwwe
42+
wsweesenenewnwwnwsenewsenwwsesesenwne
43+
neeswseenwwswnwswswnw
44+
nenwswwsewswnenenewsenwsenwnesesenew
45+
enewnwewneswsewnwswenweswnenwsenwsw
46+
sweneswneswneneenwnewenewwneswswnese
47+
swwesenesewenwneswnwwneseswwne
48+
enesenwswwswneneswsenwnewswseenwsese
49+
wnwnesenesenenwwnenwsewesewsesesew
50+
nenewswnwewswnenesenwnesewesw
51+
eneswnwswnwsenenwnwnwwseeswneewsenese
52+
neswnwewnwnwseenwseesewsenwsweewe
53+
wseweeenwnesenwwwswnew
54+
"""
55+
56+
57+
class Day24Test(unittest.TestCase):
58+
def test_day24(self):
59+
lines = get_input_data_lines(data)
60+
directions_sets = parse_input(lines)
61+
flipped_tiles = initialize_tiles(directions_sets)
62+
self.assertEqual(get_part1_answer(flipped_tiles), 10)
63+
self.assertEqual(get_part2_answer(flipped_tiles), 2208)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy