Last active
December 12, 2021 15:00
-
-
Save unbibium/f52f6cea4fee961b0850d43da8199f97 to your computer and use it in GitHub Desktop.
AoC 2021 day 12: path finding
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.