Advertisement
Guest User

AOC Day 16 pt 2 in Python 3 (corrected)

a guest
Dec 16th, 2022
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.80 KB | None | 0 0
  1. with open('2022_16input.txt', 'r') as file:
  2.     lines = file.read().split('\n')
  3.  
  4. class Valve:
  5.     def __init__(self, line):
  6.         line = line.replace("valve", "valves")
  7.         line = line.replace("valvess", "valves")
  8.         line = line.split('valves ')
  9.         self.tunnels = line[-1].split(", ")
  10.         line = line[0].split(' ')
  11.         self.name = line[1]
  12.         self.open = False
  13.         self.interested = {'me':True,'el':True}
  14.         line = line[4].strip(';')
  15.         self.rate = int(line.split('=')[-1])
  16.         if self.rate == 0:
  17.             self.interested['me'] = False
  18.             self.interested['el'] = False
  19.  
  20. def options(location, person):
  21.     target_valves = {valve for valve in valves if valves[valve].interested[person]}
  22.     other_valves = {valve for valve in valves if valve != location}
  23.     destinations = {0:[location]}
  24.     moves = 0
  25.     results = []
  26.     while target_valves:
  27.         destinations[moves + 1] = []
  28.         for valve in destinations[moves]:
  29.             if valve in target_valves:
  30.                 target_valves.remove(valve)
  31.                 results.append((valve, moves + 1, valves[valve].rate))
  32.             for option in valves[valve].tunnels:
  33.                 if option in other_valves:
  34.                     destinations[moves + 1].append(option)
  35.                     other_valves.remove(option)
  36.         moves += 1
  37.     return results
  38.  
  39. def best_move(location, person):
  40.     results = options(location, person)
  41.     best_score = 0
  42.     for valve, moves, flow in results:
  43.         score = flow / (moves ** 1.7)
  44.         if score > best_score:
  45.             best_score = score
  46.             best_valve = valve
  47.             best_moves = moves
  48.         elif score == best_score:
  49.             if len(valves[valve].tunnels) > len(valves[best_valve].tunnels):
  50.                 best_score = score
  51.                 best_valve = valve
  52.                 best_moves = moves
  53.     return best_valve, best_moves
  54. valves = []    
  55. for line in lines:
  56.     valves.append(Valve(line))
  57. valves = {valve.name:valve for valve in valves}
  58.    
  59. start = 'AA'
  60.    
  61. possibilities = {}
  62. directions = {}
  63. starting_options = options(start, 'me')
  64. for myvalve, mymoves, flow in starting_options:
  65.     for elvalve, elmoves, flow in starting_options:
  66.         if elvalve != myvalve:
  67.             valves = []    
  68.             for line in lines:
  69.                 valves.append(Valve(line))
  70.             valves = {valve.name:valve for valve in valves}
  71.             minutes_left = 26
  72.             open_valves = []
  73.             me = {
  74.                 'status'    :   'busy',
  75.                 'ready_at'  :   minutes_left - mymoves,
  76.                 'next_valve'    :   myvalve,
  77.                 'location'  :   start,
  78.                 }
  79.             elephant = {
  80.                 'status'    :   'busy',
  81.                 'ready_at'  :   minutes_left - elmoves,
  82.                 'next_valve'    :   elvalve,
  83.                 'location'  :   start,
  84.                 }
  85.             directions[(myvalve, elvalve)] = []
  86.             for person in ['me', 'el']:
  87.                 valves[myvalve].interested[person] = False
  88.                 valves[elvalve].interested[person] = False
  89.             print('If I start with valve %s and elephant starts with %s...' % (myvalve, elvalve))
  90.             while minutes_left:
  91.                 if me['status'] == 'busy':
  92.                     if me['ready_at'] == minutes_left:
  93.                         me['status'] = 'ready'
  94.                         valves[me['next_valve']].open = True
  95.                         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))
  96.                         open_valves.append((valves[me['next_valve']].rate, minutes_left))
  97.                         me['location'] = me['next_valve']
  98.                 if elephant['status'] == 'busy':
  99.                     if elephant['ready_at'] == minutes_left:
  100.                         elephant['status'] = 'ready'
  101.                         valves[elephant['next_valve']].open = True
  102.                         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))
  103.                         open_valves.append((valves[elephant['next_valve']].rate, minutes_left))
  104.                         elephant['location'] = elephant['next_valve']
  105.                
  106.                 while me['status'] == 'ready' and len([v for v in valves if valves[v].interested['me']]):
  107.                     next_valve, moves = best_move(me['location'], 'me')
  108.                     if moves <= minutes_left:
  109.                         me['status'] = 'busy'
  110.                         me['ready_at'] = minutes_left - moves
  111.                         me['next_valve'] = next_valve
  112.                         valves[next_valve].interested['me'] = False
  113.                         valves[next_valve].interested['el'] = False
  114.                     else:
  115.                         valves[next_valve].interested['me'] = False
  116.                        
  117.                 while elephant['status'] == 'ready' and len([v for v in valves if valves[v].interested['el']]):
  118.                     next_valve, moves = best_move(elephant['location'], 'el')
  119.                     if moves <= minutes_left:
  120.                         elephant['status'] = 'busy'
  121.                         elephant['ready_at'] = minutes_left - moves
  122.                         elephant['next_valve'] = next_valve
  123.                         valves[next_valve].interested['me'] = False
  124.                         valves[next_valve].interested['el'] = False
  125.                     else:
  126.                         valves[next_valve].interested['el'] = False
  127.                 minutes_left -= 1  
  128.             total_rate = sum([rate * mins for rate, mins in open_valves])
  129.             print(total_rate)
  130.             possibilities[total_rate] = (myvalve, elvalve)
  131. best = max(possibilities)
  132. print("Best one was %s." % max(possibilities))
  133. for line in directions[possibilities[best]]:
  134.     print(line)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement