# Returns the rise/run def slope(a: (int, int), b: (int, int)) -> (int, int): return (b[0] - a[0], b[1] - a[1]) def inside(pos: (int, int), max: (int, int)) -> bool: return 0 <= pos[0] < max[0] and 0 <= pos[1] < max[1] if __name__ == '__main__': with open('input.data') as file: grid = [line.strip() for line in file] nodes = {} for y, row in enumerate(grid): for x, c in enumerate(row): if c == '.': continue if c in nodes: nodes[c].append((x,y)) else: nodes[c] = [(x,y)] antinodes = set() for freq in nodes: print(f'Find all possible slopes given the starting positions of {freq}') for x,y in nodes[freq]: cur = (x,y) slopes = [slope(cur, (ox, oy)) for ox, oy in nodes[freq]] slopes = list(filter(lambda i: i != (0,0), slopes)) antis = [(x + (i[0]*2), y+ (i[1]*2)) for i in slopes] antis = list(filter(lambda i: inside(i, (len(grid[0]), len(grid[1]))), antis)) for a in antis: if a in nodes: print('found', a) antinodes.add(a) print(cur, '-->', slopes, 'antis ==>', antis) print('Total', len(antinodes))