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.

69 lines
1.6KB

  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})
  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. if grid[x - 1, y] == '|' and grid[x + 1, y] == ' ' and grid[x, y + 1] != '|':
  40. flow((x + 1, y))
  41. for dx, dy in [(-1, 0), (1, 0), (0, -1)]:
  42. new = x + dx, y + dy
  43. if grid[new] == '~':
  44. stack.append(new)
  45. grid = read_in()
  46. xmin, *_, xmax = sorted(x for x, y in grid)
  47. ymin, *_, ymax = sorted(y for x, y in grid)
  48. flow((500, 0))
  49. counter = collections.Counter(grid.values())
  50. print(counter['~'] + counter['|'])
  51. print(counter['~'])
  52. write_out(grid, 'y2018/p17out.dat')