選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

97 行
2.5KB

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