diff --git a/advent-of-code-2021.csproj b/advent-of-code-2021.csproj
index b585d03..73ef919 100644
--- a/advent-of-code-2021.csproj
+++ b/advent-of-code-2021.csproj
@@ -51,6 +51,9 @@
PreserveNewest
+
+ PreserveNewest
+
diff --git a/inputs/12.txt b/inputs/12.txt
new file mode 100644
index 0000000..0d41869
--- /dev/null
+++ b/inputs/12.txt
@@ -0,0 +1,24 @@
+rf-RL
+rf-wz
+wz-RL
+AV-mh
+end-wz
+end-dm
+wz-gy
+wz-dm
+cg-AV
+rf-AV
+rf-gy
+end-mh
+cg-gy
+cg-RL
+gy-RL
+VI-gy
+AV-gy
+dm-rf
+start-cg
+start-RL
+rf-mh
+AV-start
+qk-mh
+wz-mh
\ No newline at end of file
diff --git a/src/12.cs b/src/12.cs
new file mode 100644
index 0000000..50c0562
--- /dev/null
+++ b/src/12.cs
@@ -0,0 +1,93 @@
+namespace aoc2021;
+
+internal class Day12
+{
+ internal static void Go()
+ {
+ Logger.Log("Day 12");
+ Logger.Log("-----");
+ var lines = File.ReadAllLines("inputs/12.txt");
+ var paths = new Dictionary>();
+ foreach (var line in lines)
+ {
+ var points = line.Split('-');
+ if (!paths.ContainsKey(points[0]))
+ {
+ paths[points[0]] = new List();
+ }
+ if (!paths.ContainsKey(points[1]))
+ {
+ paths[points[1]] = new List();
+ }
+
+ paths[points[0]].Add(points[1]);
+ paths[points[1]].Add(points[0]);
+ }
+ Part1(paths);
+ Part2(paths);
+ Logger.Log("");
+ }
+
+ private static void Part1(Dictionary> paths)
+ {
+ using var t = new Timer();
+
+ var validPaths = new List>();
+ FindPaths(paths, validPaths, new List(){ "start" }, false);
+
+ Logger.Log($"part1: {validPaths.Count}");
+ }
+
+ private static void FindPaths(Dictionary> paths, List> routes, List currRoute, bool canVisitSmallCaveTwice)
+ {
+ //Logger.Log($"Current path: {string.Join(',', currRoute)}");
+ var curr = currRoute.Last();
+ foreach (var next in paths[curr])
+ {
+ //Logger.Log($" Evaluating next: {next}");
+ if (next == "start")
+ {
+ //Logger.Log($" is start, skipping");
+ continue;
+ }
+ if (next != "end" && next.ToLower() == next && currRoute.Contains(next))
+ {
+ if (!canVisitSmallCaveTwice)
+ {
+ //Logger.Log($" is already-visited small cave, skipping");
+ continue;
+ }
+ else if (currRoute.Any(x => x.ToLower() == x && currRoute.Count(y => x == y) == 2))
+ {
+ //Logger.Log($" is already-visited small cave and we have already been to another one twice, skipping");
+ continue;
+ }
+ }
+ //Logger.Log($" adding to route");
+ currRoute.Add(next);
+ if (next == "end")
+ {
+ //Logger.Log($" is end, so adding {string.Join(',', currRoute)} to valid paths");
+ routes.Add(currRoute);
+ }
+ else
+ {
+ FindPaths(paths, routes, new List(currRoute), canVisitSmallCaveTwice);
+ }
+
+ currRoute.RemoveAt(currRoute.Count - 1);
+ }
+
+ //Logger.Log(" done with route");
+ }
+
+ private static void Part2(Dictionary> paths)
+ {
+ using var t = new Timer();
+
+ var validPaths = new List>();
+ FindPaths(paths, validPaths, new List() { "start" }, true);
+
+ Logger.Log($"part2: {validPaths.Count}");
+ }
+}
diff --git a/src/main.cs b/src/main.cs
index 2915053..0e612e9 100644
--- a/src/main.cs
+++ b/src/main.cs
@@ -37,7 +37,11 @@ switch (arg)
aoc2021.Day10.Go();
break;
- default:
+ case "11":
aoc2021.Day11.Go();
break;
+
+ default:
+ aoc2021.Day12.Go();
+ break;
}