aoc2024/day08.py
2024-12-08 11:40:32 +01:00

104 lines
2.8 KiB
Python

#!/usr/bin/env python3
# N
# NW NO
# W X O
# SW SO
# S
from collections import defaultdict
import math
freqmap = defaultdict(list)
lx = 0
ly = 0
with open("day08") as f:
for y,l in enumerate(f):
ly += 1
lx = len(l.strip())
for x,c in enumerate(l.strip()):
if c != '.':
freqmap[c].append((y,x))
antinodes = set()
for (_, coords) in freqmap.items():
for s,a in enumerate(coords):
for b in coords[s+1:]:
dy = abs(a[0]-b[0])
dx = abs(a[1]-b[1])
# vertical
if a[1]==b[1] and a[0]<b[0]:
antinodes.add((a[0]-dy,a[1]))
antinodes.add((b[0]+dy,b[1]))
if a[1]==b[1] and a[0]>b[0]:
antinodes.add((a[0]+dy,a[1]))
antinodes.add((b[0]-dy,b[1]))
# horizontal
if a[0]==b[0] and a[1]<b[1]:
antinodes.add((a[0],a[1]-dx))
antinodes.add((b[0],b[1]+dx))
if a[0]==b[0] and a[1]>b[1]:
antinodes.add((a[0],a[1]+dx))
antinodes.add((b[0],b[1]-dx))
# positive slope
if a[0]<b[0] and a[1]<b[1]:
antinodes.add((a[0]-dy,a[1]-dx))
antinodes.add((b[0]+dy,b[1]+dx))
if a[0]>b[0] and a[1]>b[1]:
antinodes.add((a[0]+dy,a[1]+dx))
antinodes.add((b[0]-dy,b[1]-dx))
# negative slope
if a[0]<b[0] and a[1]>b[1]:
antinodes.add((a[0]-dy,a[1]+dx))
antinodes.add((b[0]+dy,b[1]-dx))
if a[0]>b[0] and a[1]<b[1]:
antinodes.add((a[0]+dy,a[1]-dx))
antinodes.add((b[0]-dy,b[1]+dx))
def boundscheck(antinode):
if antinode[0] < 0: return False
if antinode[0] >= ly: return False
if antinode[1] < 0: return False
if antinode[1] >= lx: return False
return True
def printmap():
with open("day08") as f:
for y,l in enumerate(f):
for x,c in enumerate(l):
if c == '.':
if (y,x) in antinodes2:
print("#", end=" ")
else: print(".", end=" ")
else:
print(c.strip(), end=" ")
print()
res = len({antinode for antinode in antinodes if boundscheck(antinode)})
# 2
antinodes2 = set()
for (_, coords) in freqmap.items():
for s,a in enumerate(coords):
for b in coords[s+1:]:
slope = ((a[0]-b[0]) / (a[1]-b[1]))
# y = mx + y0
y0 = a[0] - slope*a[1]
for x in range(lx):
y = (slope*x)+y0
if abs(round(y)-y) < 0.0001:
antinodes2.add((int(round(y)), x))
res2 = len({antinode for antinode in antinodes2 if boundscheck(antinode)})