refactor: python abandoned as not required enymore and rust project init
This commit is contained in:
1 parent
ac13078bd0
commit
1de8cf22e9
27 files changed
+20
-21
No files matched your search
@@ -0,0 +1,144 @@
|
||||
from functools import total_ordering
|
||||
|
||||
|
||||
def run():
|
||||
engine = Engine(r"src/assets/day_3.txt")
|
||||
print(f"Part number sum: {engine.sum_part_numbers()}")
|
||||
print(f"Gear ratio: {engine.get_gear_ratio()}")
|
||||
|
||||
|
||||
class Engine:
|
||||
engine: list[str]
|
||||
neutral_char: str = "."
|
||||
gear_char: str = "*"
|
||||
|
||||
def __init__(self, path: str):
|
||||
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:
|
||||
sum = 0
|
||||
for x in range(self.engine.__len__()):
|
||||
y = 0
|
||||
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)
|
||||
):
|
||||
number_pos = self.extract_number_from_position(x, y)
|
||||
sum += number_pos[0]
|
||||
y = number_pos[1] - 1
|
||||
y += 1
|
||||
|
||||
return sum
|
||||
|
||||
def extract_number_from_position(self, x: int, y: int) -> tuple[int, int]:
|
||||
n = ""
|
||||
while self.position_is_number(x, y):
|
||||
y -= 1
|
||||
|
||||
y += 1
|
||||
while self.position_is_number(x, y):
|
||||
n += self.engine[x][y]
|
||||
y += 1
|
||||
|
||||
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:
|
||||
return (
|
||||
self.position_is_symbol(x + 1, y)
|
||||
or self.position_is_symbol(x - 1, y)
|
||||
or self.position_is_symbol(x, y + 1)
|
||||
or self.position_is_symbol(x, y - 1)
|
||||
or self.position_is_symbol(x + 1, y + 1)
|
||||
or self.position_is_symbol(x - 1, y - 1)
|
||||
or self.position_is_symbol(x + 1, y - 1)
|
||||
or self.position_is_symbol(x - 1, y + 1)
|
||||
)
|
||||
|
||||
def position_is_symbol(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:
|
||||
int(self.engine[x][y])
|
||||
return False
|
||||
except:
|
||||
return self.engine[x][y] != self.neutral_char
|
||||
|
||||
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:
|
||||
int(self.engine[x][y])
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
def read_engine(self, path: str) -> list[str]:
|
||||
with open(path) as file:
|
||||
return file.readlines()
|
||||
Reference in new issue
Block a user