Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from dataclasses import dataclass
- from copy import copy
- INPUT_FILENAME = "Day 16/input_1.txt"
- INF = int(1e9)
- @dataclass
- class Valve:
- name: str
- flow_rate: int
- children: list[str]
- def parse_input():
- with open(INPUT_FILENAME, "r") as file:
- lines = [l.rstrip() for l in file.readlines()]
- valves = {}
- for line in lines:
- split = line.split(" ")
- valve_name = split[1]
- flow_rate = int(split[4][:-1].split("=")[1])
- children = [split[-1]] + [token[:-1] for token in split if token.endswith(",")]
- valves[valve_name] = Valve(valve_name, flow_rate, children)
- return valves
- def floid_warshall(valves):
- dist = {v: {u: INF for u in valves} for v in valves}
- for v in valves:
- dist[v][v] = 0
- for u in valves[v].children:
- dist[v][u] = 1
- for k in valves:
- for i in valves:
- for j in valves:
- dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
- return dist
- def main():
- valves = parse_input()
- distances = floid_warshall(valves)
- non_zero_valves = [v for v in valves if valves[v].flow_rate > 0]
- def generate_open_options(pos, open_valves, time_left):
- for next in non_zero_valves:
- if next not in open_valves and distances[pos][next] < time_left:
- open_valves.append(next)
- yield from generate_open_options(
- next, open_valves, time_left - distances[pos][next] - 1
- )
- open_valves.pop()
- yield copy(open_valves)
- def get_order_score(open_order, time_left):
- now, ans = "AA", 0
- for pos in open_order:
- time_left -= distances[now][pos] + 1
- ans += valves[pos].flow_rate * time_left
- now = pos
- return ans
- def solution_1():
- return max(get_order_score(o, 30) for o in generate_open_options("AA", [], 30))
- def solution_2():
- ways = list(generate_open_options("AA", [], 26))
- best_scores = {}
- for order in ways:
- tup = tuple(sorted(order))
- score = get_order_score(order, 26)
- best_scores[tup] = max(best_scores.get(tup, 0), score)
- best_scores = list(best_scores.items())
- print(len(best_scores))
- print(len(ways))
- ans = 0
- for human_idx in range(len(best_scores)):
- for elephant_idx in range(human_idx + 1, len(best_scores)):
- human_opens, human_score = best_scores[human_idx]
- elephant_opens, elephant_score = best_scores[elephant_idx]
- if len(set(human_opens).intersection(elephant_opens)) == 0:
- ans = max(ans, human_score + elephant_score)
- return ans
- print("Answer 1:", solution_1())
- print("Answer 2:", solution_2())
- if __name__ == "__main__":
- # INPUT_FILENAME = "Day 16/sample.txt"
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement