From 5afb1de803675e818b76725e2213b3480f6c3779 Mon Sep 17 00:00:00 2001
From: Botond Hende <nettingman@gmail.com>
Date: Sat, 7 Dec 2024 11:08:24 +0100
Subject: fixed 2023 day3 solve2

---
 2023/day3/solve2.py | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)

(limited to '2023/day3')

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()
-- 
cgit v1.2.3-70-g09d2