52 lines
1.9 KiB
Python
Raw Permalink Normal View History

2022-12-16 15:24:02 +01:00
# SPDX-License-Identifier: MIT
# Copyright (c) 2022 Akumatic
#
# https://adventofcode.com/2022/day/16
from re import findall
def read_file(filename: str = "input.txt") -> dict:
pattern = "Valve (\w\w) has flow rate=(\d+); tunnels? leads? to valves? ([A-Z, ]+)"
with open(f"{__file__.rstrip('code.py')}{filename}", "r") as f:
values = [findall(pattern, line)[0] for line in f.readlines()]
return {v[0]: {"flow": int(v[1]), "paths": v[2].split(", ")} for v in values}
def dijkstra(valves: dict, start: str) -> dict:
d = {valve: float("inf") for valve in valves}
d[start] = 0
to_process = [valve for valve in valves]
while to_process:
cur = sorted([(d[valve], valve) for valve in to_process])[0][1]
to_process.remove(cur)
for neighbor in valves[cur]["paths"]:
if neighbor in to_process and d[cur] + 1 < d[neighbor]:
d[neighbor] = d[cur] + 1
return d
def calc_flow(valves: dict, distances: dict, closed: list, cur_v: str,
time: int = 30, released: int = 0, flow: int = 0) -> int:
if time < 0:
return released
if not closed:
return released + flow * time
outcomes = list()
for valve in closed:
time_needed = (distances[cur_v][valve] + 1)
predicted_flow = calc_flow(valves, distances, [v for v in closed if v != valve], valve,
time - time_needed, released + flow * time_needed, flow + valves[valve]["flow"])
outcomes.append(released + flow * time if time_needed > time else predicted_flow)
return max(outcomes)
def part1(vals: dict) -> int:
dist = {valve: dijkstra(vals, valve) for valve in vals}
closed = [valve for valve in vals if vals[valve]["flow"]]
return calc_flow(vals, dist, closed, "AA")
def part2(vals: dict) -> int:
pass
if __name__ == "__main__":
vals = read_file()
print(f"Part 1: {part1(vals)}")
print(f"Part 2: {part2(vals)}")