Solve 2021:12 "Passage Pathing"
I struggled a lot with the direction, but realised way too much later that the mappings are bidirectional. Part 2 was exceptionally hard, but I realised early that the order did not matter and that a simple boolean lock was all that was needed. The challenge was to know when to watch for duplicates. The seen was initially a set, but since new sets must be sent instead of references, a list is used instead to be able to use the seen + [] hack.
This commit is contained in:
parent
b53c50addc
commit
c0d352cdf1
2 changed files with 129 additions and 0 deletions
54
2021-python/solutions/day_12.py
Normal file
54
2021-python/solutions/day_12.py
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
from solutions import BaseSolution
|
||||
from collections import defaultdict, deque, Counter
|
||||
|
||||
|
||||
class Solution(BaseSolution):
|
||||
input_file = "12.txt"
|
||||
|
||||
def __str__(self):
|
||||
return "Day 12: Passage Pathing"
|
||||
|
||||
def parse_input(self, data):
|
||||
return [l.split("-") for l in data.split()]
|
||||
|
||||
def solve(self, puzzle_input):
|
||||
return self._solve(puzzle_input, lambda seen: True)
|
||||
|
||||
def solve_again(self, puzzle_input):
|
||||
return self._solve(
|
||||
puzzle_input,
|
||||
lambda seen: any(
|
||||
[
|
||||
k.islower() and k != "start" and v > 1
|
||||
for k, v in Counter(seen).items()
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
def _solve(self, puzzle_input, isdup):
|
||||
ft = defaultdict(lambda: [])
|
||||
for f, t in puzzle_input:
|
||||
ft[f].append(t)
|
||||
for f, t in puzzle_input:
|
||||
ft[t].append(f)
|
||||
queue = deque([("start", list(), False)])
|
||||
s2e = 0
|
||||
while queue:
|
||||
pos, seen, dup = queue.pop()
|
||||
seen.append(pos)
|
||||
dup = isdup(seen)
|
||||
for t in ft[pos]:
|
||||
if t == "end":
|
||||
s2e += 1
|
||||
continue
|
||||
elif t == "start":
|
||||
continue
|
||||
elif dup and t.islower() and t in seen:
|
||||
continue
|
||||
queue.append((t, seen + [], dup))
|
||||
return s2e
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
solution = Solution()
|
||||
solution.show_results()
|
||||
75
2021-python/tests/test_day_12.py
Normal file
75
2021-python/tests/test_day_12.py
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import unittest
|
||||
|
||||
from solutions.day_12 import Solution
|
||||
|
||||
|
||||
class Day12TestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.solution = Solution()
|
||||
self.puzzle_input = self.solution.parse_input(
|
||||
"""
|
||||
start-A
|
||||
start-b
|
||||
A-c
|
||||
A-b
|
||||
b-d
|
||||
A-end
|
||||
b-end
|
||||
"""
|
||||
)
|
||||
|
||||
def test_parse_puzzle_input(self):
|
||||
data = """
|
||||
a-b
|
||||
q1w2-e3r4
|
||||
"""
|
||||
assert self.solution.parse_input(data) == [["a", "b"], ["q1w2", "e3r4"]]
|
||||
|
||||
def test_solve_first_part(self):
|
||||
assert self.solution.solve(self.puzzle_input) == 10
|
||||
|
||||
def test_solve_second_part(self):
|
||||
assert self.solution.solve_again(self.puzzle_input) == 36
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
"""
|
||||
start,A,b,A,b,A,c,A,end
|
||||
start,A,b,A,b,A,end
|
||||
start,A,b,A,b,end
|
||||
start,A,b,A,c,A,b,A,end
|
||||
start,A,b,A,c,A,b,end
|
||||
start,A,b,A,c,A,c,A,end
|
||||
start,A,b,A,c,A,end
|
||||
start,A,b,A,end
|
||||
start,A,b,d,b,A,c,A,end
|
||||
start,A,b,d,b,A,end
|
||||
start,A,b,d,b,end
|
||||
start,A,b,end
|
||||
start,A,c,A,b,A,b,A,end
|
||||
start,A,c,A,b,A,b,end
|
||||
start,A,c,A,b,A,c,A,end
|
||||
start,A,c,A,b,A,end
|
||||
start,A,c,A,b,d,b,A,end
|
||||
start,A,c,A,b,d,b,end
|
||||
start,A,c,A,b,end
|
||||
start,A,c,A,c,A,b,A,end
|
||||
start,A,c,A,c,A,b,end
|
||||
start,A,c,A,c,A,end
|
||||
start,A,c,A,end
|
||||
start,A,end
|
||||
start,b,A,b,A,c,A,end
|
||||
start,b,A,b,A,end
|
||||
start,b,A,b,end
|
||||
start,b,A,c,A,b,A,end
|
||||
start,b,A,c,A,b,end
|
||||
start,b,A,c,A,c,A,end
|
||||
start,b,A,c,A,end
|
||||
start,b,A,end
|
||||
start,b,d,b,A,c,A,end
|
||||
start,b,d,b,A,end
|
||||
start,b,d,b,end
|
||||
start,b,end
|
||||
"""
|
||||
Loading…
Add table
Reference in a new issue