from collections import defaultdict from tools.aoc import AOCDay from typing import Any, Dict, List def getCaveMap(lines: List[List[str]]) -> Dict[str, List[str]]: m = defaultdict(list) for l, r in lines: m[l].append(r) m[r].append(l) return m def getPaths(caveMap: Dict[str, List[str]], start: str, visited: set, noDouble: bool = True) -> List[List[str]]: paths = [] visited.add(start) for thisCave in caveMap[start]: if thisCave == 'start': continue if thisCave == 'end': paths.append(['end']) continue foundDouble = False if thisCave.islower() and thisCave in visited: if noDouble: continue foundDouble = True sub_paths = getPaths(caveMap, thisCave, visited.copy(), noDouble or foundDouble) for x in sub_paths: if 'end' in x: paths.append(x) return paths class Day(AOCDay): test_solutions_p1 = [10, 19, 226, 5076] test_solutions_p2 = [36, 103, 3509, 145643] def part1(self) -> Any: caveMap = getCaveMap(self.getInputAsArraySplit("-")) return len(getPaths(caveMap, 'start', set())) def part2(self) -> Any: caveMap = getCaveMap(self.getInputAsArraySplit("-")) return len(getPaths(caveMap, 'start', set(), False))