-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday07.py
97 lines (69 loc) · 2.78 KB
/
day07.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
"""Day 7: The Treachery of Whales."""
from functools import cache
from typing import Final
import numpy as np
from advent_of_code.checks import check_answer, check_example
from advent_of_code.cli_output import print_single_answer
from advent_of_code.data import get_data_path
DAY: Final[int] = 7
def _get_input_data() -> list[int]:
data = ""
with open(get_data_path(DAY), "r") as file:
for line in file:
data += line.strip()
return [int(x) for x in data.split(",")]
def _get_example_data() -> list[int]:
return [int(x) for x in "16,1,2,0,4,2,7,1,2,14".split(",")]
def find_cheapest_position_constant_fuel(postions: list[int]) -> tuple[int, int]:
"""Find the cheapeast position if fuel is consumed as a constant rate.
This provides the answer for Part 1.
Args:
postions (list[int]): Initial crab positions.
Returns:
tuple[int, int]: Final position and cost of moving.
"""
pos = np.around(np.quantile(postions, 0.5)).astype(int)
cost = sum([abs(x - pos) for x in postions])
return pos, cost
@cache
def _calc_fuel_cost(a: int, b: int) -> int:
return sum(list(range(abs(a - b) + 1)))
def _growing_fuel_cost(target: int, positions: list[int]) -> int:
return sum([_calc_fuel_cost(target, x) for x in positions])
def find_cheapest_position_increasing_fuel(positions: list[int]) -> tuple[int, int]:
"""Find the cheapeast position if fuel is consumed as a growing rate.
This provides the answer for Part 2.
Args:
postions (list[int]): Initial crab positions.
Returns:
tuple[int, int]: Final position and cost of moving.
"""
min_pos, min_cost = len(positions), _growing_fuel_cost(0, positions)
for target in range(min(positions), max(positions)):
cost = _growing_fuel_cost(target, positions)
if cost < min_cost:
min_pos, min_cost = target, cost
return min_pos, min_cost
def main() -> None:
"""Run code for day 7 'The Treachery of Whales'."""
# Part 1.
ex_crab_positions = _get_example_data()
ex_pos, ex_cost = find_cheapest_position_constant_fuel(ex_crab_positions)
check_example(2, ex_pos)
check_example(37, ex_cost)
crab_postion = _get_input_data()
_, cost = find_cheapest_position_constant_fuel(crab_postion)
print_single_answer(DAY, 1, cost)
check_answer(352997, cost, DAY, 1)
# Part 2.
ex_crab_positions = _get_example_data()
ex_pos, ex_cost = find_cheapest_position_increasing_fuel(ex_crab_positions)
check_example(ex_pos, 5)
check_example(ex_cost, 168)
crab_postion = _get_input_data()
_, cost = find_cheapest_position_increasing_fuel(crab_postion)
print_single_answer(DAY, 2, cost)
check_answer(101571302, cost, DAY, 2)
return None
if __name__ == "__main__":
main()