From eeaf8632c54ba58566b110ad288b6549c529c0ed Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Mon, 6 Dec 2021 10:09:52 -0500 Subject: [PATCH 1/5] Adding day06 part 2 --- puzzles/day06.py | 79 +++++++++++++++++++++++++++++++++++++++++++ puzzles/test_day06.py | 34 +++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 puzzles/day06.py create mode 100644 puzzles/test_day06.py diff --git a/puzzles/day06.py b/puzzles/day06.py new file mode 100644 index 0000000..383181c --- /dev/null +++ b/puzzles/day06.py @@ -0,0 +1,79 @@ +""" +Advent of Code 2021 - day 06 + +Run with: + python puzzles/day06.py inputs/day06.txt +""" + +import pathlib +import sys + +from dataclasses import dataclass +from typing import List, Tuple + + +@dataclass +class LanternFish: + reproduce_timer: int + children: int = 0 + +class FishSchool: + fish = None + + def __init__(self, times: List[int]) -> None: + self.fish = [] + for time in times: + self.fish.append(LanternFish(reproduce_timer=time)) + + def simulate(self, days: int=80) -> None: + for day in range(days): + self._check_school() + + def _check_school(self) -> None: + for index, fish in enumerate(self.fish): + if fish.reproduce_timer == 0: + self.fish.append(LanternFish(reproduce_timer=9)) # Need to correct (should be 8) + self.fish[index].reproduce_timer = 6 + self.fish[index].children += 1 + else: + self.fish[index].reproduce_timer -= 1 + + +def part1(inputs: List[int]) -> int: + school = FishSchool(inputs) + school.simulate(days=80) + return len(school.fish) + + +def part2(inputs: List[int]) -> int: + school = FishSchool(inputs) + school.simulate(days=256) + return len(school.fish) + + +def parse(inputs: str) -> List[int]: + """Parse the input string""" + return [int(value) for value in inputs.split(",")] + + +def solve(path: str) -> Tuple[int, int]: + """Solve the puzzle""" + puzzle_input = parse(pathlib.Path(path).read_text().strip()) + part1_result = part1(puzzle_input) + part2_result = part2(puzzle_input) + + return part1_result, part2_result + + +def main() -> None: + for path in sys.argv[1:]: + print(f"Input File: {path}") + + part1_result, part2_result = solve(path) + + print(f"Part 1 Result: {part1_result}") + print(f"Part 2 Result: {part2_result}") + + +if __name__ == "__main__": + main() diff --git a/puzzles/test_day06.py b/puzzles/test_day06.py new file mode 100644 index 0000000..52ba7ea --- /dev/null +++ b/puzzles/test_day06.py @@ -0,0 +1,34 @@ +import pathlib +import pytest +import day06 as aoc + +INPUTS_DIR = f"{pathlib.Path(__file__).parent.parent}/inputs" + +@pytest.fixture +def example_data(): + input_path = f"{INPUTS_DIR}/day06-example.txt" + return aoc.parse(pathlib.Path(input_path).read_text().strip()) + + +@pytest.fixture +def day06_data(): + input_path = f"{INPUTS_DIR}/day06.txt" + return aoc.parse(pathlib.Path(input_path).read_text().strip()) + + +def test_example1(example_data): + assert aoc.part1(example_data) == 5934 + + +def test_example2(example_data): + assert aoc.part2(example_data) == 26984457539 + + +@pytest.mark.skip(reason="Not implemented") +def test_part1(day06_data): + assert aoc.part1(day06_data) == ... + + +@pytest.mark.skip(reason="Not implemented") +def test_part2(day06_data): + assert aoc.part2(day06_data) == ... -- 2.30.1 From 5c60ea44f009508d7a741b1adb7726dae0d7e3a3 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Mon, 6 Dec 2021 10:10:25 -0500 Subject: [PATCH 2/5] Adding day06 inputs --- inputs/day06-example.txt | 1 + inputs/day06.txt | 1 + 2 files changed, 2 insertions(+) create mode 100644 inputs/day06-example.txt create mode 100644 inputs/day06.txt diff --git a/inputs/day06-example.txt b/inputs/day06-example.txt new file mode 100644 index 0000000..55129f1 --- /dev/null +++ b/inputs/day06-example.txt @@ -0,0 +1 @@ +3,4,3,1,2 diff --git a/inputs/day06.txt b/inputs/day06.txt new file mode 100644 index 0000000..8bed7ab --- /dev/null +++ b/inputs/day06.txt @@ -0,0 +1 @@ +1,3,4,1,5,2,1,1,1,1,5,1,5,1,1,1,1,3,1,1,1,1,1,1,1,2,1,5,1,1,1,1,1,4,4,1,1,4,1,1,2,3,1,5,1,4,1,2,4,1,1,1,1,1,1,1,1,2,5,3,3,5,1,1,1,1,4,1,1,3,1,1,1,2,3,4,1,1,5,1,1,1,1,1,2,1,3,1,3,1,2,5,1,1,1,1,5,1,5,5,1,1,1,1,3,4,4,4,1,5,1,1,4,4,1,1,1,1,3,1,1,1,1,1,1,3,2,1,4,1,1,4,1,5,5,1,2,2,1,5,4,2,1,1,5,1,5,1,3,1,1,1,1,1,4,1,2,1,1,5,1,1,4,1,4,5,3,5,5,1,2,1,1,1,1,1,3,5,1,2,1,2,1,3,1,1,1,1,1,4,5,4,1,3,3,1,1,1,1,1,1,1,1,1,5,1,1,1,5,1,1,4,1,5,2,4,1,1,1,2,1,1,4,4,1,2,1,1,1,1,5,3,1,1,1,1,4,1,4,1,1,1,1,1,1,3,1,1,2,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,5,1,2,1,1,1,1,1,1,1,1,1 -- 2.30.1 From cc507c17a27be1c11c345e9c83a2ff570bcc03e5 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Mon, 6 Dec 2021 18:21:26 -0500 Subject: [PATCH 3/5] Adding day06 part 2 --- puzzles/day06.py | 52 +++++++++++++++++++++---------------------- puzzles/test_day06.py | 6 ++--- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/puzzles/day06.py b/puzzles/day06.py index 383181c..9bbd08e 100644 --- a/puzzles/day06.py +++ b/puzzles/day06.py @@ -8,47 +8,45 @@ Run with: import pathlib import sys -from dataclasses import dataclass +from collections import Counter from typing import List, Tuple -@dataclass -class LanternFish: - reproduce_timer: int - children: int = 0 - -class FishSchool: - fish = None +class Reproduce: + times = None def __init__(self, times: List[int]) -> None: - self.fish = [] - for time in times: - self.fish.append(LanternFish(reproduce_timer=time)) + self.times = times - def simulate(self, days: int=80) -> None: + def start(self, days: int=80) -> None: + counts = Counter(self.times) for day in range(days): - self._check_school() + next_counts = Counter() # Can't modify while iterating + + for count_key, count in counts.items(): + if count_key == 0: + next_counts[6] += count # Move the parents back to 6 days + next_counts[8] += count # Add the new fish + else: + next_counts[count_key - 1] += count # Move count to next day count + + counts = next_counts + self.time_counts = counts - def _check_school(self) -> None: - for index, fish in enumerate(self.fish): - if fish.reproduce_timer == 0: - self.fish.append(LanternFish(reproduce_timer=9)) # Need to correct (should be 8) - self.fish[index].reproduce_timer = 6 - self.fish[index].children += 1 - else: - self.fish[index].reproduce_timer -= 1 + def count_fish(self): + return sum(self.time_counts.values()) def part1(inputs: List[int]) -> int: - school = FishSchool(inputs) - school.simulate(days=80) - return len(school.fish) + school = Reproduce(inputs) + school.start(days=80) + return school.count_fish() def part2(inputs: List[int]) -> int: - school = FishSchool(inputs) - school.simulate(days=256) - return len(school.fish) + school = Reproduce(inputs) + school.start(days=256) + return school.count_fish() def parse(inputs: str) -> List[int]: diff --git a/puzzles/test_day06.py b/puzzles/test_day06.py index 52ba7ea..e2a3250 100644 --- a/puzzles/test_day06.py +++ b/puzzles/test_day06.py @@ -24,11 +24,9 @@ def test_example2(example_data): assert aoc.part2(example_data) == 26984457539 -@pytest.mark.skip(reason="Not implemented") def test_part1(day06_data): - assert aoc.part1(day06_data) == ... + assert aoc.part1(day06_data) == 386755 -@pytest.mark.skip(reason="Not implemented") def test_part2(day06_data): - assert aoc.part2(day06_data) == ... + assert aoc.part2(day06_data) == 1732731810807 -- 2.30.1 From 9bb3b71da3c78fe28541b8d03515763b6f358c95 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Mon, 6 Dec 2021 18:23:22 -0500 Subject: [PATCH 4/5] Correcting type hints and black reformatting --- puzzles/day06.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/puzzles/day06.py b/puzzles/day06.py index 9bbd08e..62eccef 100644 --- a/puzzles/day06.py +++ b/puzzles/day06.py @@ -18,22 +18,22 @@ class Reproduce: def __init__(self, times: List[int]) -> None: self.times = times - def start(self, days: int=80) -> None: + def start(self, days: int = 80) -> None: counts = Counter(self.times) for day in range(days): - next_counts = Counter() # Can't modify while iterating + next_counts = Counter() # Can't modify while iterating for count_key, count in counts.items(): if count_key == 0: - next_counts[6] += count # Move the parents back to 6 days - next_counts[8] += count # Add the new fish + next_counts[6] += count # Move the parents back to 6 days + next_counts[8] += count # Add the new fish else: - next_counts[count_key - 1] += count # Move count to next day count + next_counts[count_key - 1] += count # Move count to next day count counts = next_counts self.time_counts = counts - def count_fish(self): + def count_fish(self) -> int: return sum(self.time_counts.values()) -- 2.30.1 From 90ef6af6e2b73be0c482a39af4f10a327539030b Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Mon, 6 Dec 2021 18:34:08 -0500 Subject: [PATCH 5/5] Cleanup --- puzzles/day06.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/puzzles/day06.py b/puzzles/day06.py index 62eccef..85c9fe0 100644 --- a/puzzles/day06.py +++ b/puzzles/day06.py @@ -20,13 +20,13 @@ class Reproduce: def start(self, days: int = 80) -> None: counts = Counter(self.times) - for day in range(days): + for _ in range(days): next_counts = Counter() # Can't modify while iterating for count_key, count in counts.items(): if count_key == 0: - next_counts[6] += count # Move the parents back to 6 days next_counts[8] += count # Add the new fish + next_counts[6] += count # Move the parents back to 6 days else: next_counts[count_key - 1] += count # Move count to next day count -- 2.30.1