-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path3.py
131 lines (108 loc) · 4.11 KB
/
3.py
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
test_case = r"""467..114..
...*......
..35..633.
......\...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598.."""
def create_grid(test_case):
grid = []
for line in test_case.split('\n'):
if line:
grid.append(list(line))
return grid
def get_adjacent_cells(cell: tuple, grid):
x, y = cell
adjacent_cells = []
if x > 0:
adjacent_cells.append((x-1, y))
if y > 0:
adjacent_cells.append((x, y-1))
if x < len(grid[0])-1:
adjacent_cells.append((x+1, y))
if y < len(grid)-1:
adjacent_cells.append((x, y+1))
if x > 0 and y > 0:
adjacent_cells.append((x-1, y-1))
if x < len(grid[0])-1 and y > 0:
adjacent_cells.append((x+1, y-1))
if x > 0 and y < len(grid)-1:
adjacent_cells.append((x-1, y+1))
if x < len(grid[0])-1 and y < len(grid)-1:
adjacent_cells.append((x+1, y+1))
return adjacent_cells
def find_digit_coords(grid: list) -> list:
coords = []
for y, row in enumerate(grid):
for x, cell in enumerate(row):
if cell.isdigit():
coords.append((x, y))
return coords
def check_adjecent_cells_for_symbols(adjacent_cells: list, grid) -> bool:
for adjacent_cell in adjacent_cells:
x, y = adjacent_cell
cell_char = grid[y][x]
if not cell_char.isdigit() and not cell_char == '.':
#print(f"Found symbol {cell_char} at {adjacent_cells}")
return True
#print(f"No symbols found at {adjacent_cells}")
return False
def expand_num(coord, grid):
x, y = coord
if not grid[y][x].isdigit():
print(f"No digit at starting coordinate ({x}, {y})")
return 0 # Return 0 if the starting coordinate is not a digit
number = ""
# Move left to the start of the number
while x > 0 and grid[y][x-1].isdigit():
x -= 1
# Expand the number
while x < len(grid[0]) and grid[y][x].isdigit():
number += grid[y][x]
print(f"Expanding number at ({x}, {y}): {number}")
x += 1
return int(number) if number else 0
def process_grid(input_grid: str) -> int:
tot_sum = 0
grid = create_grid(input_grid)
num_coords = find_digit_coords(grid)
processed = set()
for num_coord in num_coords:
if num_coord not in processed:
adjacent_cells = get_adjacent_cells(num_coord, grid)
if check_adjecent_cells_for_symbols(adjacent_cells, grid):
number = expand_num(num_coord, grid)
tot_sum += number
x, y = num_coord
while x >= 0 and y >= 0 and y < len(grid) and x < len(grid[0]) and grid[y][x].isdigit():
processed.add((x, y))
x += 1
return tot_sum
#print(process_grid(test_case))
# >>> 4361 (its working!)
with open("input_3.txt", 'r') as f:
input_grid = f.read()
#print(process_grid(input_grid))
def calculate_gear_ratios(grid: list) -> int:
total_ratio = 0
for y, row in enumerate(grid):
for x, cell in enumerate(row):
if cell == '*':
print(f"Checking * at ({x}, {y})")
adjacent_numbers = []
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (-1, 1), (1, -1), (1, 1)]:
nx, ny = x + dx, y + dy
if 0 <= nx < len(grid[0]) and 0 <= ny < len(grid):
print(f"Checking adjacent cell at ({nx}, {ny}), character: '{grid[ny][nx]}'")
if grid[ny][nx].isdigit():
num = expand_num((nx, ny), grid)
adjacent_numbers.append(num)
print(f"Adjacent number at ({nx}, {ny}): {num}")
if len(adjacent_numbers) == 2:
print(f"Gear at ({x}, {y}) with numbers {adjacent_numbers}")
total_ratio += adjacent_numbers[0] * adjacent_numbers[1]
return total_ratio
print(calculate_gear_ratios(create_grid(test_case)))