Reputation: 57
I'm implementing a sudoku solver using human way algorithm. Which have 3 constraint, different number ini row, cell and box.
I googled and I got http://www.emanueleferonato.com/2008/12/09/sudoku-creatorsolver-with-php/. But I cannot understand how this guy get floor($cell / 9)
for return_row function or floor(return_row($cell) / 3) * 3 + floor(return_col($cell) / 3)
for return_block.
I try to figure it out by write down the data in excel and I know there is some pattern like this :
[cell] [column]
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 0
But how did he figure it out that the formula was $cell % 9
?
I want to know, if I don't know the answer for the formula, how can I calculate that ? How can I determine that formula ? What method should I use?
Thanks
Upvotes: 2
Views: 684
Reputation: 11395
This comes from the way the cells are counted, which we could call row-major.
You can see block and cell numbers with their respective row and column numbers on this image :
The first row (0) contains cells 0 to 8, the second row cells 9 to 17, and so on until row 8, which contains cells 72 to 80.
If you number rows 0 to 8 and columns 0 to 8 as well, we can see that the formula for a cell that corresponds to this numbering is then cell = 9 * row + col
, which should explain the formulas for get_row and get_col.
When moving right from any cell by one column, you add 1 to the cell count, which means the formula for the cell number looks like something + col
.
When moving down one row, you add to the cell number the amount of cells per row, which here is 9, so the formula also looks like 9 * row + something
.
Putting those together, you get a formula that is 9 * row + col + offset
: the "+ something"s dependencies is row and col are determined, but maybe they still contain a constant value.
In our case, the formula gives the numbering we want with offset=0, but if you started numbering from 1 you formula would be 9 * row + col + 1
.
However you do not have to do this reasoning every time. Just now that when you have a rectangle where you count items row by row, the formula for an item's number is always row * row_size + col + number at (0,0)
. This is also how contiguous memory is allocated for double arrays in C, for example, a very common pattern. If you count column by column, then you have col * col_size + row + number at (0,0)
Now blocks are numbered the same way, but there are only 3 rows and columns. You can replace one by one the elements in the get_block formula to understand it : floor(row / 3) * 3 + floor(col / 3)
Since there are 3 rows of blocks but 9 of cells, the (cell-)rows 0, 1 and 2 correspond to the first row of blocks, 3 to 5 to the second row of blocks and 6 to 8 to the final and third row of blocks. What we get out of this is that a row of blocks rb
contains the rows of cells 3 * rb
, 3 * rb +1
and 3 * rb + 2
. The opposite operation is dividing by 3 and flooring, which gets you rb
for any of the expressions above.
This works exactly the same for the columns.
Thus when replacing in the expression, we now have : block_row * 3 + block_col
. This I'd exactly the same formula (with 3 instead of 9) than we had for the numbering of cells, and thus gets you the number of the block from its row and column.
Upvotes: 4