user3470214
user3470214

Reputation: 35

Sum of selected elements in 2d array (box shape?)

I'm currently creating a 2d array to represent elements on a grid to be laid out for a game. I would like to be able to Sum a specific block of elements, but I can't seem to get my function to work correctly, and I suspect there is a far easier way to do this.

Example of Array:

int[6,6] myArray = {{2,1,4,3,1,2,5}
                ,{4,2,3,3,1,2,4}
                ,{3,4,9,1,2,7,5}
                ,{1,6,2,1,3,4,2}
                ,{2,1,4,6,2,1,0}
                ,{6,2,8,1,6,5,7}
                ,{7,6,10,3,9,7,2}};

Current Code:

int BoxSum(int x, int y, int x1, int y1,  int [,] arrayM) {
        int Results = 0; 
        int xmod = (x1 - x) / Mathf.Abs (x1 - x);
        int ymod = (y1 - y) / Mathf.Abs (y1 - y);
        if (x1 > x & y1 > y) {
            for (int ix = x; ix <= x1; ix ++) {
                for (int iy = y; iy <= y1; iy++) {
                    Results += arrayM [ix, iy];
                }
            }
        }
        if (x1 > x & y1 < y) {
            for (int ix = x; ix <= x1; ix ++) {
                for (int iy = y; iy <= y1; iy--) {
                    Results += arrayM [ix, iy];
                }
            }
        }
        if (x1 < x & y1 < y) {
            for (int ix = x; ix <= x1; ix --) {
                for (int iy = y; iy <= y1; iy--) {
                    Results += arrayM [ix, iy];
                }
            }
        }
        if (x1 < x & y1 > y) {
            for (int ix = x; ix <= x1; ix ++) {
                for (int iy = y; iy <= y1; iy--) {
                    Results += arrayM [ix, iy];
                }
            }
        }
        return Results;
    }

So, if I were to enter:

(BoxSum(1,1,5,5,myArray));

or

(BoxSum(5,5,1,1,myArray));

I would want to get 86 for both (independent of whether I enter x,y or x1,y1 first in the command). Right now they give me different results, 86 and 0.

Thank you for your help!

Upvotes: 2

Views: 129

Answers (3)

Doug E Fresh
Doug E Fresh

Reputation: 840

If I'm reading your question right you just want one nest for loops so: edit: forgot the bit that sorts out the start and stop positions! Added it. Also taking phoogs suggestion of using math min and max

using System;
public class boxes{
public int[6,6] myArray;
public void boxes(){ // This is just a constructor. 
myArray = {{2,1,4,3,1,2,5}
                ,{4,2,3,3,1,2,4}
                ,{3,4,9,1,2,7,5}
                ,{1,6,2,1,3,4,2}
                ,{2,1,4,6,2,1,0}
                ,{6,2,8,1,6,5,7}
                ,{7,6,10,3,9,7,2}};
}
public int BoxSum(int x, int y, int x1, int y1) {
int sum = 0;
int xstart = Math.Min(x1, x);
int ystart = Math.Min(y1, y);
int xend = Math.Max(x1, x);
int yend = Math.Max(y1, y);
for(int i=xstart;i<=xend;i++)
{
    for(int j=ystart;j<=yend;j++)
    {
        sum += myArray[i,j];
    }
}
return sum;
}
}

I wrote up a simple class, I'm assuming you have something similar. If the method is a member of the class that has your array in it you won't need to pass it to the method.

Upvotes: 2

phoog
phoog

Reputation: 43056

None of the existing answers explains why you got the wrong result in one case. The problem is a bug in the block that handles that case:

if (x1 < x & y1 < y) {
    for (int ix = x; ix <= x1; ix --) {
        for (int iy = y; iy <= y1; iy--) {
            Results += arrayM [ix, iy];
        }
    }
}

It should be:

if (x1 < x & y1 < y) {
    for (int ix = x; ix >= x1; ix --) {
        for (int iy = y; iy >= y1; iy--) {
            Results += arrayM [ix, iy];
        }
    }
}

This is a great example of why the Don't repeat yourself (DRY) principle is important. Spare yourself the headache and do as the other answers suggest.

Upvotes: 1

Saragis
Saragis

Reputation: 1792

If you want it to work regardless of which parameters are the high/low values, you could do something like this.

    private int BoxSum(int x, int y, int x1, int y1, int[,] arrayM)
    {
        int lowestX = (x1 > x) ? x : x1;
        int lowestY = (y1 > y) ? y : y1;

        int highestX = (x1 > x) ? x1 : x;
        int highestY = (y1 > y) ? y1 : y;

        int sum = 0;

        for (int i = lowestX; i < highestX; i++)
        {
            for (int j = lowestY; j < highestY; j++)
            {
                sum += arrayM[i, j];
            }
        }

        return sum;
    }

Upvotes: 3

Related Questions