Skip to content

Commit

Permalink
day(23): Much faster algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
adamrodger committed Dec 23, 2024
1 parent fd8508a commit 73bce7d
Showing 1 changed file with 33 additions and 40 deletions.
73 changes: 33 additions & 40 deletions src/AdventOfCode/Day23.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using AdventOfCode.Utilities;

Expand Down Expand Up @@ -58,10 +57,40 @@ public string Part2(string[] input)
graph.GetOrCreate(elements[1], () => new List<string>()).Add(elements[0]);
}

var cliques = new List<IImmutableSet<string>>();
BronKerbosch(graph, [], graph.Keys.ToImmutableSortedSet(), [], cliques);
List<string> biggest = [];
HashSet<string> visited = [];

IImmutableSet<string> biggest = cliques.MaxBy(c => c.Count);
foreach (string node in graph.Keys)
{
if (!visited.Add(node))
{
// already part of another clique
continue;
}

List<string> 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());
}
Expand All @@ -85,41 +114,5 @@ private static SortedDictionary<string, ICollection<string>> BuildGraph(string[]

return graph;
}

/// <summary>
/// Sort the graph into 'cliques', which are clusters in which every node is connected
/// to every other node.
///
/// Had to do some Googling for this one... Never heard of it before
/// </summary>
/// <param name="graph">Graph of node ID to the IDs of all connected nodes</param>
/// <param name="clique">Current clique being considered</param>
/// <param name="candidates">Candidate nodes to be added to the clique</param>
/// <param name="visited">Nodes already visited</param>
/// <param name="cliques">All cliques found</param>
private static void BronKerbosch(IDictionary<string, ICollection<string>> graph,
IImmutableSet<string> clique,
IImmutableSet<string> candidates,
IImmutableSet<string> visited,
ICollection<IImmutableSet<string>> cliques)
{
if (candidates.Count == 0)
{
cliques.Add(clique);
return;
}

foreach (string candidate in candidates.ToArray())
{
BronKerbosch(graph,
clique.Add(candidate),
candidates.Intersect(graph[candidate]),
visited.Intersect(graph[candidate]),
cliques);

candidates = candidates.Remove(candidate);
visited = visited.Add(candidate);
}
}
}
}

0 comments on commit 73bce7d

Please sign in to comment.