private bool CheckForNearlyLocatedDigits(int checkNumber, CheckType checkType) { var removed = false; var digits = new List<List<int>>(); for (int i = 0; i < 9; i++) { digits.Add(new List<int>()); } for (int i = 0; i < 9; i++) { var checkCell = Utility.GetCell(checkNumber, i, checkType, grid); foreach (var digit in checkCell.MightBe) { digits[digit - 1].Add(i); } } for (var i = 0; i < 9; i++) { var digit = digits[i]; var digitName = i + 1; if (digit.Count > 1 && digit.Count <= 3) { var firstLocation = digit[0]; var firstRow = (int)Math.Floor(firstLocation / 3.0); var firstCol = firstLocation % 3; var rowLocated = true; var colLocated = true; foreach (var location in digit) { var row = (int)Math.Floor(location / 3.0); if (row != firstRow) { rowLocated = false; } var col = location % 3; if (col != firstCol) { colLocated = false; } } if (rowLocated) { var globalRow = 3 * (int)Math.Floor(checkNumber / 3.0) + firstRow; for (int j = 0; j < 9; j++) { var removeCell = Utility.GetCell(globalRow, j, CheckType.Row, grid); var boxNum = Utility.GetBoxNum(removeCell); if (boxNum != checkNumber && removeCell.MightBe.Contains(digitName) && removeCell.MightBe.Count > 1) { removeCell.MightBe.Remove(digitName); removed = true; } } if (chatty && removed) { Console.WriteLine("In Box " + (checkNumber + 1) + ", " + digitName + " must be in Row " + (globalRow + 1)); } } if (colLocated) { var globalCol = 3 * (checkNumber % 3) + firstCol; for (int j = 0; j < 9; j++) { var removeCell = Utility.GetCell(globalCol, j, CheckType.Column, grid); var boxNum = Utility.GetBoxNum(removeCell); if (boxNum != checkNumber && removeCell.MightBe.Contains(digitName) && removeCell.MightBe.Count > 1) { removeCell.MightBe.Remove(digitName); removed = true; } } if (chatty && removed) { Console.WriteLine("In Box " + (checkNumber + 1) + ", " + digitName + " must be in Column " + (globalCol + 1)); } } } } return removed; }
private bool CheckForIntersects(int checkNumber, CheckType checkType) { var removed = false; for (int i = 0; i < 9; i++) { var basisCell = Utility.GetCell(checkNumber, i, checkType, grid); var basisSet = basisCell.MightBe; if (basisSet.Count == 1) { continue; } var intersects = new List<int> { }; var chattyRemoved = false; for (int j = 0; j < 9; j++) { var checkCell = Utility.GetCell(checkNumber, j, checkType, grid); if (j != i && basisSet.Intersect(checkCell.MightBe).Count() < checkCell.MightBe.Count && basisSet.Intersect(checkCell.MightBe).Count() > 0) { intersects.Add(j); } } if (basisSet.Count == 2 && intersects.Count == 2 && checkType == CheckType.Box) { var intersect1 = Utility.GetCell(checkNumber, intersects[0], CheckType.Box, grid).MightBe; var intersect2 = Utility.GetCell(checkNumber, intersects[1], CheckType.Box, grid).MightBe; var union = Enumerable.Union(basisSet, Enumerable.Union(intersect1, intersect2)); if (union.Count() == intersects.Count + 1) { for (int k = 0; k < 9; k++) { if (k != i && !intersects.Contains(k)) { var removeCell = Utility.GetCell(checkNumber, k, checkType, grid); foreach (var digit in union) { if (removeCell.MightBe.Contains(digit)) { removeCell.MightBe.Remove(digit); if (removeCell.MightBe.Count == 0) { throw new Exception(checkType.ToString() + " " + (checkNumber + 1) + ": Intersect check ruled out all options for " + removeCell.Row + "," + removeCell.Column); } chattyRemoved = true; removed = true; } } } } } if (chattyRemoved && chatty) { Console.WriteLine("In " + checkType.ToString() + " " + (checkNumber + 1) + ", the set " + string.Join(",", union) + " is covered by 3 cells"); } } } return removed; }