diff --git a/12/a.py b/12/a.py new file mode 100644 index 0000000..2ca7a82 --- /dev/null +++ b/12/a.py @@ -0,0 +1,52 @@ +class Node(object): + def __init__(self, name): + self.name = name + self.links = [] + self.small = self.name == self.name.lower() + + def __repr__(self): + return "<{}>".format(self.name) + + +nodes = {} + + +# with open("sample.txt") as f: +with open("input.txt") as f: + for line in f.readlines(): + a, b = line.strip().split("-") + if a not in nodes: + nodes[a] = Node(a) + if b not in nodes: + nodes[b] = Node(b) + nodes[a].links.append(nodes[b]) + nodes[b].links.append(nodes[a]) + + +paths = [] + + +def step(node, path, visited): + # append node to the path + path.append(node) + + # if we just hit the end, emit the path + if node.name == "end": + paths.append(path) + return + + # append node to visited + if node.small: + visited.update([node.name]) + + # look for legal next nodes + legal = [n for n in node.links if n.name not in visited] + + # call step for each + for next_step in legal: + step(next_step, path[:], set(visited)) + + +step(nodes["start"], [], set()) + +print(len(paths)) diff --git a/12/b.py b/12/b.py new file mode 100644 index 0000000..8a756f5 --- /dev/null +++ b/12/b.py @@ -0,0 +1,64 @@ +from collections import defaultdict + + +class Node(object): + def __init__(self, name): + self.name = name + self.links = [] + self.small = self.name == self.name.lower() + + def __repr__(self): + return "<{}>".format(self.name) + + +nodes = {} + + +# with open("sample.txt") as f: +with open("input.txt") as f: + for line in f.readlines(): + a, b = line.strip().split("-") + if a not in nodes: + nodes[a] = Node(a) + if b not in nodes: + nodes[b] = Node(b) + nodes[a].links.append(nodes[b]) + nodes[b].links.append(nodes[a]) + + +paths = [] + + +def step(node, path, visited): + # append node to the path + path.append(node) + + # if we just hit the end, emit the path + if node.name == "end": + paths.append(path) + return + + # append node to visited + if node.small: + visited[node.name] += 1 + + # look for legal next nodes + legal = [n for n in node.links if n.name not in visited] + + # call step for each + for next_step in legal: + step(next_step, path[:], defaultdict(lambda: 0, visited)) + + # use a small cave a second time, if possible + if all([v <= 1 for v in visited.values()]): + legal = [n for n in node.links if n.name in visited and n.small and n != nodes["start"]] + + for next_step in legal: + step(next_step, path[:], defaultdict(lambda: 0, visited)) + + +step(nodes["start"], [], defaultdict(lambda: 0)) + +print(len(paths)) + +#35m diff --git a/12/input.txt b/12/input.txt new file mode 100644 index 0000000..4a1ba87 --- /dev/null +++ b/12/input.txt @@ -0,0 +1,22 @@ +FK-gc +gc-start +gc-dw +sp-FN +dw-end +FK-start +dw-gn +AN-gn +yh-gn +yh-start +sp-AN +ik-dw +FK-dw +end-sp +yh-FK +gc-gn +AN-end +dw-AN +gn-sp +gn-FK +sp-FK +yh-gc diff --git a/12/sample.txt b/12/sample.txt new file mode 100644 index 0000000..898cd56 --- /dev/null +++ b/12/sample.txt @@ -0,0 +1,7 @@ +start-A +start-b +A-c +A-b +b-d +A-end +b-end \ No newline at end of file