--- /dev/null
+""" Count number of paths through caves """
+from collections import defaultdict
+
+def walk_from_node(current_node, path_taken_so_far):
+ possible_paths = []
+ for node in caves[current_node]:
+ if node == "end":
+ possible_paths.append(path_taken_so_far + ["end"])
+ elif node == node.lower() and node in path_taken_so_far:
+ pass
+ else:
+ possible_paths += walk_from_node(node, path_taken_so_far + [current_node])
+
+ return possible_paths
+
+caves = defaultdict(set)
+
+with open("12_input.txt") as f:
+ for line in f:
+ node_a, node_b = line.strip().split("-")
+
+ caves[node_a].add(node_b)
+ caves[node_b].add(node_a)
+
+walked_paths = walk_from_node("start", [])
+print(len(walked_paths))
+
+filtered_walked_paths = [path for path in walked_paths if path[-1] == "end"]
+print(len(filtered_walked_paths))
--- /dev/null
+""" Count number of paths through caves """
+import pprint
+from collections import defaultdict
+
+def walk_from_node(current_node, path_taken_so_far, visited_small_cave_twice=False):
+ possible_paths = []
+ for node in caves[current_node]:
+ if node == "start":
+ pass
+ elif node == "end":
+ possible_paths.append(path_taken_so_far + ["end"])
+ elif node == node.lower() and node in path_taken_so_far:
+ if not visited_small_cave_twice:
+ possible_paths += walk_from_node(node, path_taken_so_far + [current_node], True)
+ else:
+ possible_paths += walk_from_node(node, path_taken_so_far + [current_node], visited_small_cave_twice)
+
+ return possible_paths
+
+caves = defaultdict(set)
+
+with open("12_input.txt") as f:
+ for line in f:
+ node_a, node_b = line.strip().split("-")
+
+ caves[node_a].add(node_b)
+ caves[node_b].add(node_a)
+
+walked_paths = walk_from_node("start", [])
+print(len(walked_paths))
--- /dev/null
+""" Count the dots on slightly folded transparent paper """
+
+dots = set()
+with open("13_input.txt") as f:
+ for line in f:
+ if line.strip() == "":
+ break
+ else:
+ dots.add(tuple(int(a) for a in line.split(",")))
+
+ for fold in f:
+ direction, fold_line = fold.strip().split(" ")[2].split("=")
+ fold_line = int(fold_line)
+
+ folded_dots = set()
+ for x, y in dots:
+ if direction == "x" and x > fold_line:
+ diff = x - fold_line
+ x = fold_line - diff
+ elif direction == "y" and y > fold_line:
+ diff = y - fold_line
+ y = fold_line - diff
+
+ folded_dots.add((x, y))
+
+ dots = folded_dots
+ # break # First part just wants the number of dots after first fold.
+
+
+
+xs, ys = list(zip(*dots))
+max_x = max(xs)
+max_y = max(ys)
+
+for j in range(max_y + 1):
+ line = []
+ for i in range(max_x + 1):
+ if (i, j) in dots:
+ line.append("#")
+ else:
+ line.append(".")
+
+ print("".join(line))