tags:

views:

112

answers:

3

I have a 9 x 9 matrix. (think of suduko).

   4 2 1 6 8 1 8 5 8 
   3 1 5 8 1 1 7 5 8 
   1 1 4 0 5 6 7 0 4 
   6 2 5 5 4 4 8 1 2 
   6 8 8 2 8 1 6 3 5 
   8 4 2 6 4 7 4 1 1 
   1 3 5 3 8 8 5 2 2 
   2 6 6 0 8 8 8 0 6 
   8 7 2 3 3 1 1 7 4 

now I wanna be able to get a "quadrant". for example (according to my code) the quadrant 2 , 2 returns the following:

    5 4 4 
    2 8 1 
    6 4 7 

If you've noticed, this is the matrix from the very center of the 9 x 9. I've split everything up in to pairs of "3" if you know what i mean. the first "ROW" is from 0 - 3, the second from 3 - 6, the third for 6 - 9.. I hope this makes sense ( I am open to alternate ways to go about this)

anyways, heres my code. I dont really like this way, even though it works. I do want speed though beccause i am making a suduko solver.

    //a quadrant returns the mini 3 x 3
    //row 1  has three quads,"1", "2", 3"
    //row 2  has three quads "1", "2", "3" etc
    public int[,] GetQuadrant(int rnum, int qnum) {
        int[,] returnMatrix = new int[3, 3];
        int colBegin, colEnd, rowBegin, rowEnd, row, column;

        //this is so we can keep track of the new matrix
        row = 0;
        column = 0;      
        switch (qnum) {
            case 1:
                colBegin = 0;
                colEnd = 3;
                break;
            case 2:
                colBegin = 3;
                colEnd = 6;
                break;
            case 3:
                colBegin = 6;
                colEnd = 9;
                break;
            default:
                colBegin  = 0;
                colEnd = 0;
                break;
        }

        switch (rnum) {
            case 1:
                rowBegin = 0;
                rowEnd = 3;
                break;
            case 2:
                rowBegin = 3;
                rowEnd = 6;
                break;
            case 3:
                rowBegin = 6;
                rowEnd = 9;
                break;
            default:  
                rowBegin = 0;
                rowEnd = 0;
                break;
        }
        for (int i = rowBegin ; i < rowEnd; i++) {
            for (int j = colBegin; j < colEnd; j++) {                 
                returnMatrix[row, column] = _matrix[i, j];
                column++;
            }
            column = 0;
            row++;
        }
        return returnMatrix;
    }
+1  A: 

The common pattern for this in Python is to use a dict to map:

qmap = {
  1: (0, 3),
  2: (3, 6),
  3: (6, 9),
}

print qmap.get(qnum, (0, 0))

I'm sure that C# supports something similar.

Ignacio Vazquez-Abrams
+7  A: 

Unless I'm missing something, why not do math? Fist of all, only store rowBegin and colBegin.

Now, simply issue:

rowBegin = (rnum-1)*3
colBegin = (qnum-1)*3

This maps 1 -> 0, 2 -> 3, and 3-> 6.

Now, you loop from colBegin to colBegin + 3, and rowBegin to rowBegin + 3. Is your default behavior really necessary? If it is, special case when rnum < 1 || rnum > 3 and qnum < 1 || qnum > 3

Stefan Kendall
Wow, thanks.. I thought about it for a long time. This is kinda sad considering im an undergraduate math student and couldnt pick up the pattern hehe. :P
masfenix
I should have known you had a math background. You were referring to the upper left (or bottom left) as (1,1) instead of (0,0). Madness!
Stefan Kendall
i am trying to generalize this even more. Instead of recieving coordinate type points, i am going to pass it a number from 1 - 9. where 1 2 3 are the two row, 4, 5, 6, from the second, and so on.
masfenix
This is not math but arithmetics.
Hamish Grubijan
A: 

For a general solution (i.e.: an NxN grid) I would use some maths (you'll need the modulo operator).

If you're always using a 9x9 sudoku grid then you can pre-calculate the answers and stick them in a map or array.

Of course you can combine those ideas and pre-calculate the answers in your init() function and then store them in a map.

Stewart Johnson