summaryrefslogtreecommitdiff
path: root/2023
diff options
context:
space:
mode:
Diffstat (limited to '2023')
-rw-r--r--2023/day3/solve2.py104
1 files changed, 104 insertions, 0 deletions
diff --git a/2023/day3/solve2.py b/2023/day3/solve2.py
index e69de29..5b23f13 100644
--- a/2023/day3/solve2.py
+++ b/2023/day3/solve2.py
@@ -0,0 +1,104 @@
+class Gear:
+ def __init__(self, line_idx, column_idx):
+ self.line_idx = line_idx
+ self.column_idx = column_idx
+ self.connecting_parts = []
+
+
+def add_part_to_gear(line_idx, column_idx, part_number_line_idx, part_number_column_idx, gears):
+ for gear in gears:
+ if gear.line_idx == line_idx and gear.column_idx == column_idx:
+ gear.connecting_parts.append((part_number_line_idx, part_number_column_idx))
+ break
+ else:
+ new_gear = Gear(line_idx, column_idx)
+ new_gear.connecting_parts.append((part_number_line_idx, part_number_column_idx))
+ gears.append(new_gear)
+
+
+def check_if_part_number(line_index, column_index, lines, gears):
+ ret_val = False
+
+ current_line = lines[line_index]
+ if column_index > 0 and current_line[column_index - 1] != ".":
+ if current_line[column_index - 1] == "*":
+ add_part_to_gear(line_index, column_index - 1, line_index, column_index, gears)
+ ret_val = True
+
+ max_column_index = column_index
+ for index in range(column_index + 1, len(current_line)):
+ if not current_line[index].isdigit():
+ break
+ max_column_index = index
+
+ if max_column_index + 1 < len(current_line) and current_line[max_column_index + 1] != ".":
+ if current_line[max_column_index + 1] == "*":
+ add_part_to_gear(line_index, column_index + 1, line_index, column_index, gears)
+ ret_val = True
+
+ min_other_column_index = max(column_index - 1, 0)
+ max_other_column_index = min(max_column_index + 1, len(current_line) - 1)
+
+ if line_index > 0:
+ other_line = lines[line_index - 1]
+ for current_column_index in range(min_other_column_index, max_other_column_index + 1):
+ other_char = other_line[current_column_index]
+ if not other_char.isdigit() and other_char != ".":
+ if other_char == "*":
+ add_part_to_gear(line_index - 1, current_column_index, line_index, column_index, gears)
+ ret_val = True
+
+ if line_index + 1 < len(lines):
+ other_line = lines[line_index + 1]
+ for current_column_index in range(min_other_column_index, max_other_column_index + 1):
+ other_char = other_line[current_column_index]
+ if not other_char.isdigit() and other_char != ".":
+ if other_char == "*":
+ add_part_to_gear(line_index + 1, current_column_index, line_index, column_index, gears)
+ ret_val = True
+
+ return ret_val
+
+
+def main():
+ lines = []
+ positions = []
+ gears = []
+ with open("input", "r") as f:
+ for line in f:
+ lines.append(line.strip())
+
+ part_numbers = []
+
+ parsed_number = None
+ is_part_number_parsed = False
+ for line_index, line in enumerate(lines):
+ for column_index, char in enumerate(line):
+ if not char.isdigit():
+ if is_part_number_parsed:
+ part_numbers.append(int(parsed_number))
+
+ parsed_number = None
+ is_part_number_parsed = False
+ elif parsed_number is not None:
+ parsed_number += char
+ else:
+ parsed_number = char
+ is_part_number_parsed = check_if_part_number(line_index, column_index, lines, gears)
+ if is_part_number_parsed:
+ positions.append((line_index, column_index))
+
+ if is_part_number_parsed:
+ part_numbers.append(int(parsed_number))
+ parsed_number = None
+ is_part_number_parsed = False
+
+ gears = [gear for gear in gears if len(gear.connecting_parts) == 2]
+ ratios = []
+ for gear in gears:
+ ratios.append(part_numbers[positions.index(gear.connecting_parts[0])] * part_numbers[positions.index(gear.connecting_parts[1])])
+ print(sum(ratios))
+
+
+if __name__ == '__main__':
+ main()