Pav
Pav

Reputation: 57

How to compress primitive integer data for an array?

I am teaching myself java using the cs106a course from Stanford. Currently I am on chapter 10 of the book "The Art and Science of Java". The problem is to write a 3x3 Magic Square. The exercise:

  1. You have to write a 3x3 array
  2. Each side of the array(Magic Square) has to equal 15

The problem:
The program I wrote works, the assignment is complete, this question is for self learning. As a beginner I would like to improve the method SumOfSides() and make it smaller and more efficient. I tried iterating the array in this method but still have issues. Is there a way to make it more efficient?

public void run() {
    //set the font
    setFont("Helvetica-40");


    //fill the array
    fillArray();

    //sum up all sides 
    SumOfSides();

    //check if all of the sides in the magic square array equal 15: 
    checkSides(mSqr);

    //I used this for debugging purposes only:
    //showSides();

}

//for debugging purposes:
public void showSides() {

    println(sumRight0);
    println(sumRight1);

    println(sumRight2);
    println(sumBottom0);
    println(sumBottom1);
    println(sumBottom2);
    println(sumDiagonalUp);
    println(sumDiagonalDown);


}

public void SumOfSides() {
    sumRight0 = mSqr[0][0] + mSqr[0][1] + mSqr[0][2];
    sumRight1 = mSqr[1][0] + mSqr[1][1] + mSqr[1][2];
    sumRight2 = mSqr[2][0] + mSqr[2][1] + mSqr[2][2];

    sumBottom0 =mSqr[0][0] + mSqr[1][0] + mSqr[2][0];
    sumBottom1 =mSqr[0][1] + mSqr[1][1] + mSqr[2][1];
    sumBottom2 =mSqr[0][2] + mSqr[1][2] + mSqr[2][2];

    sumDiagonalUp = mSqr[2][0] + mSqr[1][1]+ mSqr[0][2];

    sumDiagonalDown = mSqr[0][0] + mSqr[1][1] + mSqr[2][2];

}

/*This predicate method checks if the sides
  of the array add up to 15: */

public boolean checkSides(int[][] myArray) {

    if (sumRight0 ==15 && sumRight1 ==15&& sumRight2==15 && sumBottom0==15&& sumBottom1==15&&
         sumBottom2==15&& sumDiagonalUp==15&&sumDiagonalDown==15) {
        println("True, this is a Magic Square");
        return true;
    } else {
        println("False, the sides do not equal 15");
        return false;
    }

}

public void fillArray() {

    int num =0;
    for(int row=0; row <3; row++) {

        for (int col=0; col<3; col++) {
            num=readInt("");
            mSqr[row][col]=num;
        }
    }

    /*Test array values here to see
     * if they were entered correctly.
     */
    //println(mSqr[1][2]); //should be 6
    //println(mSqr[2][0]); //should be 7

}


    //instance variables: 
    int[][] mSqr= new int[3][3];

    List<List<Integer>> new1 = new ArrayList<>();

    private int sumRight0;
    private int sumRight1;
    private int sumRight2;
    private int sumBottom0;
    private int sumBottom1;
    private int sumBottom2;

    private int sumDiagonalUp;
    private int sumDiagonalDown;

}

Upvotes: 1

Views: 84

Answers (1)

agiles231
agiles231

Reputation: 71

Perhaps the only thing is readability. You could take the values and move them into more readable variables:

int topLeft = mSqr[0][0];
int topMid = mSqr[0][1];
...
int sumLeft = topLeft + midLeft + bottomLeft;
int sumRight = topRight = midRight + bottomRight;
...

To address your concern of making it smaller, I would argue that converting the sums into loops, as you mentioned, is certainly not worth it in the case that you are doing 6 sums of 3 values each. Furthermore, each term of each sum is common to either one or two other sums, which does not provide much overlap. If you were performing larger sums (larger in number of terms in the sum, not the total value), then perhaps it would be worth it on a readability/SLOC argument.

Suppose you did want to do a loop still though, you could do something like

 sumLeft = 0;
 sumRight = 0;
 sumTop = 0;
 sumBottom = 0;
 sumDiagonalUp = 0;
 sumDiagonalDown = 0;
 for(int i = 0; i < mSqr.length; i++) {
     for(int j = 0; j < mSqr[i].length; j++) {
         if (i == 0) {
            sumLeft += mSqr[i][j];
         }
         if (i == mSqr.length - 1) {
            sumRight += mSqr[i][j];
         }
         if (j == 0) {
            sumTop += mSqr[i][j];
         }
         if (j == mSqr[i].length) {
            sumBottom += mSqr[i][j];
         }
         if (i == j) {
            sumDiagonalDown += mSqr[i][j];
         }
         if (i + j == mSqr.length - 1) {
            sumDiagonalUp += mSqr[i][j];
         }
     }
 }

The loops only provide benefit on large magic squares. Also, I am confused by your description contrasted with your implementation. It seems you are summing each row and column, and the two diagonals of the square, as opposed to the 4 sides and the diagonals.

Upvotes: 1

Related Questions