static void Main(string[] args) { var stopwatch = Stopwatch.StartNew(); // keep track of matches var matches = new List <HexTile>(); // keep track of ring we're currently processing var ring = 0; var index = 0; while (matches.Count < 2000) { var tile = HexTile.FromIndex(++index); // starting a new ring? var tmp = tile.Ring; if (tmp != ring) { ring = tmp; Console.WriteLine($"Checking Ring {tmp} (start index {tile.Index}), found {matches.Count} tiles so far."); } // walk all neighbors var neighbor = tile.GetNeighbor(Direction.North); // NOTE: need arbitrarily large integer here, as 128 bit (decimal) are not sufficient BigInteger result = neighbor.Index; neighbor = tile.GetNeighbor(Direction.NorthEast); result *= neighbor.Index; neighbor = tile.GetNeighbor(Direction.NorthWest); result *= neighbor.Index; neighbor = tile.GetNeighbor(Direction.South); result *= neighbor.Index; neighbor = tile.GetNeighbor(Direction.SouthEast); result *= neighbor.Index; neighbor = tile.GetNeighbor(Direction.SouthWest); result *= neighbor.Index; // check if product is devisable by value of tile if (result % tile.Index == 0) { matches.Add(tile); } } stopwatch.Stop(); Console.WriteLine($"Found {matches.Count} matches in {stopwatch.Elapsed.TotalSeconds}s"); var lastMatch = matches.Last(); Console.WriteLine($"Last match was {lastMatch} with the following neighbors:"); Console.WriteLine($"N : {lastMatch.GetNeighbor(Direction.North)}"); Console.WriteLine($"NW: {lastMatch.GetNeighbor(Direction.NorthWest)}"); Console.WriteLine($"SW: {lastMatch.GetNeighbor(Direction.SouthWest)}"); Console.WriteLine($"S : {lastMatch.GetNeighbor(Direction.South)}"); Console.WriteLine($"SE: {lastMatch.GetNeighbor(Direction.SouthEast)}"); Console.WriteLine($"NE: {lastMatch.GetNeighbor(Direction.NorthEast)}"); Console.WriteLine("Hit any key to exit."); Console.ReadKey(); }