add 2024/day8
This commit is contained in:
parent
d1a08f36c3
commit
8f0bc54b7c
1 changed files with 94 additions and 0 deletions
94
2024/08/main.py
Normal file
94
2024/08/main.py
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
#!/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()
|
Loading…
Reference in a new issue