0

I seem to be having trouble with the three user created methods and calling them correctly in the main method. I don't have any syntax errors that I know of, so that leaves logical ones, the parameters look fine too.

The program is suppose to have an output similar to the last output below. It's a program that takes a 2D array and checks if it's a magic square. Each method has a responsibility regarding the vetting/checking process to determine if it's a magic square or not.

I'd really appreciate some help getting this working, I'm stumped.

Code:

import java.util.Arrays;

public class Magic10
{
    // A method to check whether rows equal the target sum
    private static boolean rowsEqTargetSum(int[][] a, int targetSum, int n, int row, int col, int sum)
    {
    // Calculate the sum of each row ... if magic, then equal to targetSum      
        for(row=0; row<n; row++)
        {
            System.out.print("row "+row+": ");
            for(col=0; col<n; col++)
            {
                int value = a[row][col];
                sum += value;
                if (col > 0)
                    System.out.print(" + "); // print plus before all except 1st
                System.out.print(value);
            }
            System.out.println(" = "+sum);
            if(sum != targetSum)
            {
                System.out.println("Row sum incorrect : Not a magic Square!");
            }
        }
        return rowsEqTargetSum(null, 0, sum, sum, sum, sum);
    }
    // A method to check whether diagonals equal the target sum 
    private static boolean diagonalEqTargetSum(int[][] a, int targetSum, int n, int row, int col, int sum)
    {
        System.out.print("diagonal: ");
        for(int pos=0; pos<n; pos++)
        {

            row = n-1 - pos;
            col = pos;
            int value = a[row][col];
            sum += value;
            if (pos > 0)
                System.out.print(" + "); // print plus before all except 1st
            System.out.print(value);
        }
        System.out.println(" = "+sum);
        if(sum != targetSum)
        {
            System.out.println("Diagonal is incorrect : Not a magic Square!");
        }
        return diagonalEqTargetSum(null, 0, 0, sum, sum, sum);
    }
    // A method to check whether all numbers are used exactly once in the 2D array
    private static boolean allNumbersRepresented(int[][] a, int n, int col, int row)
    {
    // Lastly, we check that every number from 1 to n is represented
        final int nSquare=n*n;
        boolean[] flag= new boolean[n*n];

        for(row=0; row<n; row++)
        {
            for(col=0; col<n; col++)
            {
                int num = a[row][col];
                if (n < 1 || num > nSquare)
                {
                    System.out.println("Number out of range : Not a magic Square!");
                }
                if (flag[num-1]) 
                {
                    System.out.println("Duplicate number : Not a magic Square!");
                }
                flag[num-1] = true;
            }
        }
        return allNumbersRepresented(null, 0, 0, 0);
    }

    public static void main(String []args)
    {
        int[][] a ={{4,9,2},
                    {3,5,7},
                    {8,1,6}};
        final int n=a.length;
        final int targetSum=n*(n*n+1)/2;

        System.out.println(" The following two dimensional array is Magic!");   
        for (int i = 0;i< a.length;i++)
        {
            System.out.println(Arrays.toString(a[i]));
        }

        // Calls rowsEqTargetSum Method
        if (!rowsEqTargetSum(a, targetSum, targetSum, targetSum, targetSum, targetSum))
        {
            return;
        }
        // Calls diagonalEqTargetSum Method
        if (!diagonalEqTargetSum(a, targetSum, targetSum, targetSum, targetSum, targetSum))
        {
                 return;
        }
        // Calls allNumbersRepresented Method
        if (!allNumbersRepresented(a, targetSum, targetSum, targetSum))
        {
                return;
        }
    }
}

Current Output (Something is wrong with calling the methods?)

 The following two dimensional array is Magic!
[4, 9, 2]
[3, 5, 7]
[8, 1, 6]
row 0: 4 + 9 + 2Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
    at Magic10.rowsEqTargetSum(Magic10.java:14)
    at Magic10.main(Magic10.java:91)

Output looking somewhat like this:

row 0: 4 + 9 + 2 = 15
row 1: 3 + 5 + 7 = 15
row 2: 8 + 1 + 6 = 15
diagonal: 8 + 5 + 2 = 15
 The following two dimensional array is Magic !
[4, 9, 2]
[3, 5, 7]
[8, 1, 6]
Aramza
  • 193
  • 7
  • 29
  • 1
    _"having trouble "_ -- what does this mean? Please clarify and explain exactly what is happening and what you expect to happen. Include any error messages and/or stack trace. – Jim Garrison Nov 30 '16 at 23:29
  • I am confused on what the problem is, I thought I called the methods correctly and set them up correctly, and I don't know what I did incorrectly. – Aramza Nov 30 '16 at 23:31
  • What isn't working. like what is it supposed to do, but doesn't do. – sbowde4 Nov 30 '16 at 23:32
  • 1
    Possible duplicate of [What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?](http://stackoverflow.com/questions/5554734/what-causes-a-java-lang-arrayindexoutofboundsexception-and-how-do-i-prevent-it) – shmosel Nov 30 '16 at 23:33
  • It's suppose to have an output similar to the one I put in above. It's a program that takes a 2D array and checks if it's a magic square (https://en.wikipedia.org/wiki/Magic_square). Each method has a responsibility regarding the vetting/checking process to determine if it's a magic square or not. – Aramza Nov 30 '16 at 23:38

2 Answers2

0

Your method is not the problem. This is a case of G.I.G.O (Garbage in, Garbage out). You have called your method using incorrect arguments. In this case the third argument of the rowsEqTargetSum method should be n and instead you pass n*(n*n+1)/2 (targetSum). This value will always be above n for any n greater than 1 and therefore lead to an index out of bounds exception based on your code.

This same issue happens again within the method in your tail call of rowsEqTargetSum(null, 0, sum, sum, sum, sum) which is an infinite recursion (your next bug) since there is no alternative (completion) option in the method. This I believe will lead to your next error of a stack overflow IF your code is repaired to call methods with proper arguments.

Ralph Ritoch
  • 3,260
  • 27
  • 37
  • I changed return rowsEqTargetSum(null, 0, sum, sum, sum, sum); to (a, 0, sum...) and I hit a stack overflow error if that's the one you're talking about - that is after the change indicated by Acewin – Aramza Dec 01 '16 at 01:03
  • 1
    Yes, the stack overflow is due to the infinite recursion. If I understand your code correctly you should "return sum == targetSum;" instead of doing a recursion. – Ralph Ritoch Dec 01 '16 at 01:06
0

You need to be able to understand what an Exception is and how to resolve it. Your code execution in its output says java.lang.ArrayIndexOutOfBoundsException and at what line you are getting it.

First step to correct your logic is to avoid java.lang.ArrayIndexOutOfBoundsException

You can control the iteration as below

for(row=0; row<a.length; row++)
    {
        int[] rowArr = a[row];
        System.out.print("row "+row+": ");
        for(col=0; col<rowArr.length; col++)
        {
            int value = a[row][col];
            sum += value;
            if (col > 0)
                System.out.print(" + "); // print plus before all except 1st
            System.out.print(value);
        }
        System.out.println(" = "+sum);
        if(sum != targetSum)
        {
            System.out.println("Row sum incorrect : Not a magic Square!");
        }
    }

Step 1 -> int[] rowArr = a[row];

Step 2- >

int[] rowArr = a[row];
System.out.print("row "+row+": ");
for(col=0; col<rowArr.length; col++)

This leads to java.lang.NullPointerException when you make call return rowsEqTargetSum(null, 0, sum, sum, sum, sum);

Acewin
  • 1,657
  • 4
  • 17
  • 36
  • This method you have created has a different behavior as it doesn't enforce that the provided argument contains the same number of columns in each row. In this case the purpose of argument n is to ensure that the input always has the same number of columns as rows, otherwise there will be a null pointer exception. The null pointer exception could be caught to produce a more useful error like an invalid arguments exception but if the passed argument isn't square this method should throw an exception. – Ralph Ritoch Nov 30 '16 at 23:56
  • Actually I have not come to the point to avoid NullPointerException. Rather than understanding the whole problem in one go, my suggestion as what others have pointed out is understand the exception and work from there. You shouldnt code visulaizing all the steps but modify them one step at a time – Acewin Nov 30 '16 at 23:56
  • I don't know where you got the idea that "You shouldnt code visulaizing all the steps but modify them one step at a time" but this isn't an easily defended opinion as it doesn't allow any room for concurrency as you will see in GPU development and soon in mainstream development as we're facing 60+ core processors. – Ralph Ritoch Nov 30 '16 at 23:58
  • true there are different methodology to provide a solution, but first you should learn debugging and breaking down into steps. What you say will be correct for a seasoned developer but not a first time coder. And OP definitely is not a seasoned. And yes it is an individual opinion I am not going to defend it as a fool proof approach. – Acewin Dec 01 '16 at 00:02
  • My mistake in stating null pointer exception, I meant the IndexOutOfBounds exception. concurrency problems with my brain, lol. – Ralph Ritoch Dec 01 '16 at 00:03
  • hehe, we are overworked my friend. We should check other problems. I was also confused when you said NullPointer could have been avoided – Acewin Dec 01 '16 at 00:04