diff --git a/2021/06/README.md b/2021/06/README.md new file mode 100644 index 0000000..b94d0f9 --- /dev/null +++ b/2021/06/README.md @@ -0,0 +1,69 @@ +# 2021 Day 06: Lanternfish +Copyright (c) Eric Wastl +#### [Direct Link](https://adventofcode.com/2021/day/06) + +## Part 1 + +The sea floor is getting steeper. Maybe the sleigh keys got carried this way? + +A massive school of glowing [lanternfish](https://en.wikipedia.org/wiki/Lanternfish) swims past. They must spawn quickly to reach such large numbers - maybe **exponentially** quickly? You should model their growth rate to be sure. + +Although you know nothing about this specific species of lanternfish, you make some guesses about their attributes. Surely, each lanternfish creates a new lanternfish once every **7** days. + +However, this process isn't necessarily synchronized between every lanternfish - one lanternfish might have 2 days left until it creates another lanternfish, while another might have 4. So, you can model each fish as a single number that represents **the number of days until it creates a new lanternfish.** + +Furthermore, you reason, a **new** lanternfish would surely need slightly longer before it's capable of producing more lanternfish: two more days for its first cycle. + +So, suppose you have a lanternfish with an internal timer value of `3`: + +- After one day, its internal timer would become `2`. +- After another day, its internal timer would become `1`. +- After another day, its internal timer would become `0`. +- After another day, its internal timer would reset to `6`, and it would create a **new** lanternfish with an internal timer of `8`. +- After another day, the first lanternfish would have an internal timer of `5`, and the second lanternfish would have an internal timer of `7`. + +A lanternfish that creates a new fish resets its timer to `6`, **not `7`** (because `0` is included as a valid timer value). The new lanternfish starts with an internal timer of `8` and does not start counting down until the next day. + +Realizing what you're trying to do, the submarine automatically produces a list of the ages of several hundred nearby lanternfish (your puzzle input). For example, suppose you were given the following list: + +``` +3,4,3,1,2 +``` + +This list means that the first fish has an internal timer of `3`, the second fish has an internal timer of `4`, and so on until the fifth fish, which has an internal timer of `2`. Simulating these fish over several days would proceed as follows: + +``` +Initial state: 3,4,3,1,2 +After 1 day: 2,3,2,0,1 +After 2 days: 1,2,1,6,0,8 +After 3 days: 0,1,0,5,6,7,8 +After 4 days: 6,0,6,4,5,6,7,8,8 +After 5 days: 5,6,5,3,4,5,6,7,7,8 +After 6 days: 4,5,4,2,3,4,5,6,6,7 +After 7 days: 3,4,3,1,2,3,4,5,5,6 +After 8 days: 2,3,2,0,1,2,3,4,4,5 +After 9 days: 1,2,1,6,0,1,2,3,3,4,8 +After 10 days: 0,1,0,5,6,0,1,2,2,3,7,8 +After 11 days: 6,0,6,4,5,6,0,1,1,2,6,7,8,8,8 +After 12 days: 5,6,5,3,4,5,6,0,0,1,5,6,7,7,7,8,8 +After 13 days: 4,5,4,2,3,4,5,6,6,0,4,5,6,6,6,7,7,8,8 +After 14 days: 3,4,3,1,2,3,4,5,5,6,3,4,5,5,5,6,6,7,7,8 +After 15 days: 2,3,2,0,1,2,3,4,4,5,2,3,4,4,4,5,5,6,6,7 +After 16 days: 1,2,1,6,0,1,2,3,3,4,1,2,3,3,3,4,4,5,5,6,8 +After 17 days: 0,1,0,5,6,0,1,2,2,3,0,1,2,2,2,3,3,4,4,5,7,8 +After 18 days: 6,0,6,4,5,6,0,1,1,2,6,0,1,1,1,2,2,3,3,4,6,7,8,8,8,8 +``` + +Each day, a `0` becomes a `6` and adds a new `8` to the end of the list, while each other number decreases by 1 if it was present at the start of the day. + +In this example, after 18 days, there are a total of `26` fish. After 80 days, there would be a total of **`5934`**. + +Find a way to simulate lanternfish. **How many lanternfish would there be after 80 days?** + +## Part 2 + +Suppose the lanternfish live forever and have unlimited food and space. Would they take over the entire ocean? + +After 256 days in the example above, there would be a total of **`26984457539`** lanternfish! + +**How many lanternfish would there be after 256 days?** \ No newline at end of file diff --git a/2021/06/code.py b/2021/06/code.py new file mode 100644 index 0000000..b44434e --- /dev/null +++ b/2021/06/code.py @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: MIT +# Copyright (c) 2021 Akumatic +# +# https://adventofcode.com/2021/day/06 + +def read_file(filename: str = "input.txt") -> list: + with open(f"{__file__.rstrip('code.py')}{filename}", "r") as f: + return [int(x) for x in f.read().strip().split(",")] + +def part1(vals: list, days: int = 80) -> int: + fishes = vals[:] + for _ in range(days): + for i in range(len(fishes)): + if fishes[i] == 0: + fishes[i] = 6 + fishes.append(8) + else: + fishes[i] -= 1 + return len(fishes) + +def part2(vals: list, days: int = 256) -> int: + fishes = [vals.count(x) for x in range(9)] + for _ in range(days): + tmp = fishes[0] + fishes = fishes[1:] + [tmp] + fishes[6] += tmp + return sum(fishes) + +if __name__ == "__main__": + vals = read_file() + print(f"Part 1: {part1(vals)}") + print(f"Part 2: {part2(vals)}") \ No newline at end of file diff --git a/2021/06/input.txt b/2021/06/input.txt new file mode 100644 index 0000000..a2ca78e --- /dev/null +++ b/2021/06/input.txt @@ -0,0 +1 @@ +1,1,3,5,3,1,1,4,1,1,5,2,4,3,1,1,3,1,1,5,5,1,3,2,5,4,1,1,5,1,4,2,1,4,2,1,4,4,1,5,1,4,4,1,1,5,1,5,1,5,1,1,1,5,1,2,5,1,1,3,2,2,2,1,4,1,1,2,4,1,3,1,2,1,3,5,2,3,5,1,1,4,3,3,5,1,5,3,1,2,3,4,1,1,5,4,1,3,4,4,1,2,4,4,1,1,3,5,3,1,2,2,5,1,4,1,3,3,3,3,1,1,2,1,5,3,4,5,1,5,2,5,3,2,1,4,2,1,1,1,4,1,2,1,2,2,4,5,5,5,4,1,4,1,4,2,3,2,3,1,1,2,3,1,1,1,5,2,2,5,3,1,4,1,2,1,1,5,3,1,4,5,1,4,2,1,1,5,1,5,4,1,5,5,2,3,1,3,5,1,1,1,1,3,1,1,4,1,5,2,1,1,3,5,1,1,4,2,1,2,5,2,5,1,1,1,2,3,5,5,1,4,3,2,2,3,2,1,1,4,1,3,5,2,3,1,1,5,1,3,5,1,1,5,5,3,1,3,3,1,2,3,1,5,1,3,2,1,3,1,1,2,3,5,3,5,5,4,3,1,5,1,1,2,3,2,2,1,1,2,1,4,1,2,3,3,3,1,3,5 \ No newline at end of file diff --git a/2021/06/solution.txt b/2021/06/solution.txt new file mode 100644 index 0000000..f5a27d0 --- /dev/null +++ b/2021/06/solution.txt @@ -0,0 +1,2 @@ +Part 1: 361169 +Part 2: 1634946868992 \ No newline at end of file diff --git a/2021/06/test_code.py b/2021/06/test_code.py new file mode 100644 index 0000000..52780b5 --- /dev/null +++ b/2021/06/test_code.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: MIT +# Copyright (c) 2021 Akumatic + +from code import part1, part2, read_file + +def test(): + vals = read_file("test_input.txt") + assert part1(vals, days=18) == 26 + assert part1(vals) == 5934 + print("Passed Part 1") + assert part2(vals) == 26984457539 + print("Passed Part 2") + +if __name__ == "__main__": + test() diff --git a/2021/06/test_input.txt b/2021/06/test_input.txt new file mode 100644 index 0000000..a7af2b1 --- /dev/null +++ b/2021/06/test_input.txt @@ -0,0 +1 @@ +3,4,3,1,2 \ No newline at end of file diff --git a/2021/README.md b/2021/README.md index 532a33d..1457d19 100644 --- a/2021/README.md +++ b/2021/README.md @@ -20,7 +20,7 @@ Collect stars by solving puzzles. Two puzzles will be made available on each day | 03 | :white_check_mark: | :white_check_mark: | [Solution](03/code.py) | [Day 03](https://adventofcode.com/2021/day/3) | | 04 | :white_check_mark: | :white_check_mark: | [Solution](04/code.py) | [Day 04](https://adventofcode.com/2021/day/4) | | 05 | :white_check_mark: | :white_check_mark: | [Solution](05/code.py) | [Day 05](https://adventofcode.com/2021/day/5) | -| 06 | | | | | +| 06 | :white_check_mark: | :white_check_mark: | [Solution](06/code.py) | [Day 06](https://adventofcode.com/2021/day/6) | | 07 | | | | | | 08 | | | | | | 09 | | | | |