5
\$\begingroup\$

WiKi and GitHub.

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;
}
\$\endgroup\$
5
  • \$\begingroup\$ Where does Range come from? Did you mean Enumerable.Range? \$\endgroup\$ Commented Nov 8, 2019 at 4:05
  • 1
    \$\begingroup\$ @tinstaafl yes, exactly. You could see all the code by clicking the github link on above. \$\endgroup\$ Commented Nov 8, 2019 at 4:08
  • \$\begingroup\$ @DmitryNogin: Please post all relevant code, don't hide it behind a link. Links can decay, potentially rendering the question unintelligible for posterity's sake. \$\endgroup\$ Commented Nov 8, 2019 at 10:19
  • \$\begingroup\$ Without correct compilable code being shown in your post,not referenced through a link, your post is off topic. \$\endgroup\$ Commented Nov 8, 2019 at 12:05
  • \$\begingroup\$ @tinstaafl @Flater It is correct and compilable. And no one ever being posting required 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\$ Commented Nov 8, 2019 at 13:18

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.