There has simply GOT to be a better way to do this

Caporegime
Joined
18 Oct 2002
Posts
29,493
Location
Back in East London
I'm writing a sudoku solver as a hobby project/kata at home and have come to refactor the below method:
Code:
        private static int GetBlockNumberForCellNumber(int cellNumber)
        {
            if (cellNumber < 0) throw new ArgumentOutOfRangeException("cellNumber");

            if (cellNumber < 3) return 0;
            if (cellNumber < 6) return 1;
            if (cellNumber < 9) return 2;
            if (cellNumber < 12) return 0;
            if (cellNumber < 15) return 1;
            if (cellNumber < 18) return 2;
            if (cellNumber < 21) return 0;
            if (cellNumber < 24) return 1;
            if (cellNumber < 27) return 2;

            if (cellNumber < 30) return 3;
            if (cellNumber < 33) return 4;
            if (cellNumber < 36) return 5;
            if (cellNumber < 39) return 3;
            if (cellNumber < 42) return 4;
            if (cellNumber < 45) return 5;
            if (cellNumber < 48) return 3;
            if (cellNumber < 51) return 4;
            if (cellNumber < 54) return 5;

            if (cellNumber < 57) return 6;
            if (cellNumber < 60) return 7;
            if (cellNumber < 63) return 8;
            if (cellNumber < 66) return 6;
            if (cellNumber < 69) return 7;
            if (cellNumber < 72) return 8;
            if (cellNumber < 75) return 6;
            if (cellNumber < 78) return 7;
            if (cellNumber < 81) return 8;

            throw new ArgumentOutOfRangeException("cellNumber");
        }
My arithmetic/mathematics aren't very strong, so I'm not spotting a better way to write that.

Anyone else?
 
Block number, 0 indexed. This is part if the grid initialisation. The output is fine, tests pass etc. Cells are numbered 0-80 (9x9, left to right) and assorted into rows of 9, columns of 9, and blocks of 9. This is the block bit. :)

Cell Block numbers are like so:

Code:
000111222
000111222
000111222
333444555
333444555
333444555
666777888
666777888
666777888
 
Last edited:
There sure is :)

Code:
int row = cellNumber / 9;
int column = cellNumber % 9;
return column / 3 + row;

More generally:

Code:
int gridSize = 9;
int blockSize = 3;
int ratio = gridSize / blockSize;

int row = cellNumber / gridSize;
int column = cellNumber % gridSize;
return column / blockSize + (row / blockSize) * ratio;
 
Last edited:
Learning to look for patterns and ways to make your code more efficient is the best way to write better code. Great answer Inquisitor.
 
Hence this as a project/kata :)

I'm writing this so that each cell is an object, rather than what most do and just have a matrix of ints. Basically an exercise of "tell, don't ask" and also so it solves it like a human would, rather than just apply a mathematical function and say "tada!"
 
Last edited:
There sure is :)

Code:
int row = cellNumber / 9;
int column = cellNumber % 9;
return column / 3 + row;

More generally:

Code:
int gridSize = 9;
int blockSize = 3;
int ratio = gridSize / blockSize;

int row = cellNumber / gridSize;
int column = cellNumber % gridSize;
return column / blockSize + (row / blockSize) * ratio;
Just tested the "non-generalised".. it doesn't work. :)

For example:

first row (0), first column (0) should be block: 0 - correct.
second row (1), second column (1) should be block: 0 - incorrect.

Code:
0 / 3 + 0 = 0;
1 / 3 + 1 = 1;

The generalised version does work - i.e. missing the (rowNumber / gridSize) in the "non-generalised" :)
 
Last edited:
Back
Top Bottom