Home

Previous Entry | Next Entry

Sudoko

  • May. 22nd, 2005 at 1:02 AM
Deadwood hat
My first (and probably last encounter) with Sudoko was today. My view: it's very lame.

I saw the puzzle on page two of the Guardian. Supposedly this is the new puzzle craze that is supplanting crosswords. Your first warning should be that the puzzles are easily generated entirely by computer since, unlike crosswords, it's purely a numeric and logic puzzle.

Tonight I gave it a try - I spent a good five minutes pencilling in "this cell can be 1, 4 or 7" and this one can be "1, 5 or 6" so if this one is 4 the other can be 6, when boredom occurred, decided that there was a better, easier, more efficient way.

In one hour I wrote a program to solve it. To make things easy I used brute force and recursion, hardcoded the puzzle data, and just opened up a new form class and put the code into here. To make it interesting I did in C#.

It only took an hour to write. The code is simple, but it gives the right answer in under half a second. And with different data in it, will give the right answer for each and every Sudoko puzzle that there is. What more could you want - more comments? Consistent use of x and y co-ords? It's too lat at night for that and hey, job done.

So, Sudoko - a family of arithmetic puzzles generated by computers, for computers.

Unsubtle code below the cut:



		public const int BOARD_SIZE = 9;

		int[,] SudokoData = new int [BOARD_SIZE, BOARD_SIZE]
			{
				{0, 0, 0, 0, 0, 6, 0, 8, 9},
				{0, 0, 7, 2, 0, 3, 0, 0, 0},
				{5, 0, 0, 0, 0, 0, 0, 4, 0},

				{3, 0, 0, 5, 1, 0, 0, 6, 0},
				{0, 0, 0, 0, 0, 0, 0, 0, 0},
				{0, 4, 0, 0, 3, 9, 0, 0, 2},

				{0, 1, 0, 0, 0, 0, 0, 0, 4},
				{0, 0, 0, 8, 0, 7, 5, 0, 0},
				{2, 9, 0, 3, 0, 0, 0, 0, 0}
			};

		private bool UniqueInRow(int[,] Data, int val, int x, int y)
		{
		  bool result = true;
		  for (int i = 0; i < BOARD_SIZE; i++)
		  {
			if ((i != x) && (Data[i, y] == val))
			{
				result = false;
				break;
			}
		  }

		  return result;
		}

		private bool UniqueInCol(int[,] Data, int val, int x, int y)
		{
		  bool result = true;
		  for (int i = 0; i < BOARD_SIZE; i++)
		  {
			if ((i != y) && (Data[x, i] == val))
			{
				result = false;
				break;
			}
		  }

		  return result;
		}

		/*
		  The board is divided in 9 parts not 4 -
		  they are not quadrants so they must be nonstants
		*/
		private bool UniqueInNonstant(int[,] Data, int val, int x, int y)
		{
		  bool result = true;

		  int NonstantSize = BOARD_SIZE / 3;
		  int startx = x / 3;
		  startx = startx * 3;
		  int starty = y / 3;
		  starty = starty * 3;

		  for (int ix = startx; ix < startx + NonstantSize; ix++)
			for (int iy = starty; iy < starty + NonstantSize; iy++)
			{
				if ((ix != x) && (iy != y) && (Data[ix, iy] == val))
				{
					result = false;
					break;
				}
			}

		  return result;
		}

		private bool UniqueInAllWays(int[,] Data, int val, int x, int y)
		{
		  return
			UniqueInRow(Data, val, x, y) &&
			UniqueInCol(Data, val, x, y) &&
			UniqueInNonstant(Data, val, x, y);
		}


		/*
			Get a board, try to fill the first empty cell
			return if this can be done with a value that is unique
			and can solve further
		*/
		private bool Solve(int [,] Data)
		{

		  for (int ix = 0; ix < BOARD_SIZE; ix++)
			for (int iy = 0; iy < BOARD_SIZE; iy++)
			{
				if (Data[ix, iy] == 0)
				{
					return SolveCell(Data, ix, iy);
				}
			}

		  // no cells empty
		  return true;
		 }


		private bool SolveCell(int [,] Data, int x, int y)
		{
			int TestVal = 0;

			for (TestVal = 1; TestVal <= 9; TestVal++)
			{
				if (UniqueInAllWays(Data, TestVal, x, y))
				{
					Data[x, y] = TestVal;
					if (Solve(Data))
					  return true;
				}
			}

			// failed to find a soln on this path
			Data[x, y] = 0;
			return false;
		}

		private string ShowData(int [,] Data)
		{
		  StringBuilder result = new StringBuilder();

		  for (int iy = 0; iy < BOARD_SIZE; iy++)
		  {
			for (int ix = 0; ix < BOARD_SIZE; ix++)
			{
				result.Append(Data[iy, ix]);
				result.Append(", ");
			}
			result.Append("\n");
		  }

		  return result.ToString();
		}

		private void button1_Click(object sender, System.EventArgs e)
		{
		  Solve(SudokoData);
		  soln.Text = ShowData(SudokoData);
		}

Comments

[info]call_waiting wrote:
May. 22nd, 2005 08:46 am (UTC)
If I could remember the relevant syntax in e for list permutation constraints, the solution in e would be of the order of about 5 lines, plus pretty-printing.

Assuming, of course, I was going to do anything as frivolously insane as splash out on a Specman license just to do a puzzle...
[info]strawberryfrog wrote:
Apr. 8th, 2006 06:56 pm (UTC)
I've been pointed to this page. It ssems that my code is very verbose by comparison.

Profile

Deadwood hat
[info]strawberryfrog
strawberryfrog

Latest Month

July 2009
S M T W T F S
   1234
567891011
12131415161718
19202122232425
262728293031 
Powered by LiveJournal.com