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