2023-12-09 19:30:00 +01:00
|
|
|
import lib
|
|
|
|
|
|
|
|
EXAMPLE = """
|
2023-12-10 18:52:31 +01:00
|
|
|
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
|
|
|
|
Valve BB has flow rate=13; tunnels lead to valves CC, AA
|
|
|
|
Valve CC has flow rate=2; tunnels lead to valves DD, BB
|
|
|
|
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
|
|
|
|
Valve EE has flow rate=3; tunnels lead to valves FF, DD
|
|
|
|
Valve FF has flow rate=0; tunnels lead to valves EE, GG
|
|
|
|
Valve GG has flow rate=0; tunnels lead to valves FF, HH
|
|
|
|
Valve HH has flow rate=22; tunnel leads to valve GG
|
|
|
|
Valve II has flow rate=0; tunnels lead to valves AA, JJ
|
|
|
|
Valve JJ has flow rate=21; tunnel leads to valve II
|
2023-12-09 19:30:00 +01:00
|
|
|
"""
|
|
|
|
|
|
|
|
def solve(lines: list[str]):
|
2023-12-10 18:52:31 +01:00
|
|
|
nodes = {}
|
2023-12-09 19:30:00 +01:00
|
|
|
for (i, line) in enumerate(lines):
|
2023-12-10 18:52:31 +01:00
|
|
|
source = line.split(" ")[1]
|
|
|
|
to_valves = list(map(lambda v: v.replace(",", ""), line.split(" ")[9:]))
|
2023-12-28 04:02:59 +01:00
|
|
|
flow_rate = lib.str_to_int(line)
|
2023-12-10 18:52:31 +01:00
|
|
|
nodes[source] = (flow_rate, to_valves)
|
|
|
|
|
2023-12-28 04:02:59 +01:00
|
|
|
|
2023-12-10 18:52:31 +01:00
|
|
|
options = [(0, 0, "AA", ())]
|
|
|
|
visited = set()
|
|
|
|
for _ in range(30):
|
|
|
|
new_options = []
|
|
|
|
for (total, flow, current, valves) in options:
|
|
|
|
valve_flow_rate = nodes[current][0]
|
|
|
|
if not current in valves and valve_flow_rate > 0:
|
|
|
|
o = (total + flow, flow + valve_flow_rate, current, valves + (current, ))
|
|
|
|
new_options.append(o)
|
|
|
|
for new_valve in nodes[current][1]:
|
|
|
|
o = (total + flow, flow, new_valve, valves)
|
|
|
|
new_options.append(o)
|
|
|
|
|
|
|
|
options = sorted(list(set(new_options)))[-100:]
|
|
|
|
return options[-1][0]
|
|
|
|
|
2023-12-09 19:30:00 +01:00
|
|
|
|
|
|
|
def solve2(lines: list[str]):
|
2023-12-10 18:52:31 +01:00
|
|
|
nodes = {}
|
2023-12-09 19:30:00 +01:00
|
|
|
for (i, line) in enumerate(lines):
|
2023-12-10 18:52:31 +01:00
|
|
|
source = line.split(" ")[1]
|
|
|
|
to_valves = list(map(lambda v: v.replace(",", ""), line.split(" ")[9:]))
|
2023-12-28 04:02:59 +01:00
|
|
|
flow_rate = lib.str_to_int(line)
|
2023-12-10 18:52:31 +01:00
|
|
|
nodes[source] = (flow_rate, to_valves)
|
|
|
|
|
|
|
|
options = [(0, 0, ("AA", "AA"), ())]
|
|
|
|
for _ in range(26):
|
|
|
|
new_options = []
|
|
|
|
for (total, flow, (a, b), valves) in options:
|
|
|
|
flow_a = nodes[a][0]
|
|
|
|
flow_b = nodes[b][0]
|
|
|
|
|
|
|
|
# a turns on b moves
|
|
|
|
if not a in valves and flow_a > 0:
|
|
|
|
for new_valve_b in nodes[b][1]:
|
|
|
|
o = (total + flow, flow + flow_a, (a, new_valve_b), valves + (a, ))
|
|
|
|
new_options.append(o)
|
|
|
|
|
|
|
|
# a moves and b turns on
|
|
|
|
if not b in valves and flow_b > 0:
|
|
|
|
for new_valve_a in nodes[a][1]:
|
|
|
|
o = (total + flow, flow + flow_b, (new_valve_a, b), valves + (b, ))
|
|
|
|
new_options.append(o)
|
|
|
|
|
|
|
|
# both turn on
|
|
|
|
if a != b and flow_a > 0 and flow_b > 0 and not a in valves and not b in valves:
|
|
|
|
o = (total + flow, flow + flow_a + flow_b, (a, b), valves + (a, b, ))
|
|
|
|
new_options.append(o)
|
|
|
|
|
|
|
|
# both move
|
|
|
|
for new_valve_a in nodes[a][1]:
|
|
|
|
for new_valve_b in nodes[b][1]:
|
|
|
|
o = (total + flow, flow, (new_valve_a, new_valve_b), valves)
|
|
|
|
new_options.append(o)
|
|
|
|
|
|
|
|
options = sorted(list(set(new_options)))[-1000:]
|
|
|
|
# 52:00
|
|
|
|
return options[-1][0]
|
|
|
|
|
2023-12-09 19:30:00 +01:00
|
|
|
|
|
|
|
def main():
|
|
|
|
lines = lib.str_to_lines_no_empty(EXAMPLE)
|
|
|
|
print("Example 1:", solve(lines))
|
|
|
|
|
2023-12-10 18:52:31 +01:00
|
|
|
lines = lib.str_to_lines_no_empty(open("i16.txt").read())
|
2023-12-09 19:30:00 +01:00
|
|
|
print("Solution 1:", solve(lines))
|
|
|
|
|
|
|
|
lines = lib.str_to_lines_no_empty(EXAMPLE)
|
|
|
|
print("Example 2:", solve2(lines))
|
|
|
|
|
2023-12-10 18:52:31 +01:00
|
|
|
lines = lib.str_to_lines_no_empty(open("i16.txt").read())
|
2023-12-09 19:30:00 +01:00
|
|
|
print("Solution 2:", solve2(lines))
|
2023-12-28 04:02:59 +01:00
|
|
|
assert solve2(lines) == 2591
|
2023-12-09 19:30:00 +01:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|