Sudoku Programmers Forum Index

 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister   ProfileProfile   Log inLog in          Games  Calendar

Log in to check your private messagesLog in to check your private messages   

How to validate a sudoku grid

 
Post new topic   Reply to topic    Sudoku Programmers Forum Index -> Solving sudoku
View previous topic :: View next topic  
Author Message
jemore2

Joined: 02 Feb 2006
Posts: 4
:

Items
PostPosted: Thu Feb 02, 2006 8:07 pm    Post subject: How to validate a sudoku grid Reply with quote

Hi there.

After folding a bit in this forum, I did not found a smart way to validate a Sudoku grid. In other terms, I'm looking for a algorithm to check if a grid is a Sudoku, if it is correctly filled.

I'm writing a Sudoku games in DoJo, for i-mode cellphone, and I have a few constraints to implement this algorithm :
- must be in java
- must be quick
- must use a litle memory.

I do not want to use the first technic that come in mind, let's say checking if there is all the number from 1 to 9 in line, row and sector, because it can be huge in memory and slow.

I think there is a smarter way by summing the number in rows and cols, or doing a kind of CRC of the numbers of the grid.
The summing method can be fooled if you invert two numbers in a row or a cell. My simple CRC method can alsbo be easily tricked.

Are you aware of a such technic, that do note use an array to store the numbers in row, colls and sector ?

Thanks

Jerome.
Back to top
View user's profile Send private message
evert

Joined: 30 Aug 2005
Posts: 68
:
Location: Amsterdam

Items
PostPosted: Fri Feb 03, 2006 9:35 am    Post subject: Reply with quote

What's CRC?
Back to top
View user's profile Send private message Send e-mail
dom

Joined: 10 Nov 2005
Posts: 42
:

Items
PostPosted: Fri Feb 03, 2006 10:27 am    Post subject: Reply with quote

Summing the numbers will fail on a grid of all 5's

555 555 555
555 555 555
555 555 555

555 555 555
555 555 555
555 555 555

555 555 555
555 555 555
555 555 555

As all rows, columns and regions now add up to 45...

My recommendation would be to just cycle through each house and count instances of each digit in a 9 value array. If the count for a digit exceeds 1 then the board is invalid.

i.e.

Code:

function isValid(house)
{
 byte valueFound[] = {0,0,0,0,0,0,0,0,0};

 for (i=0; i<9; i++)
 {
  // increment count for this value
  valueFound[house[i]]++;
 
  // if we've found two of them then this house is not valid
  if (valueFound[house[i]]>1)
   return false;
 }
 return true;
}


If memory is really tight then rather than a 9 value array (9 bytes) you could use an 18 bit mask (3/4 bytes) such that 0x1 is the bit for 1, 0x4 is a bit for 2, etc.. Then add the bitmask to that integer for each digit that is set. If any even bits are set then there is more than 1 of that digit.

i.e.

(in binary)
....000101

would be a digit for 1 and a digit for 2

Then add another digit for 1...

....000101 + ....000001 = ....000110

Then test for even digits using value&....101010 >0

Does that make sense?

Anyway, that's a memory efficient way to look for two of an integer type, it's O(n) where n is number of digits in a house so also pretty efficient. If that doesn't make sense I can probably make it clearer!
_________________
Orangeminds Sudoku
http://www.orangeminds.com/sudoku/
Back to top
View user's profile Send private message
jemore2

Joined: 02 Feb 2006
Posts: 4
:

Items
PostPosted: Fri Feb 03, 2006 6:23 pm    Post subject: Reply with quote

evert wrote:
What's CRC?

CRC : http://en.wikipedia.org/wiki/Cyclic_redundancy_check Smile

What I mean by CRC in a completed Sudoku grid, is a way (ie algorithm) to compute a number, which is always the same, whatever the grid is , at the condition that the grid is complete and valid. An unvalid grid will result as a wrong CRC. (To be precise, it is not a real CRC, but I understand myself...)

My first method to compute the CRC was to shift a bitmask by the number present in a cell, by row, and to sum this shifted register until all the line was browse. It result of crc value of 0x3FE000000001L if the grid is complete. But it can be fooled in some case, if you invert two values.

I'm going to analyze the Dom' solution of this problem.

My code was :
Code:

long crc = 1;
for (int y = 0; y < 9; y ++)
{
   long tmp = 1;
   for (int x = 0; x < 9; x++)
   {
      c = this.cells[x][y];
      int n = c.getNumber();
      if (n != 0)
      {
      
         tmp = (tmp << n);
      }
      else
      {
         return false;
      }
   }
   crc += (tmp) >> y ;
}
return (crc == 0x3FE000000001L);
Back to top
View user's profile Send private message
jemore2

Joined: 02 Feb 2006
Posts: 4
:

Items
PostPosted: Fri Feb 03, 2006 6:27 pm    Post subject: Reply with quote

dom wrote:

(...)
My recommendation would be to just cycle through each house and count instances of each digit in a 9 value array. (...)


What do you call a house ? Is it what i call a "sector" ? (not the row, not the column, but the small 3x3 square)

I'm going to test your solution.
Back to top
View user's profile Send private message
jemore2

Joined: 02 Feb 2006
Posts: 4
:

Items
PostPosted: Fri Feb 03, 2006 7:05 pm    Post subject: Reply with quote

Ok, I come with my solution. It is small in memory and fast.
(What i mean by small memory, is that .class filesize must be as small as possible. So code size must be short). Inspired by Dom's suggestion

Code:

Cell c;
      int n;
      
      byte[] nums = {0,0,0, 0,0,0, 0,0,0};
      for(int y = 0; y < 9; y++)
      {
         for (int x = 0; x < 9 ; x++)
         {
            // Check line
            c = this.cells[x][y];
            n = c.getNumber();
            if (n == 0)
            {   // Cell not setted by the user
               return false;
            }
            nums[n-1]++;
            // Check rows
            c = this.cells[y][x];
            n = c.getNumber();
            if (n == 0)
            {   // Cell not setted by the user
               return false;
            }
            nums[n-1]++;
         }
      }
      for (int y = 0; y < 9; y++)
      {
         if (nums[y] != 18)
            return false;
      }
      return true;
Back to top
View user's profile Send private message
dom

Joined: 10 Nov 2005
Posts: 42
:

Items
PostPosted: Mon Feb 06, 2006 10:07 am    Post subject: Reply with quote

Hi jemore,

Glad you got your checker working. By "house" I mean any row, column or region. I think my "region" is most analagous to your "sector".

Also, looking at your pseudocode I'm not sure this will work. Imagine this basic grid

123 456 789
789 564 123
456 789 231
....

If I swap the 1,7 on column 1 I get...

723 456 789
189 564 123
456 789 231
....

I'm fairly certain that your code will still think this is valid as the counts for digits in rows and columns will be the same in total. You really need to check the count after each cycle through a column or row. You will also need to check each region (sector) too or there are some cases that will slip through.

You might also want to take a look at some of the entries in the smallest sudoku solver thread in programming sudoku as these programmers have developed some very small and quick tests for correctness.

Hope that helps.
_________________
Orangeminds Sudoku
http://www.orangeminds.com/sudoku/
Back to top
View user's profile Send private message
hopeforestcom

Joined: 05 Feb 2006
Posts: 2
:

Items
PostPosted: Tue Feb 07, 2006 1:48 pm    Post subject: Reply with quote

I think it is not a efficient way by filling 1-9 , if you wanna save your memory and time.
1st,let us think about it .what is different between 123456789 and 12345678? Nothing! So ,we just need 12345678. Right?
2nd, Denote 1 in 00000001,2 in 00000010,3 in 00000100, ...... and so on.
you just do "||" "or" operation for each block, culomn and row, it is fast . and don't waste any memory.

I hope it can help you. Good luck!

==============================
hopeforestcom@gmail.com
A new free sudoku solver

Hi, I am Robin from montreal,Canada
I wrote a free sudoku solver.
Please try it.
http://www.hopeforest.com/download/download.html
_________________
Hi, I am Robin from montreal,Canada
I wrote a free sudoku solver.
Please try it.
http://www.hopeforest.com/download/download.html
Back to top
View user's profile Send private message Send e-mail
neeta

Joined: 08 Feb 2006
Posts: 2
:

Items
PostPosted: Wed Feb 08, 2006 2:47 pm    Post subject: checking for correctness of sudoku grid Reply with quote

Can anyone help me write a program in Ada/C to check if the sudoku grid that is entered is correct or not.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Sudoku Programmers Forum Index -> Solving sudoku All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Sudoku Programmers topic RSS feed 


Powered by phpBB © 2001, 2005 phpBB Group

Igloo Theme Version 1.0 :: Created By: Andrew Charron