1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
public static int[] zigzagify(int[] array, int xmax, int ymax) { int[] zz = new int[array.length]; //zigzag array if (array.length != xmax * ymax) { throw new IllegalArgumentException(); } int ai = 0; //original array index int zzi = 0; //zigzag array index int x = 0; //x position int y = 0; //y position zz[zzi] = array[ai]; while (y * xmax + x < xmax * ymax - 1) { if(x<xmax-1) x++; else y++; zzi++; ai = y * xmax + x; System.out.println("x "+x+", y "+y+", zzi "+zzi+", ai "+ai); zz[zzi] = array[ai]; while (x > 0 && y < ymax-1) { x--; y++; zzi++; ai = y * xmax + x; System.out.println("x "+x+", y "+y+", zzi "+zzi+", ai "+ai); zz[zzi] = array[ai]; } if(y<ymax-1) y++; else x++; zzi++; ai = y * xmax + x; System.out.println("x "+x+", y "+y+", zzi "+zzi+", ai "+ai); zz[zzi] = array[ai]; while (y > 0 && x < xmax-1) { y--; x++; zzi++; ai = y * xmax + x; System.out.println("x "+x+", y "+y+", zzi "+zzi+", ai "+ai); zz[zzi] = array[ai]; } } return zz; }
Refactorings
No refactoring yet !
Kaloyan
August 20, 2008, August 20, 2008 08:28, permalink
IMHO the code cannot get much more readable that what you posted. You could try to gather the two inner loops together, since they are completely symmetrical. I'm posting an example to give you an idea
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
public static int[] zigzagify(int[] array, int xmax, int ymax) { int[] zz = new int[array.length]; //zigzag array if (array.length != xmax * ymax) { throw new IllegalArgumentException(); } int x = 0; int y = 1; int step = 1; int zzi = 0; zz[zzi++] = array[0]; System.out.println(0 + " " + 0); while (xmax-1 != x || ymax-1 != y) { do { System.out.println(x + " " + y); zz[zzi++] = array[y * xmax + x]; x += step; y -= step; } while ( (x > 0) && (x < xmax -1) && (y > 0) && (y < ymax -1)); step = -step; System.out.println(x + " " + y); zz[zzi++] = array[y * xmax + x]; if (y == 0 || y == ymax - 1) { x++; } else { y++; } } System.out.println(x + " " + y); zz[zz.length - 1] = array[array.length - 1]; return zz; }
Kaloyan
August 20, 2008, August 20, 2008 11:29, permalink
There's a bug at line 25, fix it with
1
if ((y == 0 && x < xmax -1) || y == ymax - 1) {
Kaloyan
August 20, 2008, August 20, 2008 12:13, permalink
okay, I think I came up with something better, how about generating the indexes of the next element iteratively as you go over the source array ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
public static int[] zigzag2(int[] array, int xmax, int ymax) { int[] zz = new int[array.length]; int x = 1; int y = 1; for(int t = 0; t < array.length; t++){ zz[t] = array[(y - 1) * xmax + (x - 1)]; System.out.println((x-1) + " " + (y - 1)); if((x + y) % 2 == 0) { // Even stripes if (y < ymax) { y++; } else { x+= 2; } if (x > 1) { x--; } } else { // Odd stripes if (x < xmax) { x++; } else { y+= 2; } if (y > 1) { y--; } } } return zz; }
This is the code that is supposed to turn array in normal order into array with zig-zag order (like this: http://en.wikipedia.org/wiki/Image:JPEG_ZigZag.svg). Normally the input and output array would be 2d array, but because of how the output array is used, it is only simple array, therefore xmax and ymax are used to specify how the imaginary 2d array should look like.