part2.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import argparse
  2. import functools
  3. from typing import NamedTuple, List, Dict, Set, Tuple
  4. import sys
  5. parser = argparse.ArgumentParser()
  6. parser.add_argument("ifile", type=argparse.FileType('r'))
  7. args = parser.parse_args()
  8. octopi = [[int(x) for x in line.strip()] for line in args.ifile.readlines()]
  9. max_dim = len(octopi) # thing is square, so this works for both
  10. TOTAL_FLASHES = 0
  11. def getNeighbors(x: int, y: int):
  12. positions = [(x - 1, y - 1), (x, y - 1), (x + 1, y - 1),
  13. (x - 1, y), (x, y), (x + 1, y),
  14. (x - 1, y + 1), (x, y + 1), (x + 1, y + 1)]
  15. return list(filter(lambda pair: 0 <= pair[0] < max_dim and 0 <= pair[1] < max_dim, positions))
  16. def printOctopi(octopi_list: List[List[int]]):
  17. for line in octopi_list:
  18. print("".join([str(x) for x in line]))
  19. def incrementOctopi(octopi_list: List[List[int]]) -> List[List[int]]:
  20. return [list(map(lambda x: x + 1, line)) for line in octopi_list]
  21. def flashOctopi(octopi_list: List[List[int]]) -> List[List[int]]:
  22. global TOTAL_FLASHES
  23. to_flash: Set[Tuple[int, int]] = set()
  24. has_flashed: Set[Tuple[int, int]] = set()
  25. for y in range(0, max_dim):
  26. for x in range(0, max_dim):
  27. if octopi_list[y][x] > 9:
  28. to_flash.add((x, y))
  29. while(len(to_flash) > 0):
  30. octopode = to_flash.pop()
  31. TOTAL_FLASHES += 1
  32. has_flashed.add(octopode)
  33. for oct_pos in getNeighbors(octopode[0], octopode[1]):
  34. octopi_list[oct_pos[1]][oct_pos[0]] += 1
  35. if octopi_list[oct_pos[1]][oct_pos[0]] > 9:
  36. if (oct_pos[0], oct_pos[1]) not in has_flashed:
  37. to_flash.add((oct_pos[0], oct_pos[1]))
  38. for pos in has_flashed:
  39. octopi_list[pos[1]][pos[0]] = 0
  40. if len(has_flashed) == 100:
  41. raise Exception
  42. return octopi_list
  43. octs = octopi
  44. for x in range(0, 1000):
  45. octs = incrementOctopi(octs)
  46. try:
  47. octs = flashOctopi(octs)
  48. except:
  49. print(x + 1)
  50. break