about summary refs log tree commit diff
path: root/aoc2021/Day12.cs
diff options
context:
space:
mode:
authorBen Harris <ben@tilde.team>2021-12-12 12:51:36 -0500
committerBen Harris <ben@tilde.team>2021-12-12 12:51:36 -0500
commit7feb07944a4183f4caae4b9004bab1d4e139fd51 (patch)
tree28cdc01af5fe996c76cb3e61482ab4b797f1bc48 /aoc2021/Day12.cs
parent043ab861bd4723edc97848ada3aba4a3a6745fb2 (diff)
day 12
Diffstat (limited to 'aoc2021/Day12.cs')
-rw-r--r--aoc2021/Day12.cs62
1 files changed, 62 insertions, 0 deletions
diff --git a/aoc2021/Day12.cs b/aoc2021/Day12.cs
new file mode 100644
index 0000000..7413206
--- /dev/null
+++ b/aoc2021/Day12.cs
@@ -0,0 +1,62 @@
+namespace aoc2021;
+
+/// <summary>
+/// Day 12: <see href="https://adventofcode.com/2021/day/12"/>
+/// </summary>
+public sealed class Day12 : Day
+{
+    private readonly Dictionary<string, List<string>> _edges = new();
+
+    public Day12() : base(12, "Passage Pathing")
+    {
+        foreach (var line in Input)
+        {
+            var s = line.Split('-', 2);
+
+            if (_edges.ContainsKey(s[0])) _edges[s[0]].Add(s[1]);
+            else _edges[s[0]] = new() { s[1] };
+
+            if (_edges.ContainsKey(s[1])) _edges[s[1]].Add(s[0]);
+            else _edges[s[1]] = new() { s[0] };
+        }
+    }
+
+    private static int WalkGraph(IReadOnlyDictionary<string, List<string>> edges, string point,
+        Dictionary<string, bool> seen)
+    {
+        if (point == "end") return 1;
+        if (char.IsLower(point[0]) && seen.GetValueOrDefault(point, false)) return 0;
+
+        seen[point] = true;
+        return edges[point].Sum(path => WalkGraph(edges, path, seen.ToDictionary(k => k.Key, v => v.Value)));
+    }
+
+    private static int TraverseGraph(IReadOnlyDictionary<string, List<string>> edges, string point,
+        Dictionary<string, bool> seen)
+    {
+        if (point == "end") return 1;
+        if (!TwiceCheck(point, seen)) return 0;
+
+        seen[point] = true;
+        return edges[point].Sum(path => TraverseGraph(edges, path, seen.ToDictionary(k => k.Key, v => v.Value)));
+    }
+
+    private static bool TwiceCheck(string point, Dictionary<string, bool> seen)
+    {
+        if (point == "start" && seen.GetValueOrDefault(point, false))
+            return false;
+        if (!char.IsLower(point[0]) || !seen.GetValueOrDefault(point, false))
+            return true;
+        if (seen.GetValueOrDefault("_twice", false))
+            return false;
+        
+        seen["_twice"] = true;
+        return true;
+    }
+
+    public override string Part1() =>
+        $"{WalkGraph(_edges, "start", new())}";
+
+    public override string Part2() =>
+        $"{TraverseGraph(_edges, "start", new())}";
+}
\ No newline at end of file