views:

211

answers:

3

Ok, so I have an array like so:

1 2 3
4 5 6
7 8 9

Doesn't necessarily have to be any specific size, just showing it so you guys have something to look at. So I have to go through each number, and calculate the average of the numbers that are surrounding it. For example, for the number 1 I have to calculate the average of 2, 5, and 4. I have to compare that average to the number itself, but that's not my issue. My issue is running through an array of any size (determined by the user) and examining the numbers around it. Now, I could program a separate method for each section, meaning a separate method for each corner, a separate method for each side, and a method for the center. But that sounds like a lot more work and a lot less efficient. So, I've decided to make a sort of border around the outside. This border will be filled with 0's, assuming that 0 will never be an input value. This is so that I will not run out of my array, but i can run one coded function on the inside of this border, so that it calculates the average of the 8 surrounding numbers.

So I'm wondering how I could go about running through an array and ignore any 0's it comes across, but take the average of the other numbers around it?

Example:
0 0 0 0 0
0 1 2 3 0
0 4 5 6 0
0 7 8 9 0
0 0 0 0 0

so in the first spot, it'd take the average of the numbers 2, 4, and 5, but ignore the 0's. the reason I need to ignore them is because:
1. I cannot include them in the number count because even though adding 0 won't affect the total, it'll affect the amount of numbers to divide by in obtaining the average
2. I won't actually be using 0 since 0 is a possible input, it'll actually be -1. I put 0 here for the ease of typing and readability.

Suggested best method of going about this?

EDIT2:

So now, I'm getting an output that's close to what I should be getting. But I've thoroughly looked through and I can't see where this error is coming about.

public static int calculate(int[][] array, int row, int col){
    double num = 0;//Used to find the total of real numbers to be divided by
    double total = 0;
    double average;

    for (int a = -1; a <= 1; a++) 
    {
        for (int b = -1; b <= 1; b++) 
        {
            if(row + a < 0 || col + b < 0)
            {
                continue;
            }
            if(a == 0 && b == 0)//if(row + a == row || col + b == col)
            {
                continue;
            }
            if(row + a >= r || col + b >= c)
            {
                continue;
            }
            else
            {                   
                num+=1;
                total+= array[row + a][b + col];
                System.out.println("row+a = " + (row + a) + " and col+b = " + (col + b));
            }
        }
     }

    average = (double)(total/num);
    count++;
    System.out.print(count + ". Average = " + total + " divided by " + num + " = " + average + "\n");

    if (average < array[row][col])
        return 255;
    else
        return 0;
}

Into this function, I put each value in the array (going through each row) to be changed to either 0 or 255. Apparently, the correct final result should be: 0 255 0 255 0

0 0 255 0 0

255 0 255 0 255

255 0 0 0 0

0 255 0 0 255

But I'm getting

0 255 0 255 0

0 0 0 0 0

255 0 255 0 255

0 0 0 0 0

255 0 255 0 255

So I'm looking into those specific differences and I'm going to see where the issue is.

+3  A: 

So, I've decided to make a sort of border around the outside.

Trivia - Dan and Kathy Spacklen (Spacken?) did this wit their chessboard when they wrote Sargon 30 years ago.

You can do the border but I think it isn't going to help much. Tell me, in your first example

1 2 3
4 5 6
7 8 9

Assuming #1 is at [0][0], what would be the indexes for the 8 cells surrounding #2?

Tony Ennis
+1 For guidance without doing the homework.
Jim Ferrans
assuming [r][c] --> [-1][0], [-1][1], [-1][2], [0][0] , [1][1] , [1][2] , [1][3] , [0][3]
rar
Good. Now, some of those values are impossible. Why? Simply do the loop you clearly did in your head, and ignore the impossible values. Then you're golden.
Tony Ennis
So my thought would be to run through each of these possibilities, but won't saying "ignore the impossible values" be running outside of the array? Or is there a way in Java to check if that position does not exist?
rar
They are outside your array. That's why they are easy to detect. In the list you posted 3 comments up, how do you know the first element is impossible? Before you include a number in the average, make sure its indexes aren't impossible.
Tony Ennis
I guess my question was...how can you check if a spot in an array does not exist? I can't put "if array[-1][0] does not exist" can I?Second thought: you mean to check if the loop variable is less than 0? that would be the easiest way...how did I not think of it?
rar
@rar - A lot of programming is easy, once you figure out the trick. Good job!
Tony Ennis
@TonyI've edited the question to include my latest progress, could you take another look?
rar
@rar - please explain to me what happens if row and col are each 5 and the grid is a 10x10 grid. Show the 8 coordinates that you'll be testing.
Tony Ennis
[4][4], [4][5], [4][6], [5][4], [5][6], [6][4], [6][5], [6][6]. that's what I'm expecting.
rar
Do you think the following is doing what you want? `if(row + a == row || col + b == col)`
Tony Ennis
@Tony I've changed that to `if(a == 0 || b == 0) continue;` but it didn't give me any better results, since that's essentially the same thing (or so I intended). My intention was to ignore the current number (being the centre of all calculated numbers). How should it look instead? I'm confused as to what's wrong...
rar
@rar col+b == col whenever b is 0. But should you be discounting a's value? Also, please explain to me exactly what that 'else' does. Finally, are r and c your maximum grid dimensions?
Tony Ennis
For fun, you can print the values of the row+a and col+b when we get into your else statement. Then we can see which coordinates are being ignored.
Tony Ennis
@Tony I'm still a bit confused...why wouldn't I discount a's value? If I just said "when col + b = col" then wouldn't that say anytime it's in the same column it'd ignore it? Meaning the whole column would be ignored?Is is perhaps that I need to discount any a impossibilities in the outer for loop, and the b impossibilities on the inner for loop?
rar
the "else" adds to the count of numbers (to divide by later when finding the average) and the total is the sum of all the numbers to be divided by num to find the average.
rar
You're right, ignore my comment about the `else` - I'm at work and really should be paying more attention. So, just print out the coordinates you're not ignoring and if there are any problems they'll become evident.
Tony Ennis
I seem to be getting an answer the way I've modified my code now, but I'm unsure currently if it's the correct result so I have to verify it. Thanks for your help, though, and I'll post my progress here later.
rar
+3  A: 

It seems to me that the simplest solution is to go through all possible cells in a loop and for each to see if it's inside the matrix. It's not exactly short, but there's no ugly unreadable conditions involved and you don't have to surround matrix with anything.

int sum = 0;
int amount = 0;
for (int di = -1; di <= 1; ++di) {
    for (int dj = -1; dj <= 1; ++dj) {
        // check that cell (i0 + di, j0 + dj) is inside the matrix
        // and not the original cell (i0, j0)
        // increase 'sum' and 'amount' if necessary
    }
}

return (double) sum / amount;

edit
Removed part of the code to leave some challenge in the problem

Nikita Rybak
It's homework, I think.
Tony Ennis
@Tony thanks, updated it
Nikita Rybak
@rar it seems like finding determinant for a matric |A| nxn
Suresh S
+3  A: 

The following is the code that I use to determine if a cell lives or dies in the game of life.

private static boolean lives(Point p, byte[][] squares) {
    int liveNeighboors = 0;
    for (int i = p.x - 1; i < p.x + 2; i++) {
        for (int j = p.y - 1; j < p.y + 2; j++) {
            if (new Point(i, j).equals(p))
                continue;
            try {
                liveNeighboors += squares[i][j];
            } catch (Exception e) {
                // this happens if you try to sum an edge space
            }
        }
    }
    if (squares[p.x][p.y] == 0) {
        return liveNeighboors == 3;
    } else {
        return liveNeighboors == 2 || liveNeighboors == 3;
    }
}

You could adapt this to sum the numbers and return the average instead of whether or not the cell should live or die.

This would need to be called in a loop like so:

for(int i = 0;  i < arr.length; i++) {
    for (int j = 0;j < arr[0].length; j++) {
        lives(new Point(i,j), arr);
    }
}
jjnguy