-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday3.py
109 lines (86 loc) · 2.76 KB
/
day3.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
import re;
# ******* Part 1 ********/
num_indices = dict()
matrix = []
size = 0
def sum_parts():
global size
row, sum = 0, 0
with (open("input3.txt") as file):
lines = [line.rstrip() for line in file]
size = len(lines)
for line in lines:
matrix.append(list(line))
indices = [(m.start(), m.end()) for m in re.finditer(r'\d+', line)]
if len(indices) != 0:
num_indices[row] = indices
row += 1
for row in num_indices:
for start, end in num_indices[row]:
if check_neighbours(row, start, end):
part = ''.join(matrix[row][start:end])
sum += int(part)
return sum
def check_neighbours(row, col, end_col):
valid_neighbours = False
single_digit = (
(-1, -1), (-1, 0), (-1, 1),
(0, -1), (0, 1),
(1, -1), (1, 0), (1, 1)
)
double_digit = single_digit + ((-1, 2), (0, 2), (1, 2))
triple_digit = double_digit + ((-1, 3), (0, 3), (1, 3))
if (end_col - col) == 3:
neighbours = triple_digit
elif (end_col - col) == 2:
neighbours = double_digit
else:
neighbours = triple_digit
for x, y in neighbours:
if row + x in range(size) and col + y in range(size):
if re.match(r'[^a-zA-Z0-9.]', matrix[row + x][col + y]):
valid_neighbours = True
return valid_neighbours
# ******* Part 2 ********/
def find_gear_ratios():
potential_gears = []
count, sum = 0, 0
for row in matrix:
indices = ([i for i, x in enumerate(row) if x == "*"])
if len(indices) != 0:
for index in indices:
potential_gears.append((count, index))
count += 1
for x, y in potential_gears:
gear_neighbours = find_gear_neighbours(x, y)
if gear_neighbours:
sum = sum + gear_parts_ratio(gear_neighbours)
return sum
def find_gear_neighbours(row, col):
neighbour_nums = []
neighbours = (
(-1, -1), (-1, 0), (-1, 1),
(0, -1), (0, 1),
(1, -1), (1, 0), (1, 1)
)
for x, y in neighbours:
if row + x in range(size) and col + y in range(size):
num = re.match(r'\d', matrix[row + x][col + y])
if num:
neighbour_nums.append((row + x, col + y))
if len(neighbour_nums) >= 2:
return neighbour_nums
else:
return False
def gear_parts_ratio(gear_neighbours):
parts = set()
ratio = 0
for row, col in gear_neighbours:
for start, end in num_indices[row]:
if start <= col <= end:
part = ''.join(matrix[row][start:end])
parts.add(part)
p = list(parts)
if len(parts) > 1:
ratio = int(p[0]) * int(p[1])
return ratio