Block scanning on sudoku solver explanation

2019-09-10 22:47发布

问题:

I tried this sudoku solver http://www.emanueleferonato.com/2008/12/09/sudoku-creatorsolver-with-php/. It works fine.

Also see this spreadsheet to see more detail in calculation : spreadsheet

I understand how the row and col scanning. From the board, we know that:

  • index = 9*row + col
  • row = floor(index/9)
  • col = index % 9

And for the block, because it build from 3x3 board so the formula: block_index = 3*row_block + col_row. Because per block there are 3 rows and cols, so the formula for row_block = floor(row/3) and col_block = floor(col/3). From here we can conclude that:

block_index = 3*row_block + col_row
block_index = 3(floor(row/3)) + floor(col/3)
block_index = floor(row/3)*3 + floor(col/3)

This could explain for these function :

  • return_row
  • retun_col
  • return_block
  • is_possible_row
  • is_possible_col

But I cannot understand about is_possible_block function. Here is the function:

function is_possible_block($number,$block,$sudoku){
    $possible = true;
    for($x = 0;$x <= 8;$x++){
        if($sudoku[floor($block / 3) * 27 + $x % 3 + 9 * floor($x / 3) + 3 * ($block % 3)] == $number){
            $possible = false;
        }
    }
    return $possible;
}

What I know about is_possible_block function is:

floor($block / 3) * 27 + $x % 3 + 9 * floor($x / 3) + 3 * ($block % 3)

= 9row+col
= 9(floor($block/3)*3 + floor($x/3)) + ($x%3 + 3*($block%3))

row = 3row_block+row_x_block
floor($block/3) = row_block
    floor($x/3) = row_x_block

col = 3col_block+col_x_block

How col = 3col_block+col_x_block , because what I know, the formula should be like this : col = 3row_block+col.

I know col_x_block mean column position on 0-8 block. And row_block mean row position on 0-2 block.

How do you explain this formula? Thanks

UPDATE

Now I know. floor($block/3)*3 and 3*($block%3) determine top left corner in block. Then floor($x / 3) and $x % 3 moves each cell in the block.

回答1:

I use it in c++

for(int k = ((x - 1) / 3) * 3 + 1; k < ((x - 1) / 3) * 3 + 4; k++

because of "x" is integer "/" operation return int value.

maybe 3(floor($block-1/3)) can help you.