Add day12

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2021-12-13 14:58:21 -08:00
parent 97a2d896f5
commit 7679363bb7
5 changed files with 143 additions and 0 deletions

87
day12/day12.py Executable file
View File

@@ -0,0 +1,87 @@
#!/usr/bin/env python3
import sys
from collections import defaultdict
from copy import deepcopy
from typing import DefaultDict, MutableMapping, Set
import pprint
import string
Vertices = DefaultDict[str, Set[str]]
SMALL = set(string.ascii_lowercase)
BIG = set(string.ascii_uppercase)
def is_small(cave: str):
s = set(cave)
return (s & SMALL) == s
def part1(vertices: Vertices):
small = {cave for cave in vertices.keys() if is_small(cave)}
big = set(vertices.keys()) - small
assert len(big & small) == 0
def find_paths(current: str, visited: Set[str] = set(), path: str = "") -> Set[str]:
visited = deepcopy(visited)
visited |= {current}
paths = set()
for vertex in vertices[current]:
if vertex == "end":
paths |= {path}
elif vertex in visited and vertex in small:
continue
else:
paths |= find_paths(vertex, visited, path + vertex)
return paths
paths = find_paths("start")
print(len(paths))
def part2(vertices: Vertices):
small = {cave for cave in vertices.keys() if is_small(cave)}
big = set(vertices.keys()) - small
assert len(big & small) == 0
def find_paths(
allowed: str,
current: str,
visited: MutableMapping[str, int] = defaultdict(lambda: 0),
path: str = "",
) -> Set[str]:
if current == allowed:
if visited[current] >= 2:
# This is a small cave and we've already visited it twice
return set()
elif current in small and visited[current]:
# Visited already
return set()
visited = deepcopy(visited)
visited[current] += 1
paths = set()
for vertex in vertices[current]:
if vertex == "end":
paths |= {path}
else:
paths |= find_paths(allowed, vertex, visited, path + vertex)
return paths
paths = set()
for allowed in small - {"start", "end"}:
paths |= find_paths(allowed, "start")
print(len(paths))
# Doing this comprehension so Mypy is happy
edges = [(a, b) for a, b in map(lambda l: l.strip().split("-"), sys.stdin)]
vertices: Vertices = defaultdict(set)
for a, b in edges:
vertices[a] |= {b}
vertices[b] |= {a}
print("Part 1")
part1(vertices)
print("Part 2")
part2(vertices)

7
day12/example.txt Normal file
View File

@@ -0,0 +1,7 @@
start-A
start-b
A-c
A-b
b-d
A-end
b-end

10
day12/example2.txt Normal file
View File

@@ -0,0 +1,10 @@
dc-end
HN-start
start-kj
dc-start
dc-HN
LN-dc
HN-end
kj-sa
kj-HN
kj-dc

18
day12/example3.txt Normal file
View File

@@ -0,0 +1,18 @@
fs-end
he-DX
fs-he
start-DX
pj-DX
end-zg
zg-sl
zg-pj
pj-he
RW-he
fs-DX
pj-RW
zg-RW
start-pj
he-WI
zg-he
pj-fs
start-RW

21
day12/input.txt Normal file
View File

@@ -0,0 +1,21 @@
ma-start
YZ-rv
MP-rv
vc-MP
QD-kj
rv-kj
ma-rv
YZ-zd
UB-rv
MP-xe
start-MP
zd-end
ma-UB
ma-MP
UB-xe
end-UB
ju-MP
ma-xe
zd-UB
start-xe
YZ-end