-2

This is homework that we got in my Computer Science class dealing with 2D Arrays. I tried understanding the code, but unfortunately, I'm having a hard time understanding some of the code. This is the code that we were provided with:

public class Magic {
    public static void main(String[] args) {

        // Initializing a variable named n and assigning the integer 3 to it
        int n = 3;
        // Initializing a multi-dimensional array with 3 rows and 3 columns max
        int m[][] = new int[n][n]; // 3 by 3

        int i, j;
        // Assigning 1 to variable num
        int num = 1;

        int nn = n * 3 / 2; //4


        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                m[(j - i + nn) % n][(i * 2 - j + n) % n] = num++; 

                System.out.println(num);
            } // next j
        } //next i

        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                System.out.print(m[i][j] + "\t");
            } // next j
            System.out.println();
        } //next i
    } //end main()
} //end class Magic

Now my problem is that I don't understand this snippet of code specifically:

for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
        m[(j - i + nn) % n][(i * 2 - j + n) % n] = num++;
    } 
}

What does this line of code do in the loop? I'm not sure why the modulus is also used in this line. Is it there to limit the range of the generated numbers?

m[(j - i + nn) % n][(i * 2 - j + n) % n] = num++;
halfer
  • 19,824
  • 17
  • 99
  • 186
Abwatts
  • 31
  • 2
  • 6
  • What exactly don’t you understand? If it’s the `%` operator, that’s the *modulus* operator, which returns the *remainder* of a division operation. Eg, `7 % 3` is `1`. If it’s something else, please clarify your question. – Bohemian Feb 22 '19 at 21:44
  • "I'm not sure **why** the modulus is also used in this line." – ihavenoidea Feb 22 '19 at 21:47
  • See [Wikipedia](https://en.wikipedia.org/wiki/Magic_square#Specific_methods_of_construction) for algorithms of building a magic square. It's impossible to understand code implementing an algorithm, if you don't understand the algorithm itself, so step 1: Identify the algorithm used, and step 2: Learn how that algorithm works, then finally step 3: Learn/verify that the code is a correct implementation of that algorithm. – Andreas Feb 22 '19 at 21:48
  • 1
    Actually, the fact that you’re asking this question is testimony that the variables are very poorly named, because they convey no information about their meaning. `nn` for example should be called `median` or similar. Once variables are properly named, and chunks of code refactored by breaking out into well-named methods, what’s going on would probably be clear. – Bohemian Feb 22 '19 at 21:51

2 Answers2

1

You can get an idea by looking at the generated magic square, it looks like this:

8   3   4   
1   5   9   
6   7   2

The first coordinates (where i=0 and j=0) are 4%3=1 and 3%3=0. For the next coordinate, j increases by one and makes the coordinate go one left and one down. The modulus operator makes sure that the coordinates stay inside the square. After j has been incremented three times, i gets incremented and j gets reset to 0, so that every third move is straight to the right. After nine moves, the square is full.

fafl
  • 7,222
  • 3
  • 27
  • 50
  • Thanks a lot, guys! All the information you have listed have truly helped me understand what happens behind the scenes! So, just to clarify, the box is getting populated in a diagonal pattern, which as a result, makes it impossible to have the same number in the same row or column appear more than once? – Abwatts Feb 22 '19 at 22:03
  • `num++` increments the number after the placement. It will never place the same number twice. – fafl Feb 22 '19 at 22:09
  • Thank you for taking the time and helping! That means a lot to me. Sorry for my ignorance, but how exactly are the numbers in the first row are being generated (8, 3, 4)? I can't really fully comprehend how and why the numbers are assigned in this way. Thanks again. – Abwatts Feb 22 '19 at 22:25
  • Oh, I see, so the numbers are being assigned in a diagonal way. So, the first number that's being generated and stored in the box is 1, then 2, then 3, and so on until the box is populated? – Abwatts Feb 22 '19 at 22:33
  • Right, that's exactly what happens. The coordinate is moved and a new number gets placed, until the grid is full. – fafl Feb 23 '19 at 07:44
1

m, the "multi-dimensional" array (really just an array of arrays), has size n by n, therefore the max indices into the array are n-1 and n-1 (because indexing starts at 0).

A clever way to safely achieve indexing into m is by using the modulo operator %. You can think of the result of a % b as the "remainder" when you divide a / b (read more on Java's modulus operator here).

When you perform a % b where a >= 0 and b > 0, the result will always be strictly less than b. Therefore in our case, the modulus is used to index into m with a number that is strictly less than n (which is what we want or else we'd get some out of bounds exception!)

Derek Plautz
  • 108
  • 1
  • 5