solution.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #!/usr/bin/python3
  2. import sys
  3. import re
  4. import functools
  5. # part 1
  6. valves = []
  7. rates = []
  8. indices = []
  9. adjacent = []
  10. index_map = {}
  11. def parse_input():
  12. nodes = 0
  13. # process input
  14. for line in sys.stdin:
  15. source, rate, targets = re.match(r'^Valve ([A-Z]+) has flow rate=([0-9]+); tunnels? leads? to valves? ([A-Z, ]+)', line.strip()).groups()
  16. index_map[source] = nodes
  17. valves.append(nodes)
  18. rates.append(int(rate))
  19. adjacent.append(targets.split(', '))
  20. nodes += 1
  21. # transform letter neighbors to index neighbors
  22. for i in range(nodes):
  23. indices.append([*map(lambda x: index_map[x], adjacent[i])])
  24. #print(f'index_map {index_map}\nadjacent {adjacent}')
  25. print(f'nodes {nodes}\nvalves {valves}\nrates {rates}\nindices {indices}')
  26. #return nodes, index_map, valves, rates, indices
  27. #@functools.lru_cache(maxsize=None)
  28. def enumerate_pressure(seen, current, time=30):
  29. print('looking at', current)
  30. if time <= 0:
  31. return 0
  32. max_pressure = 0
  33. if current not in seen:
  34. pressure = rates[current] * (time - 1)
  35. new_seen = seen.union({current})
  36. print(f'{current} not yet seen, pressure {pressure} (rate {rates[current]}, time {time - 1})')
  37. for index in indices[current]:
  38. if pressure == 0:
  39. max_pressure = max(max_pressure, enumerate_pressure(new_seen, index, time - 1))
  40. else:
  41. max_pressure = max(max_pressure, pressure + enumerate_pressure(new_seen, index, time - 2))
  42. #print(seen, current, time, max_pressure)
  43. return max_pressure
  44. def part1():
  45. # parse input
  46. parse_input()
  47. # find maximal pressure
  48. #for i in range(nodes):
  49. #visited = [False for i in range(nodes)]
  50. #print(maximal_pressure(valves, rates, indices, visited, i))
  51. seen = frozenset()
  52. print(enumerate_pressure(seen, 0))
  53. # part 2
  54. def part2():
  55. pass
  56. if sys.argv[1] in '1':
  57. part1()
  58. else:
  59. part2()