From 3fe94bbb0201c4372b074aec853f72f4dcd83140 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Tue, 15 Dec 2020 09:22:49 +0100 Subject: [PATCH] Solve day 15 (part 2 bruteforce) --- 2020/day15_memory.py | 70 +++++++++++++++++++++++++++++++++++++++++ 2020/inputs/day15 | 1 + 2020/inputs/day15-test1 | 1 + 2020/inputs/day15-test2 | 1 + 2020/inputs/day15-test6 | 1 + 2020/inputs/day15-test7 | 1 + 2020/template.py | 34 ++++++++++++++++++++ 7 files changed, 109 insertions(+) create mode 100644 2020/day15_memory.py create mode 100644 2020/inputs/day15 create mode 100644 2020/inputs/day15-test1 create mode 100644 2020/inputs/day15-test2 create mode 100644 2020/inputs/day15-test6 create mode 100644 2020/inputs/day15-test7 create mode 100644 2020/template.py diff --git a/2020/day15_memory.py b/2020/day15_memory.py new file mode 100644 index 0000000..c1a3cf0 --- /dev/null +++ b/2020/day15_memory.py @@ -0,0 +1,70 @@ +import functools +import re +from typing import Dict, Iterable, List, Tuple, Union + + +def main(filename: str, expected_part_1: int = None, expected_part_2: int = None): + print(f"\n+ Running on {filename}") + with open(filename) as f: + starting_numbers = list(map(int, f.read().strip().split("\n")[0].split(","))) + + counter_part_1 = solve_part_1(starting_numbers) + + print(f"1. Found {counter_part_1}") + if expected_part_1: + assert expected_part_1 == counter_part_1 + + counter_part_2 = solve_part_2(starting_numbers) + print(f"2. Found {counter_part_2}") + if expected_part_2: + assert expected_part_2 == counter_part_2 + + +SeenTuple = Union[Tuple[int], Tuple[int, int]] +Seen = Dict[int, SeenTuple] + + +def solve_part_1(starting_numbers): + return solve(starting_numbers, 2020) + + +def solve(starting_numbers, limit): + seen = dict() # type: Seen + previous = 0 + for turn, current in enumerate(starting_numbers): + seen[current] = (turn,) + previous = current + previous_first_time = True + for turn in range(len(starting_numbers), limit): + if previous_first_time: + current = 0 + else: + current = seen[previous][0] - seen[previous][1] + seen[current] = seen_tuple(seen, current, turn) + previous = current + previous_first_time = first_time_seen(seen, previous) + return previous + + +def first_time_seen(seen: Seen, previous: int) -> bool: + return len(seen[previous]) == 1 + + +def seen_tuple(seen: Seen, current: int, turn: int) -> SeenTuple: + try: + existing = seen[current] + return turn, existing[0] + except KeyError: + return (turn,) + + +def solve_part_2(starting_numbers): + return solve(starting_numbers, 30_000_000) + + +if __name__ == "__main__": + main("inputs/day15-test1", 436, 175594) + main("inputs/day15-test2", 1, 2578) + main("inputs/day15-test6", 438, 18) + main("inputs/day15-test7", 1836, 362) + main("inputs/day15", 595, 1708310) diff --git a/2020/inputs/day15 b/2020/inputs/day15 new file mode 100644 index 0000000..87eb7a7 --- /dev/null +++ b/2020/inputs/day15 @@ -0,0 +1 @@ +1,17,0,10,18,11,6 \ No newline at end of file diff --git a/2020/inputs/day15-test1 b/2020/inputs/day15-test1 new file mode 100644 index 0000000..d743421 --- /dev/null +++ b/2020/inputs/day15-test1 @@ -0,0 +1 @@ +0,3,6 \ No newline at end of file diff --git a/2020/inputs/day15-test2 b/2020/inputs/day15-test2 new file mode 100644 index 0000000..55526f5 --- /dev/null +++ b/2020/inputs/day15-test2 @@ -0,0 +1 @@ +1,3,2 \ No newline at end of file diff --git a/2020/inputs/day15-test6 b/2020/inputs/day15-test6 new file mode 100644 index 0000000..37bfbbd --- /dev/null +++ b/2020/inputs/day15-test6 @@ -0,0 +1 @@ +3,2,1 \ No newline at end of file diff --git a/2020/inputs/day15-test7 b/2020/inputs/day15-test7 new file mode 100644 index 0000000..4d83fd9 --- /dev/null +++ b/2020/inputs/day15-test7 @@ -0,0 +1 @@ +3,1,2 \ No newline at end of file diff --git a/2020/template.py b/2020/template.py new file mode 100644 index 0000000..7ca2c9c --- /dev/null +++ b/2020/template.py @@ -0,0 +1,34 @@ +import functools +import re +from typing import Dict, Iterable, List, Union + + +def main(filename: str, expected_part_1: int = None, expected_part_2: int = None): + print(f"\n+ Running on {filename}") + with open(filename) as f: + data = f.read().strip().split("\n") + + counter_part_1 = solve_part_1(data) + + print(f"1. Found {counter_part_1}") + if expected_part_1: + assert expected_part_1 == counter_part_1 + + counter_part_2 = solve_part_2(data) + print(f"2. Found {counter_part_2}") + if expected_part_2: + assert expected_part_2 == counter_part_2 + + +def solve_part_1(data): + return 0 + + +def solve_part_2(data): + return 0 + + +if __name__ == "__main__": + main("inputs/day14-test1", 436) + main("inputs/day14-test2", 1) + main("inputs/day14")