Skip to content

Instantly share code, notes, and snippets.

@unbibium
Last active December 12, 2021 15:00
Show Gist options
  • Save unbibium/f52f6cea4fee961b0850d43da8199f97 to your computer and use it in GitHub Desktop.
Save unbibium/f52f6cea4fee961b0850d43da8199f97 to your computer and use it in GitHub Desktop.
AoC 2021 day 12: path finding
#!/usr/bin/env python3
#
# https://adventofcode.com/2021/day/12
import sys, os,math
from collections import defaultdict
def walk(routes, path, double=None):
for dst in routes[path[-1]]:
if dst == 'end':
yield path + [dst]
elif dst.isupper() or (dst not in path):
yield from walk(routes, path + [dst], double)
elif dst == 'start':
continue
elif double is None and path.count(dst) == 1:
yield from walk(routes, path + [dst], dst)
def build_routes(lines):
routes = defaultdict(set)
for line in lines:
src,dst = line.rstrip().split('-')
routes[src].add(dst)
if src != 'start': #start is one-way
routes[dst].add(src) # all others are two-way
return routes
def part1(routes):
return len(list(walk(routes,['start'],'start')))
def part2(lines):
return len(list(walk(routes,['start'])))
if __name__ == '__main__':
if len(sys.argv)<2:
print("Usage",sys.argv[0],"filename")
sys.exit(1)
with open(sys.argv[1]) as f:
lines = f.readlines()
routes = build_routes(lines)
print("part1:", part1(routes))
print("part1:", part2(routes))
@unbibium
Copy link
Author

optimized a bit -- now using the part 2 function for both parts. for part 1, to stop it from going down any small caves twice, you just have to tell it that it's already seen "start" twice. I wonder if I could have named any variables or functions any better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment