mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Implement 2024 day 8
This commit is contained in:
60
2024/src/aoc/days/day8.py
Normal file
60
2024/src/aoc/days/day8.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import itertools
|
||||
import math
|
||||
from collections import defaultdict
|
||||
|
||||
import numpy
|
||||
|
||||
from . import CombinedRunner
|
||||
|
||||
|
||||
def simplify(vec: numpy.array) -> numpy.array:
|
||||
if vec[0] == 0:
|
||||
return numpy.array([0, 1])
|
||||
elif vec[1] == 0:
|
||||
return numpy.array([0, 1])
|
||||
else:
|
||||
div = math.gcd(*vec)
|
||||
return vec // div
|
||||
|
||||
|
||||
class DayRunner(CombinedRunner):
|
||||
@classmethod
|
||||
def run_both(cls, input: str) -> int:
|
||||
grid = input.strip().split("\n")
|
||||
height = len(grid)
|
||||
width = len(grid[0])
|
||||
|
||||
antennae = defaultdict(list)
|
||||
|
||||
for y, line in enumerate(grid):
|
||||
for x, c in enumerate(line):
|
||||
if c != ".":
|
||||
antennae[c].append(numpy.array([x, y]))
|
||||
|
||||
antinodes = set()
|
||||
antinodes2 = set()
|
||||
|
||||
def in_bounds(node: numpy.array) -> bool:
|
||||
return 0 <= node[0] < width and 0 <= node[1] < height
|
||||
|
||||
def add(node: numpy.array):
|
||||
if in_bounds(node):
|
||||
antinodes.add(tuple(node))
|
||||
|
||||
def walk(start: numpy.array, step: numpy.array):
|
||||
for pos in itertools.count(start, step):
|
||||
if in_bounds(pos):
|
||||
antinodes2.add(tuple(pos))
|
||||
else:
|
||||
break
|
||||
|
||||
for values in antennae.values():
|
||||
for a, b in itertools.combinations(values, 2):
|
||||
add(2 * a - b)
|
||||
add(2 * b - a)
|
||||
|
||||
step = simplify(b - a)
|
||||
walk(b, step)
|
||||
walk(a, -step)
|
||||
|
||||
return len(antinodes), len(antinodes2)
|
||||
12
2024/tests/samples/08.txt
Normal file
12
2024/tests/samples/08.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
............
|
||||
........0...
|
||||
.....0......
|
||||
.......0....
|
||||
....0.......
|
||||
......A.....
|
||||
............
|
||||
............
|
||||
........A...
|
||||
.........A..
|
||||
............
|
||||
............
|
||||
17
2024/tests/test_day08.py
Normal file
17
2024/tests/test_day08.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import os
|
||||
|
||||
from aoc.days.day8 import DayRunner
|
||||
|
||||
|
||||
def get_data() -> str:
|
||||
sample = os.path.dirname(__file__) + "/samples/08.txt"
|
||||
with open(sample, mode="rt", encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def test_sample_part1() -> None:
|
||||
assert DayRunner.part1(get_data()) == 14
|
||||
|
||||
|
||||
def test_sample_part2() -> None:
|
||||
assert DayRunner.part2(get_data()) == 34
|
||||
Reference in New Issue
Block a user