refactor day 1
This commit is contained in:
parent
772de99197
commit
d20c76ce5c
|
|
@ -0,0 +1,66 @@
|
|||
from utils.load import get_input
|
||||
from utils.day import DayBase
|
||||
from dataclasses import dataclass
|
||||
import logging
|
||||
|
||||
@dataclass
|
||||
class Day01(DayBase):
|
||||
def __init__(self, *args, **kargs):
|
||||
super().__init__(*args, **kargs)
|
||||
|
||||
def parse_data(self, input: str):
|
||||
return input.splitlines()
|
||||
|
||||
def solve_part1(self, data: list[str])-> int:
|
||||
count = 0
|
||||
current = 50
|
||||
|
||||
for value in data:
|
||||
if value[0] == 'L':
|
||||
current = (current - int(value[1:])) % 100
|
||||
else:
|
||||
current = (current + int(value[1:])) % 100
|
||||
|
||||
if current == 0:
|
||||
count += 1
|
||||
logging.debug("%s -> %s (count: %s)", value, current, count)
|
||||
return count
|
||||
|
||||
def solve_part2(self, data: list[str]) -> int:
|
||||
count = 0
|
||||
current = 50
|
||||
for value in data:
|
||||
if value[0] == 'L':
|
||||
value = - int(value[1:])
|
||||
else:
|
||||
value = int(value[1:])
|
||||
|
||||
new_current = current + value
|
||||
div = abs(new_current) // 100
|
||||
nb_rotation = div
|
||||
if new_current < 0:
|
||||
if current != 0:
|
||||
nb_rotation += 1
|
||||
new_current += 100 * nb_rotation
|
||||
elif new_current > 0:
|
||||
new_current -= 100 * nb_rotation
|
||||
else:
|
||||
nb_rotation = 1
|
||||
new_current %= 100
|
||||
|
||||
print(f"{current} + {value} = {new_current} (+{nb_rotation})")
|
||||
current = new_current
|
||||
count += nb_rotation
|
||||
|
||||
return count
|
||||
|
||||
def test_custom_2_1(self):
|
||||
return self.solve_part2(["R48", "L498"]) == 5
|
||||
|
||||
def test_custom_2_2(self):
|
||||
assert self.solve_part2(["R1000"]) == 10
|
||||
|
||||
if __name__ == "__main__":
|
||||
day = Day01(1, "L68\nL30\nR48\nL5\nR60\nL55\nL1\nL99\nR14\nL82", excepted_part1 = 3, excepted_part2=6)
|
||||
day.run_tests()
|
||||
day.run()
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass
|
||||
from .load import get_input
|
||||
import logging
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
@dataclass
|
||||
class DayBase(ABC):
|
||||
day_number: int
|
||||
test_data: str
|
||||
excepted_part1: str
|
||||
excepted_part2: str
|
||||
|
||||
def __post_init__(self):
|
||||
if self.__class__ == DayBase:
|
||||
raise TypeError("Cannot instantiate abstract class.")
|
||||
|
||||
@abstractmethod
|
||||
def parse_data(self, input: str):
|
||||
pass
|
||||
|
||||
def test_part1(self):
|
||||
data = self.parse_data(self.test_data)
|
||||
assert self.solve_part1(data) == self.excepted_part1
|
||||
|
||||
def test_part2(self):
|
||||
data = self.parse_data(self.test_data)
|
||||
assert self.solve_part2(data) == self.excepted_part2
|
||||
|
||||
@abstractmethod
|
||||
def solve_part1(self, data):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def solve_part2(self, data):
|
||||
pass
|
||||
|
||||
def run_tests(self):
|
||||
classes = list(self.__class__.__bases__) + [self.__class__]
|
||||
for klass in classes:
|
||||
for element in klass.__dict__:
|
||||
if callable(getattr(self, element)) and element.startswith("test_"):
|
||||
logging.debug("Found test: %s", element)
|
||||
getattr(self, element)()
|
||||
|
||||
def run(self):
|
||||
data = self.parse_data(get_input(self.day_number))
|
||||
logging.info("Part 01 (day %s): %s", self.day_number, self.solve_part1(data))
|
||||
logging.info("Part 02 (day %s): %s", self.day_number, self.solve_part2(data))
|
||||
Loading…
Reference in New Issue