File size: 2,767 Bytes
a4da721
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
def read_input(file_path):
    with open(file_path, 'r') as f:
        return [line.strip() for line in f.readlines()]

def find_antennas(grid):
    antennas = {}
    for y in range(len(grid)):
        for x in range(len(grid[y])):
            if grid[y][x] not in '.':
                freq = grid[y][x]
                if freq not in antennas:
                    antennas[freq] = []
                antennas[freq].append((x, y))
    return antennas

def is_collinear(p1, p2, p3):
    x1, y1 = p1
    x2, y2 = p2
    x3, y3 = p3
    return (y2-y1)*(x3-x1) == (y3-y1)*(x2-x1)

def distance_squared(p1, p2):
    return (p2[0]-p1[0])**2 + (p2[1]-p1[1])**2

def find_antinodes_part1(grid, antennas):
    antinodes = set()
    height, width = len(grid), len(grid[0])
    
    for freq, positions in antennas.items():
        if len(positions) < 2:
            continue
            
        for i in range(len(positions)):
            for j in range(i+1, len(positions)):
                a1, a2 = positions[i], positions[j]
                
                # Check all points in the grid
                for y in range(height):
                    for x in range(width):
                        point = (x, y)
                        if point == a1 or point == a2:
                            continue
                            
                        if is_collinear(a1, a2, point):
                            d1 = distance_squared(point, a1)
                            d2 = distance_squared(point, a2)
                            if d1 == 2*d2 or d2 == 2*d1:
                                antinodes.add(point)
    
    return len(antinodes)

def find_antinodes_part2(grid, antennas):
    antinodes = set()
    height, width = len(grid), len(grid[0])
    
    for freq, positions in antennas.items():
        if len(positions) < 2:
            continue
            
        # Add antenna positions as antinodes if there are multiple antennas of same frequency
        antinodes.update(positions)
        
        # Check all points in the grid
        for y in range(height):
            for x in range(width):
                point = (x, y)
                
                # Count how many pairs of antennas this point is collinear with
                for i in range(len(positions)):
                    for j in range(i+1, len(positions)):
                        if is_collinear(positions[i], positions[j], point):
                            antinodes.add(point)
    
    return len(antinodes)

def solve(file_path):
    grid = read_input(file_path)
    antennas = find_antennas(grid)
    
    part1 = find_antinodes_part1(grid, antennas)
    part2 = find_antinodes_part2(grid, antennas)
    
    print(str(part1))
    print(str(part2))

solve("./input.txt")