Sudoku rules are being checked with the following tests:
[TestMethod]
public void Be_Valid()
{
var data = new int?[,]
{
{ 5, 3, null },
{ 6, null, null },
{ null, 9, 8 }
};
var board = new Board(data);
Assert.IsTrue(board.Valid);
}
And:
[TestMethod]
public void Be_Invalid()
{
var data = new int?[,]
{
{ 5, 3, 8 },
{ 6, null, null },
{ null, 9, 8 }
};
var board = new Board(data);
Assert.IsFalse(board.Valid);
}
Where actual implementation looks like:
public class Board
{
public Board(int?[,] cells)
{
Cells = cells ?? throw new ArgumentNullException(nameof(cells));
if(Cells.GetLength(0) != Cells.GetLength(1))
throw new ArgumentNullException(nameof(cells), "Square board required.");
if (Cells.GetLength(0) % 3 != 0)
throw new ArgumentNullException(nameof(cells), "Board size should be multiple of 3.");
}
int? [,] Cells { get; }
int N => Cells.GetLength(0);
public bool Valid => ColumnsValid && RowsValid && GridsValid;
bool RowsValid => Rows.All(AreUnique);
bool ColumnsValid => Columns.All(AreUnique);
bool GridsValid => Grids.All(AreUnique);
IEnumerable<IEnumerable<int>> Rows =>
Range(0, N).Select(r => Numbers(0, N - 1, r, r));
IEnumerable<IEnumerable<int>> Columns =>
Range(0, N).Select(c => Numbers(c, c, 0, N - 1));
IEnumerable<IEnumerable<int>> Grids =>
from r in Range(0, N / 3)
from c in Range(0, N / 3)
select Numbers(
c * 3, c * 3 + 2, r * 3, r * 3 + 2);
bool AreUnique(IEnumerable<int> numbers) =>
numbers.Distinct().Count() == numbers.Count();
IEnumerable<int> Numbers(int left, int right, int top, int bottom) =>
from r in Range(top, bottom - top + 1)
from c in Range(left, right - left + 1)
where Cells[r, c].HasValue
select Cells[r, c].Value;
}
Range
come from? Did you meanEnumerable.Range
? \$\endgroup\$using
directives here. I bet you need to declare off topic all the C# related content. I wish you a good luck in that :) \$\endgroup\$