Check if a given grid is a valid Sudoku At CodeFights I found a question about the validity of Sudoku grid. Given a grid, return true if it is valid, return false otherwise. The grid is valid when each row, each column and each 3x3 sub grid contains at most one occurrence of the numbers 1 to 9.

I solved it using C# and I would like some feedback on my solution.

The provided grid is guaranteed to be 9x9 and to only contain the characters 1 through 9 and . (for empty cells). So I did not include any error checking. 

Solution

using System;

public static class Program
{
    public static void Main()
    {
        char[][] grid = {
            new char[] {'.', '.', '.', '1', '4', '.', '.', '2', '.'}, 
            new char[] {'.', '.', '6', '.', '.', '.', '.', '.', '.'},
            new char[] {'.', '.', '.', '.', '.', '.', '.', '.', '.'},
            new char[] {'.', '.', '1', '.', '.', '.', '.', '.', '.'},
            new char[] {'.', '6', '7', '.', '.', '.', '.', '.', '9'},
            new char[] {'.', '.', '.', '.', '.', '.', '8', '1', '.'},
            new char[] {'.', '3', '.', '.', '.', '.', '.', '.', '6'},
            new char[] {'.', '.', '.', '.', '.', '7', '.', '.', '.'},
            new char[] {'.', '.', '.', '5', '.', '.', '.', '7', '.'}
        };

        var sudoku = new Sudoku(grid);
        Console.WriteLine(sudoku.IsValid());
    }
}

public class Sudoku
{
    char[][] _grid;

    public Sudoku(char[][] grid)
    {
        _grid = grid;
    }

    public bool IsValid()
    {
        return RowsAreValid() 
            &amp;&amp; ColumnsAreValid() 
            &amp;&amp; SquaresAreValid();
    }

    bool RowsAreValid()
    {
        return Validate(GetNumberFromRow);
    }

    bool ColumnsAreValid()
    {
        return Validate(GetNumberFromColumn);
    }

    bool SquaresAreValid()
    {
        return Validate(GetNumberFromSquare);
    }

    bool Validate(Func&lt;int, int, int&gt; numberGetter)
    {
        for (var row = 0; row &lt; 9; row++)
        {
            var usedNumbers = new bool[10];
            for (var column = 0; column &lt; 9; column++)
            {
                var number = numberGetter(row, column);
                if (number != 0 &amp;&amp; usedNumbers[number] == true)
                {
                    return false;
                }

                usedNumbers[number] = true;
            }
        }

        return true;
    }

    int GetNumberFromRow(int row, int column)
    {
        return ToNumber(_grid[row][column]);
    }

    int GetNumberFromColumn(int row, int column)
    {
        return ToNumber(_grid[column][row]);
    }

    int GetNumberFromSquare(int block, int index)
    {
        var column = 3 * (block % 3) + index % 3;
        var row = index / 3 + 3 * (block / 3);
        return ToNumber(_grid[row][column]);
    }

    int ToNumber(char c)
    {
        if (c == '.')
            return 0;
        return (int)(c - '0');
    }
}
Nice use of Func

I don't like the use of row and column in Validate and that is not really what it is  

Looks like you call GetNumberFromSquare more than you need to.  

Consider a byte[,] ba = new byte[9, 9]; array and use 0 for blank.

A little more compact  

public class Sudoku2
{
    byte[,] gridy = new byte[9, 9] { { 0, 0, 0, 1, 4, 0, 0, 2, 0 },
                                     { 0, 0, 6, 0, 0, 0, 0, 0, 0 },
                                     { 0, 0, 0, 0, 0, 6, 0, 0, 0 },
                                     { 0, 0, 1, 0, 0, 0, 0, 0, 0 },
                                     { 0, 6, 7, 0, 0, 0, 0, 0, 9 },
                                     { 0, 0, 0, 0, 0, 0, 8, 1, 0 },
                                     { 0, 3, 0, 0, 0, 0, 0, 0, 6 },
                                     { 5, 0, 0, 0, 0, 7, 0, 0, 0 },
                                     { 0, 0, 0, 5, 0, 0, 0, 7, 0 },
                                    };
    public bool Validate(byte[,] grid)
    {
        for (int i = 0; i &lt; 9; i++)
        {
            bool[] row = new bool[10];
            bool[] col = new bool[10];

            for (int j = 0; j &lt; 9; j++)
            {
                if(row[grid[i,j]] &amp; grid[i, j] &gt; 0)
                {
                    return false;
                }
                row[grid[i, j]] = true;

                if (col[grid[j, i]] &amp; grid[j, i] &gt; 0)
                {
                    return false;
                }
                col[grid[j, i]] = true;

                if ((i + 3) % 3 == 0 &amp;&amp; (j + 3) % 3 == 0)
                {
                    bool[] sqr = new bool[10];
                    for (int m = i; m &lt; i + 3; m++)
                    {
                        for (int n = j; n &lt; j + 3; n++)
                        {
                            if (sqr[grid[m, n]] &amp; grid[m, n] &gt; 0)
                            {
                                return false;
                            }
                            sqr[grid[m, n]] = true;
                        }
                    }
                }

            }
        }
        return true;
    }

    public Sudoku2()
    {
        bool good = Validate(gridy);
    }
    public Sudoku2(byte[,] grid)
    {
        bool good = Validate(grid);
    }
}