From 08aa3eed7d823a98b84f78d79767393e83e67a43 Mon Sep 17 00:00:00 2001 From: Adam Rodger Date: Mon, 23 Dec 2024 11:40:54 +0000 Subject: [PATCH] day(23): LAN Party :computer: --- src/AdventOfCode/Day23.cs | 110 +++++++++++++++++++++++++ src/AdventOfCode/inputs/day23.txt | Bin 0 -> 20302 bytes tests/AdventOfCode.Tests/Day23Tests.cs | 105 +++++++++++++++++++++++ 3 files changed, 215 insertions(+) create mode 100644 src/AdventOfCode/Day23.cs create mode 100644 src/AdventOfCode/inputs/day23.txt create mode 100644 tests/AdventOfCode.Tests/Day23Tests.cs diff --git a/src/AdventOfCode/Day23.cs b/src/AdventOfCode/Day23.cs new file mode 100644 index 0000000..540eaa0 --- /dev/null +++ b/src/AdventOfCode/Day23.cs @@ -0,0 +1,110 @@ +using System.Collections.Generic; +using System.Linq; +using AdventOfCode.Utilities; + +namespace AdventOfCode +{ + /// + /// Solver for Day 23 + /// + public class Day23 + { + public int Part1(string[] input) + { + SortedDictionary> graph = BuildGraph(input); + + int total = 0; + + /* Look for triangles of interconnected nodes, i.e. + + node + / \ + / \ + left -- right + */ + foreach (string node in graph.Keys) + { + foreach (string left in graph[node].Where(l => string.CompareOrdinal(node, l) < 0)) + { + foreach (string right in graph[left].Where(r => string.CompareOrdinal(left, r) < 0)) + { + if (!graph[node].Contains(right)) + { + continue; + } + + // found a triangle + if (node.StartsWith('t') || left.StartsWith('t') || right.StartsWith('t')) + { + total++; + } + } + } + } + + return total; + } + + public string Part2(string[] input) + { + SortedDictionary> graph = BuildGraph(input); + + List biggest = []; + HashSet visited = []; + + foreach (string node in graph.Keys) + { + if (!visited.Add(node)) + { + // already part of another clique + continue; + } + + List clique = [node]; + + foreach (string candidate in graph.Keys) + { + if (visited.Contains(candidate)) + { + // already part of another clique + continue; + } + + // if it's connected to every current member of the clique then it's allowed in + if (clique.All(member => graph[member].Contains(candidate))) + { + clique.Add(candidate); + visited.Add(candidate); + } + } + + if (clique.Count > biggest.Count) + { + biggest = clique; + } + } + + return string.Join(',', biggest.Order()); + } + + /// + /// Build the graph of every node to all the reachable nodes from that point + /// + /// Input edge descriptions + /// Graph + private static SortedDictionary> BuildGraph(string[] input) + { + SortedDictionary> graph = new(); + + foreach (string line in input) + { + string[] elements = line.Split('-'); + + graph.GetOrCreate(elements[0], () => new List()).Add(elements[1]); + graph.GetOrCreate(elements[1], () => new List()).Add(elements[0]); + } + + return graph; + } + } +} diff --git a/src/AdventOfCode/inputs/day23.txt b/src/AdventOfCode/inputs/day23.txt new file mode 100644 index 0000000000000000000000000000000000000000..192657c43c0c7caf61864260a424c36347481abd GIT binary patch literal 20302 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 literal 0 HcmV?d00001 diff --git a/tests/AdventOfCode.Tests/Day23Tests.cs b/tests/AdventOfCode.Tests/Day23Tests.cs new file mode 100644 index 0000000..41c7eb3 --- /dev/null +++ b/tests/AdventOfCode.Tests/Day23Tests.cs @@ -0,0 +1,105 @@ +using System.IO; +using Xunit; +using Xunit.Abstractions; + +namespace AdventOfCode.Tests +{ + public class Day23Tests + { + private readonly ITestOutputHelper output; + private readonly Day23 solver; + + public Day23Tests(ITestOutputHelper output) + { + this.output = output; + this.solver = new Day23(); + } + + private static string[] GetRealInput() + { + string[] input = File.ReadAllLines("inputs/day23.txt"); + return input; + } + + private static string[] GetSampleInput() + { + return new string[] + { + "kh-tc", + "qp-kh", + "de-cg", + "ka-co", + "yn-aq", + "qp-ub", + "cg-tb", + "vc-aq", + "tb-ka", + "wh-tc", + "yn-cg", + "kh-ub", + "ta-co", + "de-co", + "tc-td", + "tb-wq", + "wh-td", + "ta-ka", + "td-qp", + "aq-cg", + "wq-ub", + "ub-vc", + "de-ta", + "wq-aq", + "wq-vc", + "wh-yn", + "ka-de", + "kh-ta", + "co-tc", + "wh-qp", + "tb-vc", + "td-yn", + }; + } + + [Fact] + public void Part1_SampleInput_ProducesCorrectResponse() + { + var expected = 7; + + var result = solver.Part1(GetSampleInput()); + + Assert.Equal(expected, result); + } + + [Fact] + public void Part1_RealInput_ProducesCorrectResponse() + { + var expected = 1599; + + var result = solver.Part1(GetRealInput()); + output.WriteLine($"Day 23 - Part 1 - {result}"); + + Assert.Equal(expected, result); + } + + [Fact] + public void Part2_SampleInput_ProducesCorrectResponse() + { + var expected = "co,de,ka,ta"; + + var result = solver.Part2(GetSampleInput()); + + Assert.Equal(expected, result); + } + + [Fact] + public void Part2_RealInput_ProducesCorrectResponse() + { + var expected = "av,ax,dg,di,dw,fa,ge,kh,ki,ot,qw,vz,yw"; + + var result = solver.Part2(GetRealInput()); + output.WriteLine($"Day 23 - Part 2 - {result}"); + + Assert.Equal(expected, result); + } + } +}