Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- with open('2022_16input.txt', 'r') as file:
- lines = file.read().split('\n')
- class Valve:
- def __init__(self, line):
- line = line.replace("valve", "valves")
- line = line.replace("valvess", "valves")
- line = line.split('valves ')
- self.tunnels = line[-1].split(", ")
- line = line[0].split(' ')
- self.name = line[1]
- self.open = False
- self.interested = {'me':True,'el':True}
- line = line[4].strip(';')
- self.rate = int(line.split('=')[-1])
- if self.rate == 0:
- self.interested['me'] = False
- self.interested['el'] = False
- def options(location, person):
- target_valves = {valve for valve in valves if valves[valve].interested[person]}
- other_valves = {valve for valve in valves if valve != location}
- destinations = {0:[location]}
- moves = 0
- results = []
- while target_valves:
- destinations[moves + 1] = []
- for valve in destinations[moves]:
- if valve in target_valves:
- target_valves.remove(valve)
- results.append((valve, moves + 1, valves[valve].rate))
- for option in valves[valve].tunnels:
- if option in other_valves:
- destinations[moves + 1].append(option)
- other_valves.remove(option)
- moves += 1
- return results
- def best_move(location, person):
- results = options(location, person)
- best_score = 0
- for valve, moves, flow in results:
- score = flow / (moves ** 1.7)
- if score > best_score:
- best_score = score
- best_valve = valve
- best_moves = moves
- elif score == best_score:
- if len(valves[valve].tunnels) > len(valves[best_valve].tunnels):
- best_score = score
- best_valve = valve
- best_moves = moves
- return best_valve, best_moves
- valves = []
- for line in lines:
- valves.append(Valve(line))
- valves = {valve.name:valve for valve in valves}
- start = 'AA'
- possibilities = {}
- directions = {}
- starting_options = options(start, 'me')
- for myvalve, mymoves, flow in starting_options:
- for elvalve, elmoves, flow in starting_options:
- if elvalve != myvalve:
- valves = []
- for line in lines:
- valves.append(Valve(line))
- valves = {valve.name:valve for valve in valves}
- minutes_left = 26
- open_valves = []
- me = {
- 'status' : 'busy',
- 'ready_at' : minutes_left - mymoves,
- 'next_valve' : myvalve,
- 'location' : start,
- }
- elephant = {
- 'status' : 'busy',
- 'ready_at' : minutes_left - elmoves,
- 'next_valve' : elvalve,
- 'location' : start,
- }
- directions[(myvalve, elvalve)] = []
- for person in ['me', 'el']:
- valves[myvalve].interested[person] = False
- valves[elvalve].interested[person] = False
- print('If I start with valve %s and elephant starts with %s...' % (myvalve, elvalve))
- while minutes_left:
- if me['status'] == 'busy':
- if me['ready_at'] == minutes_left:
- me['status'] = 'ready'
- valves[me['next_valve']].open = True
- directions[(myvalve, elvalve)].append("Valve %s opened by me for a rate of %s with %s minutes left" % (me['next_valve'], valves[me['next_valve']].rate, minutes_left))
- open_valves.append((valves[me['next_valve']].rate, minutes_left))
- me['location'] = me['next_valve']
- if elephant['status'] == 'busy':
- if elephant['ready_at'] == minutes_left:
- elephant['status'] = 'ready'
- valves[elephant['next_valve']].open = True
- directions[(myvalve, elvalve)].append("Valve %s opened by elephant for a rate of %s with %s minutes left" % (elephant['next_valve'], valves[elephant['next_valve']].rate, minutes_left))
- open_valves.append((valves[elephant['next_valve']].rate, minutes_left))
- elephant['location'] = elephant['next_valve']
- while me['status'] == 'ready' and len([v for v in valves if valves[v].interested['me']]):
- next_valve, moves = best_move(me['location'], 'me')
- if moves <= minutes_left:
- me['status'] = 'busy'
- me['ready_at'] = minutes_left - moves
- me['next_valve'] = next_valve
- valves[next_valve].interested['me'] = False
- valves[next_valve].interested['el'] = False
- else:
- valves[next_valve].interested['me'] = False
- while elephant['status'] == 'ready' and len([v for v in valves if valves[v].interested['el']]):
- next_valve, moves = best_move(elephant['location'], 'el')
- if moves <= minutes_left:
- elephant['status'] = 'busy'
- elephant['ready_at'] = minutes_left - moves
- elephant['next_valve'] = next_valve
- valves[next_valve].interested['me'] = False
- valves[next_valve].interested['el'] = False
- else:
- valves[next_valve].interested['el'] = False
- minutes_left -= 1
- total_rate = sum([rate * mins for rate, mins in open_valves])
- print(total_rate)
- possibilities[total_rate] = (myvalve, elvalve)
- best = max(possibilities)
- print("Best one was %s." % max(possibilities))
- for line in directions[possibilities[best]]:
- print(line)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement