public void TestSolveAsync1() { var seed = new NumberPlaceMatrix(new int[] { 0, 6, 0, 8, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 0, 0, 7, 5, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 6, 0, 7, 0, 0, 9, 3, 0, 0, 0, 5, 0, 1, 0, 0, 0, 8, 3, 0, 0, 6, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 7, 0, 0, 0, 9, 0, 6, 0, 0, 0, 0, 0, 0, 7, 0, 2, 0 }); var solver = new NumberPlaceSolver(); var results = solver.Solve(seed); Assert.AreEqual(1, results.Count()); var expected = new int[] { 7, 6, 1, 8, 9, 5, 2, 3, 4, 3, 2, 8, 4, 1, 6, 9, 7, 5, 9, 4, 5, 7, 2, 3, 6, 1, 8, 1, 5, 6, 2, 7, 8, 4, 9, 3, 2, 9, 4, 5, 3, 1, 7, 8, 6, 8, 3, 7, 9, 6, 4, 1, 5, 2, 6, 8, 9, 1, 5, 2, 3, 4, 7, 5, 7, 2, 3, 4, 9, 8, 6, 1, 4, 1, 3, 6, 8, 7, 5, 2, 9 }; Assert.IsTrue(results.First().GetCells().Select(x => x.Value).ToArray().SequenceEqual(expected)); }
public void TestIsValidTrue() { var matrix = new NumberPlaceMatrix(new int[] { 7, 6, 1, 8, 9, 5, 2, 3, 4, 3, 2, 8, 4, 1, 6, 9, 7, 5, 9, 4, 5, 7, 2, 3, 6, 1, 8, 1, 5, 6, 2, 7, 8, 4, 9, 3, 2, 9, 4, 5, 3, 1, 7, 8, 6, 8, 3, 7, 9, 6, 4, 1, 5, 2, 6, 8, 9, 1, 5, 2, 3, 4, 7, 5, 7, 2, 3, 4, 9, 8, 6, 1, 4, 1, 3, 6, 8, 7, 5, 2, 9 }); Assert.IsTrue(matrix.IsValid()); }
public void TestIsValidFalse3() { var matrix = new NumberPlaceMatrix(new int[] { 1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 5, 6, 4, 5, 6, 4, 5, 6, 7, 8, 9, 7, 8, 9, 7, 8, 9, 1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 5, 6, 4, 5, 6, 4, 5, 6, 7, 8, 9, 7, 8, 9, 7, 8, 9, 1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 5, 6, 4, 5, 6, 4, 5, 6, 7, 8, 9, 7, 8, 9, 7, 8, 9, }); Assert.IsFalse(matrix.IsValid()); }
public IEnumerable<NumberPlaceMatrix> Solve(NumberPlaceMatrix seed) { var candidates = seed.GetCells().ToDictionary( x => x, x => (x.Value == 0 ? Enumerable.Repeat(true, seed.Size) : new bool[seed.Size]).ToList()); var sizeRange = Enumerable.Range(0, seed.Size); var blockRowRange = Enumerable.Range(0, seed.BlockRowSize); var blockColumnRange = Enumerable.Range(0, seed.BlockColumnCount); var blockRange = blockRowRange.SelectMany(r => blockColumnRange.Select(c => new { BlockRowIndex = r, BlockColumnIndex = c })); while (true) { var unsolvedCount = seed.GetCells().Count(x => x.Value == 0); if (unsolvedCount == 0) { break; } for (int r = 0; r < seed.Size; r++) { var values = seed.GetRow(r).Where(x => x.Value > 0).Select(x => x.Value).ToArray(); for (int c = 0; c < seed.Size; c++) { foreach (var value in values) { candidates.Single(x => x.Key.RowIndex == r && x.Key.ColumnIndex == c).Value[value - 1] = false; } } } for (int c = 0; c < seed.Size; c++) { var values = seed.GetColumn(c).Where(x => x.Value > 0).Select(x => x.Value).ToArray(); for (int r = 0; r < seed.Size; r++) { foreach (var value in values) { candidates.Single(x => x.Key.ColumnIndex == c && x.Key.RowIndex == r).Value[value - 1] = false; } } } foreach (var b in blockRange) { var values = seed.GetBlock(b.BlockRowIndex, b.BlockColumnIndex).Where(x => x.Value > 0).Select(x => x.Value).ToArray(); for (int r = b.BlockRowIndex * seed.BlockRowSize; r < (b.BlockRowIndex + 1) * seed.BlockRowSize; r++) { for (int c = b.BlockColumnIndex * seed.BlockColumnSize; c < (b.BlockColumnIndex + 1) * seed.BlockRowSize; c++) { foreach (var value in values) { candidates.Single(x => x.Key.RowIndex == r && x.Key.ColumnIndex == c).Value[value - 1] = false; } } } } var solvedCells = candidates.Where(x => x.Key.Value == 0 && x.Value.Count(b => b) == 1).ToArray(); if (solvedCells.Any()) { foreach (var solvedCell in solvedCells) { seed[solvedCell.Key.RowIndex, solvedCell.Key.ColumnIndex] = solvedCell.Value.FindIndex(b => b) + 1; } } else { var minCount = candidates.Where(x => x.Key.Value == 0).Min(x => x.Value.Count(b => b)); var unsolvedCell = candidates.Where(x => x.Key.Value == 0 && x.Value.Count(b => b) == minCount).First(); } } yield return seed; }
public void TestIsValidFalse1() { var matrix = new NumberPlaceMatrix(); Assert.IsFalse(matrix.IsValid()); }