-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDay_03.py
More file actions
133 lines (101 loc) · 3.83 KB
/
Day_03.py
File metadata and controls
133 lines (101 loc) · 3.83 KB
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
132
133
from time import perf_counter
start_time = perf_counter()
def open_file(file_name: str = "Day_03.txt") -> str:
with open(file_name) as f:
return f.read()
def get_neighbors(
row_index: int, col_index: int, row_len: int, col_len: int
) -> list[tuple[int, int]]:
neighbors = []
for row in (-1, 0, 1):
for col in (-1, 0, 1):
adj_row = row + row_index
adj_col = col + col_index
if (
0 <= adj_row < row_len
and 0 <= adj_col < col_len
and (row, col) != (0, 0)
):
neighbors.append((adj_row, adj_col))
return neighbors
def get_adjacent_numbers_set(lines: list[str]) -> set[tuple[int, int]]:
row_len = len(lines)
col_len = len(lines[0])
numbers_set = set()
for row_index, row in enumerate(lines):
for column_index, column in enumerate(row):
if not column.isnumeric() and column != ".":
neighbors = get_neighbors(row_index, column_index, row_len, col_len)
for neighbor in neighbors:
neigh_row = neighbor[0]
neigh_col = neighbor[1]
if lines[neigh_row][neigh_col].isnumeric():
numbers_set.add(neighbor)
return numbers_set
def complete_the_number(
lines: list[str], point: tuple[int, int]
) -> tuple[int, set[tuple[int, int]]]:
row = point[0]
column = point[1]
num_string = ""
seen = set()
while column >= 0 and lines[row][column].isnumeric():
num_string = lines[row][column] + num_string
seen.add((row, column))
column = column - 1
column = point[1] + 1
while column < len(lines[0]) and lines[row][column].isnumeric():
num_string = num_string + lines[row][column]
seen.add((row, column))
column = column + 1
return int(num_string), seen
def sum_the_numbers(
lines: list[str], adjacent_numbers_set: set[tuple[int, int]]
) -> int:
seen = set()
row_len = len(lines)
col_len = len(lines[0])
result = 0
for row in range(row_len):
for col in range(col_len):
point = (row, col)
if point in adjacent_numbers_set and point not in seen:
num, new_seen = complete_the_number(lines, (point))
result += num
seen.update(new_seen)
return result
def get_gear_powers(lines: list[str]) -> list[int]:
row_len = len(lines)
col_len = len(lines[0])
numbers_list = []
for row_index, row in enumerate(lines):
for column_index, character in enumerate(row):
if character == "*":
resulting_set = set()
total_seen = set()
neighbors = get_neighbors(row_index, column_index, row_len, col_len)
for neighbor in neighbors:
neigh_row = neighbor[0]
neigh_col = neighbor[1]
if lines[neigh_row][neigh_col].isnumeric():
num, seen = complete_the_number(lines, neighbor)
if neighbor not in total_seen:
resulting_set.add(num)
total_seen.update(seen)
if len(resulting_set) == 2:
result = 1
for num in resulting_set:
result *= num
numbers_list.append(result)
return numbers_list
def part_one(lines: list[str]) -> int:
return sum_the_numbers(lines, get_adjacent_numbers_set(lines))
def part_two(lines: list[str]) -> int:
return sum(get_gear_powers(lines))
def main():
lines = open_file().splitlines()
print("Part 1: ", part_one(lines))
print("Part 2: ", part_two(lines))
if __name__ == "__main__":
main()
print("Time elapsed: ", perf_counter() - start_time)