part1.py 1.9 KB

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