aoc.AOCDay: introduce class variable "DP", a dictionary that gets reset before every part method call, useful for memoization problems

This commit is contained in:
Stefan Harmuth 2024-01-03 05:46:24 +01:00
parent 87fbaeafbe
commit cf72a5451f

View File

@ -31,6 +31,7 @@ class AOCDay:
self.part_func = [self.part1, self.part2]
self._current_test_file = None
self._current_test_solution = None
self.DP = {}
self.__main_progress_bar_id = None
self.__main_progress_bar_pos = 0
self.progress_bars = {}
@ -66,27 +67,25 @@ class AOCDay:
self._load_input(input_file)
if not measure_runtime or case_count < len(self.inputs[part]) - 1:
self.DP = {}
answer = self._call_part_func(self.part_func[part])
else:
stopwatch = StopWatch(auto_start=False)
self.__main_progress_bar_pos = 1
for _ in tqdm(range(timeit_number), desc=f"Part {part+1}", leave=False):
self.DP = {}
stopwatch.start()
answer = self._call_part_func(self.part_func[part])
stopwatch.stop()
exec_time = stopwatch.avg_string(timeit_number)
if solution is None:
print_solution(
self.day, part + 1, answer, solution, case_count, exec_time
)
print_solution(self.day, part + 1, answer, solution, case_count, exec_time)
if answer not in {"", b"", None, b"None", "None", 0, "0"}:
self._submit(part + 1, answer)
else:
if verbose or answer != solution:
print_solution(
self.day, part + 1, answer, solution, case_count, exec_time
)
print_solution(self.day, part + 1, answer, solution, case_count, exec_time)
if answer != solution:
return False
@ -126,10 +125,7 @@ class AOCDay:
cookies={"session": session_id},
)
if not response.ok:
print(
"FAILED to download input: (%s) %s"
% (response.status_code, response.text)
)
print("FAILED to download input: (%s) %s" % (response.status_code, response.text))
return
with open(filename, "wb") as f:
@ -172,10 +168,7 @@ class AOCDay:
)
if not response.ok:
print(
"Failed to submit answer: (%s) %s"
% (response.status_code, response.text)
)
print("Failed to submit answer: (%s) %s" % (response.status_code, response.text))
soup = BeautifulSoup(response.text, "html.parser")
message = soup.article.text
@ -183,9 +176,7 @@ class AOCDay:
answer_cache[str_day][str_part]["correct"] = answer
has_rank = re.findall(r"You achieved.*rank (\d+)", message)
print("That's correct!%s" % f" (Rank {has_rank[0]})" if has_rank else "")
webbrowser.open(
"https://adventofcode.com/%d/day/%d#part2" % (self.year, self.day)
)
webbrowser.open("https://adventofcode.com/%d/day/%d#part2" % (self.year, self.day))
elif "That's not the right answer" in message:
hilo = re.findall("your answer is too (high|low)", message)
answer_cache[str_day][str_part]["wrong"].append(answer)
@ -233,9 +224,7 @@ class AOCDay:
else:
return [list(map(int, re.findall(r"-?\d+", l))) for l in self.input]
def getMultiLineInputAsArray(
self, return_type: Type = None, join_char: str = None
) -> list[list[Any]]:
def getMultiLineInputAsArray(self, return_type: Type = None, join_char: str = None) -> list[list[Any]]:
"""
get input for day x as 2d array, split by empty lines
"""
@ -269,17 +258,11 @@ class AOCDay:
if input has multiple lines, returns a 2d array (a[line][values])
"""
if len(self.input) == 1:
return split_line(
line=self.input[0], split_char=split_char, return_type=return_type
)
return split_line(line=self.input[0], split_char=split_char, return_type=return_type)
else:
return_array = []
for line in self.input:
return_array.append(
split_line(
line=line, split_char=split_char, return_type=return_type
)
)
return_array.append(split_line(line=line, split_char=split_char, return_type=return_type))
return return_array
@ -343,8 +326,6 @@ def split_line(line, split_char: str = ",", return_type: Type | list[Type] = Non
if return_type is None:
return line
elif isinstance(return_type, list):
return [
return_type[x](i) if len(return_type) > x else i for x, i in enumerate(line)
]
return [return_type[x](i) if len(return_type) > x else i for x, i in enumerate(line)]
else:
return [return_type(i) for i in line]