diff --git a/aoc.py b/aoc.py new file mode 100644 index 0000000..835743d --- /dev/null +++ b/aoc.py @@ -0,0 +1,149 @@ +import os +from typing import List, Any, Type + +BASE_PATH = os.path.dirname(os.path.dirname(__file__)) +INPUTS_PATH = os.path.join(BASE_PATH, 'inputs') + + +class AOCDay: + day: int + input: List # our input is always a list of str/lines + test_solutions_p1: List + test_solutions_p2: List + + def __init__(self, day: int): + self.day = day + with open(os.path.join(INPUTS_PATH, "input%02d" % day)) as f: + self.input = f.read().splitlines() + + def part1(self) -> Any: + pass + + def part2(self) -> Any: + pass + + def test_part1(self, silent: bool = False) -> bool: + live_input = self.input.copy() + for case, solution in enumerate(self.test_solutions_p1): + with open(os.path.join(INPUTS_PATH, "test_input%02d_1_%d" % (self.day, case))) as f: + self.input = f.read().splitlines() + + check = self.part1() + if not silent: + printSolution(self.day, 1, check, solution, case) + + if check != solution: + if silent: + printSolution(self.day, 1, check, solution, case) + return False + + self.input = live_input + return True + + def test_part2(self, silent: bool = False) -> bool: + live_input = self.input.copy() + for case, solution in enumerate(self.test_solutions_p2): + with open(os.path.join(INPUTS_PATH, "test_input%02d_2_%d" % (self.day, case))) as f: + self.input = f.read().splitlines() + + check = self.part2() + if not silent: + printSolution(self.day, 2, check, solution, case) + + if check != solution: + if silent: + printSolution(self.day, 2, check, solution, case) + return False + + self.input = live_input + return True + + def getInputListAsType(self, return_type: Type) -> List: + """ + get input as list casted to return_type, each line representing one list entry + """ + return [return_type(i) for i in self.input] + + def getMultiLineInputAsArray(self, return_type: Type = None, join_char: str = None) -> List: + """ + get input for day x as 2d array, split by empty lines + """ + lines = self.input + lines.append('') + + return_array = [] + line_array = [] + for line in lines: + if not line: + if join_char: + return_array.append(join_char.join(line_array)) + else: + return_array.append(line_array) + line_array = [] + continue + + if return_type: + line_array.append(return_type(line)) + else: + line_array.append(line) + + return return_array + + def getInputAs2DArray(self, return_type: Type = None) -> List: + """ + get input for day x as 2d-array (a[line][pos]) + """ + if return_type is None: + return self.input # strings already act like a list + else: + return_array = [] + for line in self.input: + return_array.append([return_type(i) for i in line]) + + return return_array + + def getInputAsArraySplit(self, split_char: str = ',', return_type: Type = None) -> List: + """ + get input for day x with the lines split by split_char + if input has only one line, returns a 1d array with the values + if input has multiple lines, returns a 2d array (a[line][values]) + """ + if len(self.input) == 1: + return splitLine(line=self.input[0], split_char=split_char, return_type=return_type) + else: + return_array = [] + for line in self.input: + return_array.append(splitLine(line=line, split_char=split_char, return_type=return_type)) + + return return_array + + +def printSolution(day, part, solution, test=None, test_case=0, exec_time=None): + if exec_time is None: + time_output = "" + else: + units = ['s', 'ms', 'μs', 'ns'] + unit = 0 + while exec_time < 1: + exec_time *= 1000 + unit += 1 + + time_output = " (Average run time: %1.2f%s)" % (exec_time, units[unit]) + + if test is not None: + print( + "(TEST case%d/day%d/part%d) -- got '%s' -- expected '%s' -> %s" + % (test_case, day, part, solution, test, "correct" if test == solution else "WRONG") + ) + else: + print("Solution to day %s, part %s: %s%s" % (day, part, solution, time_output)) + + +def splitLine(line, split_char=',', return_type=None): + if split_char: + line = line.split(split_char) + + if return_type is None: + return line + else: + return [return_type(i) for i in line] diff --git a/setup.py b/setup.py index 74439f5..2aad0e9 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup setup( name='py-tools', - version='0.1', + version='0.2', packages=[''], url='', license='GPLv3',