File size: 3,035 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
def parse_input(file):
    with open(file, 'r') as f:
        grid = [line.strip() for line in f.readlines()]
    return grid

def find_antennas(grid):
    antennas = {}
    for y, row in enumerate(grid):
        for x, char in enumerate(row):
            if char != '.':
                if char not in antennas:
                    antennas[char] = []
                antennas[char].append((x, y))
    return antennas

def calculate_antinodes_part_one(antennas):
    antinodes = set()
    for freq, positions in antennas.items():
        n = len(positions)
        for i in range(n):
            for j in range(i + 1, n):
                x1, y1 = positions[i]
                x2, y2 = positions[j]
                # Check for antinodes on the line between (x1, y1) and (x2, y2)
                if x1 == x2:  # Vertical line
                    for y in range(min(y1, y2) - abs(y2 - y1), max(y1, y2) + abs(y2 - y1) + 1):
                        if y != y1 and y != y2:
                            antinodes.add((x1, y))
                elif y1 == y2:  # Horizontal line
                    for x in range(min(x1, x2) - abs(x2 - x1), max(x1, x2) + abs(x2 - x1) + 1):
                        if x != x1 and x != x2:
                            antinodes.add((x, y1))
                else:  # Diagonal line
                    dx = x2 - x1
                    dy = y2 - y1
                    for k in range(-max(abs(dx), abs(dy)), max(abs(dx), abs(dy)) + 1):
                        x = x1 + k * dx
                        y = y1 + k * dy
                        if (x, y) != (x1, y1) and (x, y) != (x2, y2):
                            antinodes.add((x, y))
    return antinodes

def calculate_antinodes_part_two(antennas):
    antinodes = set()
    for freq, positions in antennas.items():
        n = len(positions)
        for i in range(n):
            for j in range(i + 1, n):
                x1, y1 = positions[i]
                x2, y2 = positions[j]
                # Mark all points in line with at least two antennas
                if x1 == x2:  # Vertical line
                    for y in range(min(y1, y2), max(y1, y2) + 1):
                        antinodes.add((x1, y))
                elif y1 == y2:  # Horizontal line
                    for x in range(min(x1, x2), max(x1, x2) + 1):
                        antinodes.add((x, y1))
                else:  # Diagonal line
                    dx = x2 - x1
                    dy = y2 - y1
                    for k in range(max(abs(dx), abs(dy)) + 1):
                        x = x1 + k * (dx // abs(dx))
                        y = y1 + k * (dy // abs(dy))
                        antinodes.add((x, y))
    return antinodes

def main():
    file = "input.txt"
    grid = parse_input(file)
    antennas = find_antennas(grid)
    
    # Part One
    antinodes_part_one = calculate_antinodes_part_one(antennas)
    print(len(antinodes_part_one))
    
    # Part Two
    antinodes_part_two = calculate_antinodes_part_two(antennas)
    print(len(antinodes_part_two))

main()