kupuguy

Adevent of Code 2024 Day 14

Dec 14th, 2024
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.54 KB | Source Code | 0 0
  1. from pathlib import Path
  2. import re
  3. from collections import Counter
  4.  
  5. TEST = """**REDACTED**"""
  6.  
  7.  
  8. def parse(input: str) -> list[tuple[int, int, int, int]]:
  9.     robots: list[tuple[int, int, int, int]] = []
  10.     for row in input.splitlines():
  11.         pos = [int(n) for n in re.findall("-?\\d+", row)]
  12.         assert len(pos) == 4
  13.         robots.append(tuple(pos))
  14.     return robots
  15.  
  16.  
  17. def part1(input: str, width: int = 101, height: int = 103, moves: int = 100) -> int:
  18.     quadrants: list[int] = [0, 0, 0, 0]
  19.     w2, h2 = width // 2, height // 2
  20.     for robot in parse(input):
  21.         px, py, vx, vy = robot
  22.         fx = (px + moves * vx) % width
  23.         fy = (py + moves * vy) % height
  24.         if fx != w2 and fy != h2:
  25.             quadrants[(1 if fx > w2 else 0) + (2 if fy > h2 else 0)] += 1
  26.     return quadrants[0] * quadrants[1] * quadrants[2] * quadrants[3]
  27.  
  28.  
  29. assert part1(TEST, 11, 7) == 12
  30.  
  31. INPUT = Path("input/day14.txt").read_text()
  32. part1_total = part1(INPUT)
  33. print(f"{part1_total=:,}")  # 230,900,224
  34.  
  35.  
  36. def treeness(
  37.     move: int,
  38.     robots: list[tuple[int, int, int, int]],
  39.     width: int,
  40.     height: int,
  41.     branches=6,
  42. ) -> int:
  43.     # Tree picture will have a lot of robots with close neighbours
  44.     points = {
  45.         complex((px + move * vx) % width, (py + move * vy) % height)
  46.         for px, py, vx, vy in robots
  47.     }
  48.     neighbours = sum(
  49.         len(
  50.             {
  51.                 p + 1,
  52.                 p - 1,
  53.                 p + 1j,
  54.                 p - 1j,
  55.                 p + 1 + 1j,
  56.                 p + 1 - 1j,
  57.                 p - 1 + 1j,
  58.                 p - 1 - 1j,
  59.             }
  60.             & points
  61.         )
  62.         for p in points
  63.     )
  64.     return neighbours
  65.  
  66.  
  67. def show(
  68.     move: int, robots: list[tuple[int, int, int, int]], width: int, height: int
  69. ) -> None:
  70.     grid = [[" "] * width for i in range(height)]
  71.     for px, py, vx, vy in robots:
  72.         fx = (px + move * vx) % width
  73.         fy = (py + move * vy) % height
  74.         grid[fy][fx] = "*"
  75.     for row in grid:
  76.         print("".join(row))
  77.  
  78.  
  79. def part2(inp: str, width: int = 101, height: int = 103, moves: int = 100) -> int:
  80.     w2, h2 = width // 2, height // 2
  81.     robots = parse(inp)
  82.     moves: Counter[int] = Counter()
  83.     for move in range(1, width * height):
  84.         moves[move] = treeness(move, robots, width, height)
  85.  
  86.     for move, score in moves.most_common(1):
  87.         print(move, score)
  88.         show(move, robots, width, height)
  89.  
  90.     return moves.most_common(1)[0][0]
  91.  
  92.  
  93. print(f"{part2(INPUT)=:,}") # 6532
  94.  
Advertisement
Add Comment
Please, Sign In to add comment