public static void Main()
var desiredCliqueSize = 5;
var minSum = int.MaxValue;
var foundPrimes = new System.Collections.Generic.HashSet<int>();
var graph = new System.Collections.Generic.Dictionary<int, System.Collections.Generic.HashSet<int>>();
Console.WriteLine("checking for cliques of size " + desiredCliqueSize);
while (suspect < minSum) {
var friends = FindFriendsOf(suspect, foundPrimes) ;
minSum = FindSmallerCliqueOfSize(desiredCliqueSize, minSum, suspect, friends, graph);
foundPrimes.Add(suspect);
if (FriendsHaveCliquePotential(friends, desiredCliqueSize))
graph.Add(suspect, friends);
Console.WriteLine("Min sum is " + minSum);
public static bool FriendsHaveCliquePotential(System.Collections.Generic.HashSet<int> friends, int desiredCliqueSize)
return friends.Count >= desiredCliqueSize - 2;
public static int FindSmallerCliqueOfSize(int desiredCliqueSize, int currMinSum, int suspect, System.Collections.Generic.HashSet<int> friends, System.Collections.Generic.Dictionary<int, System.Collections.Generic.HashSet<int>> graph)
var targetIntersectSize = desiredCliqueSize - 2;
if (friends.Count >= targetIntersectSize) {
foreach (var friend in friends) {
if (graph.ContainsKey(friend)) {
var potentialClique = new System.Collections.Generic.HashSet<int>(friends);
potentialClique.IntersectWith(graph[friend]);
if (potentialClique.Count >= targetIntersectSize)
var sum = friend + suspect;
foreach (var element in potentialClique) { cliqueString += (element.ToString() + ", "); sum += element; }
cliqueString += friend.ToString() + ", " + suspect;
Console.WriteLine("Found Clique " + cliqueString + " sum is " + sum);
minSum = Math.Min(sum, minSum);
public static System.Collections.Generic.HashSet<int> FindFriendsOf(int suspect, System.Collections.Generic.HashSet<int> foundPrimes)
var friends = new System.Collections.Generic.HashSet<int>();
foreach (var prime in foundPrimes) {
if (AreFriends(suspect, prime)) {
public static bool AreFriends(int a, int b)
return IsPrime(Concat(a, b)) && IsPrime(Concat(b, a));
public static int Concat(int a, int b)
if (b < 10) return 10 * a + b;
if (b < 100) return 100 * a + b;
if (b < 1000) return 1000 * a + b;
if (b < 10000) return 10000 * a + b;
if (b < 100000) return 100000 * a + b;
if (b < 1000000) return 1000000 * a + b;
if (b < 10000000) return 10000000 * a + b;
if (b < 100000000) return 100000000 * a + b;
return 1000000000 * a + b;
public static bool IsPrime(int suspect)
var limit = Math.Sqrt(suspect);
for (var i = 2; i <= limit; ++i) {
if (suspect % i == 0) {return false;}