views:

112

answers:

2

I have a 3x4 array that I want to rotate left once, so that it becomes a 4x3. Imagine a box of values, and just rotate that box left. Here's the function I wrote:

public static int[][] rotLeft(int[][] source) {
    int[][] newImage=new int[source[0].length][source.length];
    for (int i=0;i<source.length;i++)
        for (int j=0;j<source[0].length;j++)
            newImage[source.length-j][i]=source[i][j];
        return newImage;
}

This code should be working, as it passes my handwritten test (when I run it on paper), but when I try to run it through the grader that my teacher wrote, it fails the test. Whats wrong with this code?

+1  A: 

Matt Ball is absolutely correct, writing your own tests is the way to go. Many different tests.

One problem I see is that you have confusion between length and width in source.length-j expression. I.e., j is the second index of array and may be > source.length. Run it on 1x3 matrix and you'll get some very funny error.

Nikita Rybak
ok so that should be j<source.length[0], but even then I'm not getting it right
fprime
@fprime Ok, how about writing some tests _now_? Start with small cases: 1x1, 1x2, 3x1, ... You're actually one fix from a solution.
Nikita Rybak
I did write tests..I drew out a 3x4 square and put values in there, and rotated it left to see where the values should end up, and the code should be doing the trick. Maybe I'm looking at it wrong though, confusing rows and columns..lemme draw something up and show you real quick
fprime
@fprime Try a simpler example to find a mistake: 1x1
Nikita Rybak
so you see the mistake?
fprime
@fprime yep (everybody does it once in life :)) But my point is: take the simplest test reproducing error and look at it. Use debugger or debug output (System.out.println), if you like. 1x1 is pretty simple.
Nikita Rybak
OK so for the 1x1 example, source.length=1, so newImage[source.length-j]=[1-0] which is incorrect since that doesnt exist. So that part is wrong, so I tried putting [source.length-1-j], but that gave me out of bounds error..
fprime
@fprime Consider another mistake you've identified before... (or try 1x2 test)
Nikita Rybak
Ok I tried a 1x3, it seems newImage[j][i]=source[i][j] for this example, but this is still not the right answer..
fprime
@fprime You've found two mistakes in your code already. One is the lack of '-1', and another one before that (even Ishtar mentions it in his answer). Just combine both fixes.
Nikita Rybak
See this please: http://i.imgur.com/9HSzC.jpg Am I looking at this the right way?
fprime
@fprime You seem to. Now you need a function to convert pair of indexes (i, j) to new coordinates. Well, you've probably suffered enough and I can just tell you: (source[0].length - j - 1, i). Note, you mentioned 'source[0].length' fix in your first comment.
Nikita Rybak
@fprime Also, your original program worked on 3x4 case 'accidentally', because 'source[0].length - 1 == source.length' in that case.
Nikita Rybak
Wait, whats (source[0].length - j - 1, i)? Where does this apply? newImage[source[0].length-j-1][i]=...? Cuz I already tried that but that doesnt work..or am I supposed to change something else as well?
fprime
@fprime Works for me. Where does it fail for you? (what matrix size)
Nikita Rybak
its a 3x4, I get an out of bounds error -1
fprime
@fprime I just copied your code, replaced "newImage[source.length-j][i]=" with "newImage[source[0].length - j - 1][i] = " and it started working.
Nikita Rybak
And that works for all sized arrays? Rotates left once?
fprime
Ok I didnt have the [0] after source, but now I added it, but I'm getting a different error. It expected a different value then the one it got.
fprime
@fprime Well, I can't read minds: I don't know what error you've got. But this code works for me.
Nikita Rybak
Same bounds for i and j?
fprime
These are the values they expect:{ { 20, 10, 0 }, { 21, 11, 1 }, { 22, 12, 2 }, { 23, 13, 3 } }; this is a 4x3 right?
fprime
@fprime All I know is: this code rotates array in counter-clockwise order. (and produces same output on 3x4 matrix as your old program) If you want to make it clockwise order, you can easily change it (you know all the tricks now). Ok, I'm off for a supper. Goog luck!
Nikita Rybak
Ok I think I know what the problem is. The teacher called this function rotateLeft, which anyone would take to be counterclockwise. What I think he actually wants is a clockwise rotation. Not sure why it was called rotate left. Im kinda pissed, but Im gonna rewrite it now to see if I can get it working..thanks for your help man..
fprime
Ya rewrote it to rotate right and I got the right answer..this was the teachers fault..
fprime
+2  A: 

I do think you shouldn't test code without a computer. However to fix it, these simple steps might help. Try naming i and j, something like x and y and call the bounds width and height. Are the bounds always satisfied? And off course x only goes with a width in an expression.

Ishtar
Can you elaborate more on this? Where are my bounds not satisfied?
fprime
@fprime - Did you run it? It gives a `ArrayIndexOutOfBoundsException`. If you debug it, or print the values of `x` and `y`, you will know when it occurs. Then it really isn't too hard to figure out, if you don't mix up columns and rows.
Ishtar