James Michael Hare

...hare-brained ideas from the realm of software development...
posts - 166 , comments - 1469 , trackbacks - 0

My Links

News

Welcome to my blog! I'm a Sr. Software Development Engineer in the Seattle area, who has been performing C++/C#/Java development for over 20 years, but have definitely learned that there is always more to learn!

All thoughts and opinions expressed in my blog and my comments are my own and do not represent the thoughts of my employer.

Blogs I Read

Follow BlkRabbitCoder on Twitter

Tag Cloud

Archives

Post Categories

.NET

CSharp

Little Wonders

Little Wonders

vNext

Little Puzzlers–Validate a Sudoku Board

I like to keep my brain sharp by working on programming puzzlers. On off weeks I'm going to start posting programming puzzlers I've collected over the years. Hopefully you'll find them as entertaining as I do.

This one is a more straight-forward puzzler.  There’s no gotcha or “ah-hah” moment in solving this, it’s just an exercise in coding.  I’ll try to vary up the difficulty level of problems so they’re not all easy and not all brain-busters…

The Problem

Given a 2d 9 x 9 array of char representing an in-progress Sudoku board, validate that the board currently has no errors.  The​ board may be partially filled and may be unsolvable, the challenge is to simply determine if there are any errors with the solution so far.​

A Sudoku board has no errors if there are no numbers duplicated in the same row, or in the same column, or in the same 3x3 cube (as shown below by the heavy lines dividing the board into 9 equal 3x3 cubes).

Empty cells will be represented by a space (' ') otherwise, the cells will have the character representation of the numbers '1' thru '9'.

For example, this board:

250px-Sudoku-by-L2G-20050714_svg

Would be represented by the 2d array:

   1: var board = new char[9,9] 
   2:  {
   3:   {'5', '3', ' ', ' ', '7', ' ', ' ', ' ', ' '},
   4:   {'6', ' ', ' ', '1', '9', '5', ' ', ' ', ' '},
   5:   {' ', '9', '8', ' ', ' ', ' ', ' ', '6', ' '},
   6:   {'8', ' ', ' ', ' ', '6', ' ', ' ', ' ', '3'},
   7:   {'4', ' ', ' ', '8', ' ', '3', ' ', ' ', '1'},
   8:   {'7', ' ', ' ', ' ', '2', ' ', ' ', ' ', '6'},
   9:   {' ', '6', ' ', ' ', ' ', ' ', '2', '8', ' '},
  10:   {' ', ' ', ' ', '4', '1', '9', ' ', ' ', '5'},
  11:   {' ', ' ', ' ', ' ', '8', ' ', ' ', '7', '9'},
  12:  };
Again, the goal is to simply state if there are any errors in the Sudoku board as it stands, not to determine if the puzzle has a solution or is solvable.

Spoiler Alert!

Fair Warning: there may be discussion of the problem and potential solutions posted in the comments below. Read at your own risk.

Print | posted on Tuesday, May 19, 2015 7:23 PM |

Feedback

Gravatar

# re: Little Puzzlers–Validate a Sudoku Board

"not to determine if the puzzle has a solution or is solvable."

Isn't this a requirement of testing whether the board has errors?

I mean it would be easy to test for obvious errors where they've got duplicate numbers on a row. The hard question is testing whether they've added any numbers that make the puzzle impossible to solve. I would think the only way to answer that is to know whether the puzzle is solvable in its current state?
5/20/2015 2:19 PM | Rob
Gravatar

# re: Little Puzzlers–Validate a Sudoku Board

@Rob: not necessarily for our purposes. I'm defining the puzzle in error as a mistake in the rules of Sudoku as the board stands. Sort of the difference between being syntactically correct but not making sense.

Obviously, solving the Sudoku puzzle to determine if a solution is possible would be harder, though interesting.

It's not so much an exercise in solving the puzzle, as writing an efficient means of determining if the puzzle is in error.
5/20/2015 3:55 PM | James Michael Hare
Gravatar

# Send Rakhi for Brother in Canada

The ritual of Raksha Bandhan, also known as Rakhi is the best way of showing your love and dedication towards your brother or sister. Send Rakhi Gifts to Canada to your sister or brother and shower them with your love and care. Send Rakhi to Canada from India to your loved ones and that too from the comfort of your home.
5/25/2015 6:59 AM | Bishma45
Gravatar

# re: Little Puzzlers–Validate a Sudoku Board

Looking for an efficient algorithm for a data structure based on chars is probably not the right approach. It'd be like looking for the optimal way to dig holes using a teaspoon..
5/25/2015 5:17 PM | Morten
Gravatar

# re: Little Puzzlers–Validate a Sudoku Board

internal sealed class Program
{
private static void Main()
{
var board = new char[9, 9]
{
{'5', '3', ' ', ' ', '7', ' ', ' ', ' ', '5'},
{'6', ' ', ' ', '1', '9', '5', ' ', ' ', ' '},
{' ', '9', '8', ' ', ' ', ' ', ' ', '6', ' '},
{'8', ' ', ' ', ' ', '6', ' ', ' ', ' ', '3'},
{'4', ' ', ' ', '8', ' ', '3', ' ', ' ', '1'},
{'7', ' ', ' ', ' ', '2', ' ', ' ', ' ', '6'},
{' ', '6', ' ', ' ', ' ', ' ', '2', '8', ' '},
{' ', ' ', ' ', '4', '1', '9', ' ', ' ', '5'},
{' ', ' ', ' ', ' ', '8', ' ', ' ', '7', '9'},
};

Console.WriteLine(Program.IsBoardValid(board));
Console.ReadKey();
}

private static bool IsBoardValid(char[,] board)
{
// Build a list of all 27 number sets (9 rows, 9 columns, and 9 3x3 blocks).
var sets = new List<IEnumerable<char>>(27);
for (int row = 0; row < 9; row++) sets.Add(Program.RowSet(board, row));
for (int col = 0; col < 9; col++) sets.Add(Program.ColumnSet(board, col));
for (int row = 0; row < 9; row += 3)
{
for (int col = 0; col < 9; col += 3)
{
sets.Add(Program.BlockSet(board, row, col));
}
}

// Return whether all 27 number sets are valid.
return sets.Aggregate(true, (areAllSetsValid, set) => areAllSetsValid && Program.IsSetValid(set));
}

// Enumerates the 9 cells in a single row of a board.
private static IEnumerable<char> RowSet(char[,] board, int row)
{
for (int columnIndex = 0; columnIndex < 9; columnIndex++) yield return board[row, columnIndex];
}

// Enumerates the 9 cells in a single column of a board.
private static IEnumerable<char> ColumnSet(char[,] board, int column)
{
for (int rowIndex = 0; rowIndex < 9; rowIndex++) yield return board[rowIndex, column];
}

// Enumerates the 9 cells in a single 3x3 block of a board.
private static IEnumerable<char> BlockSet(char[,] board, int row, int column)
{
for (int rowIndex = 0; rowIndex < 3; rowIndex++)
{
for (int columnIndex = 0; columnIndex < 3; columnIndex++)
{
yield return board[row + rowIndex, column + columnIndex];
}
}
}

private static bool IsSetValid(IEnumerable<char> set)
{
IEnumerable<char> populatedCells = set.Where(cell => cell != ' ');
return populatedCells.Count() == populatedCells.Distinct().Count();
}
}
5/28/2015 1:02 PM | Robert Bullen
Gravatar

# re: Little Puzzlers–Validate a Sudoku Board

@Robert: I like it!
6/1/2015 11:51 AM | James Michael Hare
Gravatar

# re: Little Puzzlers–Validate a Sudoku Board

@Morten: why? yes data structures have some overhead when storing char, but there are many ways to solve the puzzle algorithmicly, and not all are the same efficiency.

I'm not asking for the optimal in terms of space (in which case you could easily get by with some bit flipping), but for an efficient algorithm for scanning the board.
6/1/2015 11:54 AM | James Michael Hare
Gravatar

# re: Little Puzzlers–Validate a Sudoku Board

@Robert:

> return populatedCells.Count() == populatedCells.Distinct().Count();

Clever!
6/2/2015 5:17 PM | Mike C
Gravatar

# re: Little Puzzlers–Validate a Sudoku Board

@Robert:

Admittedly, I'm a VB.NET guy, not a C# guy, but wouldn't using .All() instead of .Aggregate() be marginally more efficient, in that it'll short-circuit the enumeration itself once it finds an invalid set?

> // Return whether all 27 number sets are valid.
> return sets.Aggregate(true, (areAllSetsValid, set) => areAllSetsValid && Program.IsSetValid(set));

...could be:

return sets.All(Program.IsSetValid);
6/2/2015 5:42 PM | Mike C
Gravatar

# re: Little Puzzlers–Validate a Sudoku Board

My own unoptimized Functional-style solution without for loops:

http://pastebin.com/SkBh9xuw
6/2/2015 7:08 PM | Mike C
Post A Comment
Title:
Name:
Email:
Comment:
Verification:
 

Powered by: