1
0
Fork 0
adventofcode/2024/08/main.py

95 lines
2.3 KiB
Python
Raw Permalink Normal View History

2024-12-08 19:20:40 +00:00
#!/usr/bin/env python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# Author: Sebastian Mark
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string
import re
def readinput():
with open("input", "r", encoding="utf-8") as file:
lines = [line.strip("\n") for line in file.readlines()]
return lines
def get_antinodes_for_pair(city: list, pos: tuple, twin: tuple, part: int) -> set:
width = len(city[0])
height = len(city)
antinodes_for_pair = set()
# distance between pairs
dy = pos[0] - twin[0]
dx = pos[1] - twin[1]
# add antinode(s) above upper antenna
nxty = pos[0] + dy
nxtx = pos[1] + dx
while 0 <= nxty < height and 0 <= nxtx < width:
antinodes_for_pair.add((nxty, nxtx))
if part == 1:
break
nxty += dy
nxtx += dx
# add antinode(s) below lower antenna
nxty = twin[0] - dy
nxtx = twin[1] - dx
while 0 <= nxty < height and 0 <= nxtx < width:
antinodes_for_pair.add((nxty, nxtx))
if part == 1:
break
nxty -= dy
nxtx -= dx
return antinodes_for_pair
def get_antinodes_for_freq(city: list, freq: str, pos: tuple, part: int) -> set:
starty = pos[0]
antinodes_for_freq = set()
# search downwards for twins
twins = []
if starty <= len(city):
for y in range(starty + 1, len(city)):
x = city[y].find(freq)
if x >= 0:
twins.append((y, x))
for twin in twins:
antinodes_for_freq |= get_antinodes_for_pair(city, pos, twin, part)
return antinodes_for_freq
def get_antinodes(city: list, part: int) -> set:
antinodes = set()
# serch city for antennas
for y, street in enumerate(city):
antennas = re.finditer(r"([a-zA-Z0-9])", street)
for antenna in antennas:
freq = antenna.group()
pos = (y, antenna.start())
antinodes |= get_antinodes_for_freq(city, freq, pos, part)
if part == 2:
antinodes.add(pos)
return antinodes
def main():
city = readinput()
for part in [1, 2]:
antinodes = get_antinodes(city, part)
print("Unique antinodes (part%d): %d" % (part, len(antinodes)))
if __name__ == "__main__":
main()