-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday12.py
53 lines (46 loc) · 1.41 KB
/
day12.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
"""
--- Day 12: Passage Pathing ---
https://adventofcode.com/2021/day/12
Start: 05:26 Part 1: 05:44 Part 2: 05:47
"""
from collections import defaultdict
import aocd
DATA = [line.split('-') for line in aocd.data.splitlines()]
# construct the corresponding graph as an adjacency list
G = defaultdict(list)
for u, v in DATA:
G[u].append(v)
G[v].append(u)
# DFS to enumerate all the valid paths
count = 0
S = [["start"]]
while S:
path = S.pop()
for v in G[path[-1]]:
if v == "end":
count += 1
continue
# valid paths visit small caves at most once and can visit big caves any number of times
if v.islower() and v in path:
continue
S.append(path + [v])
print("Part One", count)
# DFS to enumerate all the valid paths
count = 0
S = [(["start"], False)] # an element consists of the path and whether it contains a small cave twice
while S:
path, dup = S.pop()
for v in G[path[-1]]:
if v == "end":
count += 1
continue
if v == "start":
continue
# valid paths visit at most one small cave twice and can visit big caves any number of times
if v.islower() and v in path:
if dup: # the path already contains a small cave twice
continue
S.append((path + [v], True))
else:
S.append((path + [v], dup))
print("Part Two", count)