105 lines
2.8 KiB
Python
105 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)})
|