2
\$\begingroup\$

I am completing the CodingBat exercises for Java. Here is the one I have completed just now:

Given n > = 0, create an array length n * n with the following pattern, shown here for n = 3 :

{0, 0, 1, 0, 2, 1, 3, 2, 1} (spaces added to show the 3 groups).

Here is my code:

    public int[] squareUp(int n){

    int[] ary = new int[n * n];
    int numberToInsert = 1;
    int count = 0;
    int target = n;

    //Guard condition for n = 1
    if (n == 1) {
        ary[0] = 1;
        return ary;
    }

    //Do the following n times
    for (int i = 0; i < n; i++) {
        //Working from the end of the array backwards, insert the number
        //at the appropriate point
        for (int j = ary.length - numberToInsert; j > 0; j -= n) {
            ary[j] = numberToInsert;
            //The amount of times a number is inserted decreases each
            //iteration
            count++;
            if (count == target) {
                count = 0;
                target--;
                break;
            }
        }
        numberToInsert++;
    }
    return ary;
}

My questions are:

  1. How would I implement this without the guard condition? The result without it is 0 because it doesn't get as far as the second for loop, as numberToInsert is already 1. I tried to set this as 0, and increment it later in the code, but I couldn't figure this out.
  2. What alternative is there to the count and target system I implemented? Was this a good or bad way to achieve the outcome?
  3. How else could the numbers be inserted? The method I used felt the most logical but I'm curious to see other methods.
\$\endgroup\$
  • \$\begingroup\$ Your program doesn't work as expected \$\endgroup\$ – D D Apr 17 '15 at 11:20
  • \$\begingroup\$ @Mr.777 please clarify. If the program isn't working as intended, the question is off-topic \$\endgroup\$ – Vogel612 Apr 19 '15 at 17:55
3
\$\begingroup\$

Addressing into a 1d or 2d array is not a real problem for a square array

ary[i,j] = value;

can be written as

ary[i*n + j] = value

where n is the dimension.

The following passes the tests on CodingBat though there may be more elegant ways to approach it

public int[] squareUp(int n) {
    int[] result = new int[n*n]; 
    int zeroCount = n-1;
    for(int outer = 0; outer <n; outer++){
        for(int inner = 0; inner < n; inner++){
            result[(outer * n) + inner] = zeroCount > inner
                                            ? 0
                                            : (n-inner);
        }
        zeroCount--;
    }
    return result;
}
\$\endgroup\$
  • \$\begingroup\$ Perfect man. I still am trying to figure out the solution :P \$\endgroup\$ – D D Apr 17 '15 at 12:26
2
\$\begingroup\$

Look at the problem and think about the algorithm first (do not get distracted by limitations like 1D array instead of 2D).

For example:

Fill each column with consecutive positive integers, starting from the last column. Additionally each consecutive column should contain one less row filled than previous (starting from the first row).

Then using @AlanT suggestion of how to convert 2D indexing into 1D one:

public int[] squareUp(int n) {
    int[] result = new int[n*n]; 
    int numberToInsert = 1;
    for(int column = n-1; column >= 0; column--){
        for(int row = n-1; row >= n-1-column; row--){
            result[(row * n) + column] = numberToInsert;
        }
        numberToInsert++;
    }
    return result;
}

Explanation:

Outer loop iterates columns, starting from the last one. Inner loop iterates rows, also starting from the last one, then uses column count to find stopping condition.

It also handles 0 and 1 array sizes. We also do not need to set 0 values as single-dimensional arrays of primitive values in Java will be set to default values on initialization.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.