Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

100 lines
2.4KB

  1. import collections
  2. import hashlib
  3. import itertools
  4. import math
  5. import os
  6. import re
  7. import sys
  8. from pathlib import Path
  9. import requests
  10. def integers(line):
  11. return [int(n) for n in re.findall(r'\d+', line)]
  12. def lcm(a, b):
  13. return abs(a * b) // math.gcd(a, b)
  14. def render(grid, brush=None):
  15. if brush is None:
  16. brush = {v: v for v in grid.values()}
  17. if isinstance(brush, str):
  18. brush = {i: c for i, c in enumerate(brush)}
  19. xmin, *_, xmax = sorted(int(p.real) for p in grid)
  20. ymin, *_, ymax = sorted(int(p.imag) for p in grid)
  21. brush[None] = ' '
  22. rendered = ''
  23. for y in range(ymin, ymax + 1):
  24. for x in range(xmin, xmax + 1):
  25. rendered += brush[grid.get(complex(x, y))]
  26. rendered += '\n'
  27. return rendered
  28. def read_image(text):
  29. grid = collections.defaultdict(str)
  30. for y, line in enumerate(text.splitlines()):
  31. for x, cell in enumerate(line):
  32. grid[complex(x, y)] = cell
  33. return grid, x + 1, y + 1
  34. def shortest_path(start, end, move):
  35. seen = {}
  36. edge = {start: None}
  37. while edge:
  38. seen.update(edge)
  39. edge = {
  40. adj: pos
  41. for pos in edge
  42. for adj in move(pos)
  43. if adj not in seen
  44. }
  45. if end in seen:
  46. break
  47. else:
  48. raise RuntimeError('Path not found', seen)
  49. path = []
  50. while end:
  51. path.append(end)
  52. end = seen[end]
  53. return path[::-1]
  54. def get_dat():
  55. path = sys.argv[1]
  56. year, qn = map(int, re.findall(r'\d+', sys.argv[1]))
  57. url = f'https://adventofcode.com/{year}/day/{qn}/input'
  58. cookies = {'session': os.environ['SESSION']}
  59. response = requests.get(url, cookies=cookies)
  60. response.raise_for_status()
  61. Path(path).write_bytes(response.content)
  62. def batch(iterable, size):
  63. count = itertools.count()
  64. for _, sub in itertools.groupby(iterable, lambda _: next(count) // size):
  65. yield sub
  66. def md5(string):
  67. return hashlib.md5(string.encode()).hexdigest()
  68. def loop_consume(lines, handler):
  69. instructions = collections.deque(lines)
  70. count = 0
  71. while instructions:
  72. ok = handler(instructions[0])
  73. if ok:
  74. instructions.popleft()
  75. count = 0
  76. elif count < len(instructions):
  77. instructions.rotate(1)
  78. count += 1
  79. else:
  80. raise RuntimeError('Reached steady state')