feat: day 3 part 2 done

This commit is contained in:
dqnid committed 2026-08-26 20:14:44 +02:00
1 parent 574660bced
commit 9efaa1db79
4 files changed
+90 -5

No files matched your search

+2 -2
View File
@@ -5,10 +5,10 @@
## Progress ## Progress
| Day | Name | Part 1 | Part 2 | | Day | Name | Part 1 | Part 2 |
| :-: | :------------------ | :----: | :----: | | :-: | :--- | :----: | :----: |
| 1 | | ⭐ | ⭐ | | 1 | | ⭐ | ⭐ |
| 2 | | ⭐ | ⭐ | | 2 | | ⭐ | ⭐ |
| 3 | | ⭐ | | | 3 | | ⭐ | ⭐ |
| 4 | | | | | 4 | | | |
| 5 | | | | | 5 | | | |
| 6 | | | | | 6 | | | |
+5
View File
@@ -1 +1,6 @@
iniconfig==2.3.0
packaging==26.3
pluggy==1.6.0
Pygments==2.21.0
pytest==9.1.1
ruff==0.16.4 ruff==0.16.4
+5
View File
@@ -4,3 +4,8 @@ from src.modules.day_3 import Engine
def test_engine_parts(): def test_engine_parts():
engine = Engine(r"src/assets/day_3_test.txt") engine = Engine(r"src/assets/day_3_test.txt")
assert engine.sum_part_numbers() == 4361 assert engine.sum_part_numbers() == 4361
def test_gear_ratio():
engine = Engine(r"src/assets/day_3_test.txt")
assert engine.get_gear_ratio() == 467835
+78 -3
View File
@@ -1,22 +1,48 @@
from functools import total_ordering
def run(): def run():
engine = Engine(r"src/assets/day_3.txt") engine = Engine(r"src/assets/day_3.txt")
print(f"Part number sum: {engine.sum_part_numbers()}") print(f"Part number sum: {engine.sum_part_numbers()}")
print(f"Gear ratio: {engine.get_gear_ratio()}")
class Engine: class Engine:
engine: list[str] engine: list[str]
neutral_char = "." neutral_char: str = "."
gear_char: str = "*"
def __init__(self, path: str): def __init__(self, path: str):
self.engine = self.read_engine(path) self.engine = self.read_engine(path)
def get_gear_ratio(self) -> int:
sum = 0
for x in range(self.engine.__len__()):
for y in range(self.engine[x].__len__()):
gear = self.position_is_gear(x, y)
if gear[0] == True:
n_1 = self.extract_number_from_position(
gear[1][0][0], gear[1][0][1]
)
n_2 = self.extract_number_from_position(
gear[1][1][0], gear[1][1][1]
)
sum += n_1[0] * n_2[0]
return sum
def sum_part_numbers(self) -> int: def sum_part_numbers(self) -> int:
sum = 0 sum = 0
for x in range(self.engine.__len__()): for x in range(self.engine.__len__()):
y = 0 y = 0
while y < self.engine[x].__len__(): while y < self.engine[x].__len__():
if self.engine[x][y] != self.neutral_char and not self.position_is_symbol(x,y) and self.position_has_part(x,y): if (
number_pos = self.extract_number_from_position(x,y) self.engine[x][y] != self.neutral_char
and not self.position_is_symbol(x, y)
and self.position_has_part(x, y)
):
number_pos = self.extract_number_from_position(x, y)
sum += number_pos[0] sum += number_pos[0]
y = number_pos[1] - 1 y = number_pos[1] - 1
y += 1 y += 1
@@ -35,6 +61,53 @@ class Engine:
return (int(n), y) return (int(n), y)
def position_is_gear(self, x: int, y: int) -> tuple[bool, list[tuple[int, int]]]:
if x >= self.engine.__len__() or x < 0 or y >= self.engine.__len__() or y < 0:
return (False, [])
if self.engine[x][y] != self.gear_char:
return (False, [])
total_numbers = 0
position_number: list[tuple[int, int]] = []
b = self.position_is_number(x + 1, y)
t = self.position_is_number(x - 1, y)
r = self.position_is_number(x, y + 1)
l = self.position_is_number(x, y - 1)
bl = self.position_is_number(x + 1, y - 1)
br = self.position_is_number(x + 1, y + 1)
tl = self.position_is_number(x - 1, y - 1)
tr = self.position_is_number(x - 1, y + 1)
if r is True:
position_number.append((x, y + 1))
total_numbers += 1
if l is True:
position_number.append((x, y - 1))
total_numbers += 1
if tl is True:
position_number.append((x - 1, y - 1))
total_numbers += 1
elif t is True:
position_number.append((x - 1, y))
total_numbers += 1
if tr is True and t is not True:
position_number.append((x - 1, y + 1))
total_numbers += 1
if bl is True:
position_number.append((x + 1, y - 1))
total_numbers += 1
elif b is True:
position_number.append((x + 1, y))
total_numbers += 1
if br is True and b is not True:
position_number.append((x + 1, y + 1))
total_numbers += 1
return (total_numbers == 2, position_number)
def position_has_part(self, x: int, y: int) -> bool: def position_has_part(self, x: int, y: int) -> bool:
return ( return (
@@ -58,6 +131,8 @@ class Engine:
return self.engine[x][y] != self.neutral_char return self.engine[x][y] != self.neutral_char
def position_is_number(self, x: int, y: int) -> bool: def position_is_number(self, x: int, y: int) -> bool:
if x >= self.engine.__len__() or x < 0 or y >= self.engine.__len__() or y < 0:
return False
try: try:
int(self.engine[x][y]) int(self.engine[x][y])
return True return True