Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

70 lines
1.7KB

  1. import collections
  2. import re
  3. from pathlib import Path
  4. def read_in():
  5. grid = collections.defaultdict(lambda: ' ')
  6. for _ in Path('y2018/p17.dat').read_text().splitlines():
  7. _ = _.replace(',', ';')
  8. _ = re.sub(r'(\d+)\.\.(\d+)', r'range(\1, \2 + 1)', _)
  9. _ = re.sub(r'=(\d+)', r'=[\1]', _)
  10. exec(_, globals())
  11. grid.update({(X, Y): '#' for X in x for Y in y}) # noqa
  12. return grid
  13. def write_out(grid, path):
  14. text = '\n'.join(
  15. ''.join(grid[x, y] for x in range(xmin - 5, xmax + 5))
  16. for y in range(ymin, ymax + 1)
  17. )
  18. Path(path).write_text(text)
  19. def flow(start):
  20. stack = [start]
  21. while stack:
  22. x, y = stack.pop()
  23. grid[x, y] = '~'
  24. if y > ymax:
  25. break
  26. for dx, dy in [(1, 0), (-1, 0), (0, 1)]:
  27. new = x + dx, y + dy
  28. if dy == 1 and grid[new] == '|':
  29. stack.clear()
  30. break
  31. if grid[new] == ' ':
  32. stack.append(new)
  33. drain((x, y))
  34. def drain(end):
  35. stack = [end]
  36. while stack:
  37. x, y = stack.pop()
  38. grid[x, y] = '|'
  39. left, right, below = grid[x - 1, y], grid[x + 1, y], grid[x, y + 1]
  40. if all([right == ' ', left == '|', below != '|']):
  41. flow((x + 1, y))
  42. for dx, dy in [(-1, 0), (1, 0), (0, -1)]:
  43. new = x + dx, y + dy
  44. if grid[new] == '~':
  45. stack.append(new)
  46. grid = read_in()
  47. xmin, *_, xmax = sorted(x for x, y in grid)
  48. ymin, *_, ymax = sorted(y for x, y in grid)
  49. flow((500, 0))
  50. counter = collections.Counter(grid.values())
  51. print(counter['~'] + counter['|'])
  52. print(counter['~'])
  53. write_out(grid, 'y2018/p17out.dat')