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\$
    – user33306
    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\$ 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\$
    – Flater
    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\$
    – user33306
    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\$ Nov 8, 2019 at 13:18

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.