Skip to content

Commit

Permalink
Day 14
Browse files Browse the repository at this point in the history
  • Loading branch information
GeertLitjens committed Dec 14, 2023
1 parent f49e6d0 commit 88e2d7a
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/advent_of_code_2023/days/day14/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### Part 1
<PART_1_TEXT>

### Part 2
<PART_2_TEXT>
Empty file.
71 changes: 71 additions & 0 deletions src/advent_of_code_2023/days/day14/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""
"""

from advent_of_code_2023.utils import Solution


class DaySolution(Solution):
def __init__(self: "DaySolution", day: int = 14, year: int = 2023) -> None:
super().__init__(day, year)

def _parse_data(self: "DaySolution", input_data: str) -> list[list[str]]:
""" """
return [[x for x in line] for line in input_data.splitlines()]

def rotate(
self: "DaySolution", mirrors: list[list[str]], dir: int = 1
) -> list[list[str]]:
if dir == 1:
return [list(x) for x in zip(*mirrors[::-1], strict=True)]
else:
return [list(x) for x in zip(*mirrors, strict=True)][::-1]

def tilt_mirrors(self: "DaySolution", mirrors: list[list[str]]) -> list[list[str]]:
tilted_mirrors = []
for col in mirrors:
tilted_pieces = [
"O" * piece.count("O") + "." * (len(piece) - piece.count("O"))
for piece in "".join(col).split("#")
]
tilted_mirrors.append([x for x in "#".join(tilted_pieces)])
return tilted_mirrors

def _solve_part1(self: "DaySolution", parsed_data: list[list[str]]) -> str:
""" """
mirrors: list[list[str]] = self.rotate(parsed_data)
tilted_mirrors = self.tilt_mirrors(mirrors)
tilted_mirrors = self.rotate(tilted_mirrors)
return str(
sum(["".join(x).count("O") * (i + 1) for i, x in enumerate(tilted_mirrors)])
)

def _solve_part2(self: "DaySolution", parsed_data: list[list[str]]) -> str:
""" """
cache: dict[str, int] = {}
scores = []
mirrors = self.rotate(parsed_data, -1)
for cycle in range(1_000_000_000):
for _ in range(4):
mirrors = self.tilt_mirrors(mirrors)
mirrors = self.rotate(mirrors)

mirrors = self.rotate(mirrors)
str_mirrors = "\n".join(["".join(line) for line in mirrors])
scores.append(
sum(
[
"".join(x).count("O") * (len(mirrors) - i)
for i, x in enumerate(mirrors)
]
)
)
mirrors = self.rotate(mirrors, -1)

if str_mirrors in cache:
prev_cycle = cache[str_mirrors]
cycle_length = cycle - prev_cycle
req_cycle = prev_cycle + (1_000_000_000 - prev_cycle) % cycle_length - 1
return str(scores[req_cycle])
else:
cache[str_mirrors] = cycle
return "0"
33 changes: 33 additions & 0 deletions tests/test_day14.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import pytest

from advent_of_code_2023.days.day14.solution import DaySolution # type: ignore


@pytest.fixture
def day_testdata() -> str:
return """\
O....#....
O.OO#....#
.....##...
OO.#O....O
.O.....O#.
O.#..O.#.#
..O..#O..O
.......O..
#....###..
#OO..#....\
"""


def test_part1(day_testdata: str) -> None:
sol = DaySolution()
parsed_data = sol._parse_data(day_testdata)
result = sol._solve_part1(parsed_data)
assert result == "136"


def test_part2(day_testdata: str) -> None:
sol = DaySolution()
parsed_data = sol._parse_data(day_testdata)
result = sol._solve_part2(parsed_data)
assert result == "64"

0 comments on commit 88e2d7a

Please sign in to comment.