There is a question on 2D array which says
Given a 6*6 matrix we have to print the largest (maximum) hourglass sum found in the matrix. An hourglass is described as:
Here's some overkill — four different ways to write the 'hourglass sum' function. For reasons outlined in user3629249's comment, I've renamed the functions to hourglass_N
(for N in 1..4). Of these variants, hourglass_1()
is pretty neat for this particular shape, but hourglass_2()
is more readily adaptable to other shapes.
The test code correctly handles matrices with negative maximum sums.
#include <assert.h>
#include <stdio.h>
enum { ARR_SIZE = 6 };
static int hourglass_1(int a[ARR_SIZE][ARR_SIZE], int i, int j)
{
assert(i >= 0 && i < ARR_SIZE - 2 && j >= 0 && j < ARR_SIZE - 2);
int sum = a[i+0][j+0] + a[i+0][j+1] + a[i+0][j+2]
+ a[i+1][j+1] +
a[i+2][j+0] + a[i+2][j+1] + a[i+2][j+2];
return sum;
}
static int hourglass_2(int a[ARR_SIZE][ARR_SIZE], int i, int j)
{
assert(i >= 0 && i < ARR_SIZE - 2 && j >= 0 && j < ARR_SIZE - 2);
static const int rows[] = { 0, 0, 0, 1, 2, 2, 2 };
static const int cols[] = { 0, 1, 2, 1, 0, 1, 2 };
enum { HG_SIZE = sizeof(rows) / sizeof(rows[0]) };
int sum = 0;
for (int k = 0; k < HG_SIZE; k++)
sum += a[rows[k]+i][cols[k]+j];
return sum;
}
static int hourglass_3(int a[ARR_SIZE][ARR_SIZE], int i, int j)
{
assert(i >= 0 && i < ARR_SIZE - 2 && j >= 0 && j < ARR_SIZE - 2);
int sum = 0;
for (int i1 = 0; i1 < 3; i1++)
{
for (int j1 = 0; j1 < 3; j1++)
{
if (i1 == 1)
{
sum += a[i + i1][j + j1 + 1];
break;
}
else
sum += a[i + i1][j + j1];
}
}
return sum;
}
static int hourglass_4(int a[ARR_SIZE][ARR_SIZE], int i, int j)
{
assert(i >= 0 && i < ARR_SIZE - 2 && j >= 0 && j < ARR_SIZE - 2);
int n = i + 3;
int m = j + 3;
int sum = 0;
for (int i1 = i; i1 < n; i1++)
{
for (int j1 = j; j1 < m; j1++)
{
if (i1 == n - 2)
{
sum += a[i1][j1 + 1];
break;
}
else
sum += a[i1][j1];
}
}
return sum;
}
typedef int (*HourGlass)(int arr[ARR_SIZE][ARR_SIZE], int i, int j);
static void test_function(int arr[ARR_SIZE][ARR_SIZE], const char *tag, HourGlass function)
{
int max_sum = 0;
int max_row = 0;
int max_col = 0;
for (int i = 0; i < (ARR_SIZE-2); i++)
{
for (int j = 0; j < (ARR_SIZE-2); j++)
{
int n = (*function)(arr, i, j);
if (n > max_sum || (i == 0 && j == 0))
{
max_sum = n;
max_row = i;
max_col = j;
}
}
}
printf("%s: %3d at (r=%d,c=%d)\n", tag, max_sum, max_row, max_col);
}
int main(void)
{
int arr[ARR_SIZE][ARR_SIZE];
for (int i = 0; i < ARR_SIZE; i++)
{
for (int j = 0; j < ARR_SIZE; j++)
{
if (scanf("%d", &arr[i][j]) != 1)
{
fprintf(stderr, "Failed to read integer (for row %d, col %d)\n", i, j);
return 1;
}
}
}
test_function(arr, "hourglass_1", hourglass_1);
test_function(arr, "hourglass_2", hourglass_2);
test_function(arr, "hourglass_3", hourglass_3);
test_function(arr, "hourglass_4", hourglass_4);
return 0;
}
For various different data sets, the code produces the correct answer.
Set 1:
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 2 4 4 0
0 0 0 2 0 0
0 0 1 2 4 0
hourglass_1: 19 at (r=3,c=2)
hourglass_2: 19 at (r=3,c=2)
hourglass_3: 19 at (r=3,c=2)
hourglass_4: 19 at (r=3,c=2)
Set 2:
-1 -1 -1 +0 +0 +0
+0 -1 +0 +0 +0 +0
+1 -1 +1 +0 +0 +0
+0 +0 -2 +4 -4 +0
+0 +0 +0 +2 +0 +0
+0 +0 +1 +2 -4 +0
hourglass_1: 7 at (r=2,c=2)
hourglass_2: 7 at (r=2,c=2)
hourglass_3: 7 at (r=2,c=2)
hourglass_4: 7 at (r=2,c=2)
Set 3:
-7 -2 -9 -7 -4 -4
-6 0 -7 -5 -8 -1
-9 -1 -2 -1 -3 -3
-9 -1 -3 -6 -2 -9
-8 -1 -3 -7 -7 -9
0 -3 -5 -2 -2 -5
hourglass_1: -18 at (r=2,c=1)
hourglass_2: -18 at (r=2,c=1)
hourglass_3: -18 at (r=2,c=1)
hourglass_4: -18 at (r=2,c=1)
Set 4:
-7 -7 0 -7 -8 -7
-9 -1 -5 -6 -7 -8
-2 0 -7 -7 -6 -3
-5 -3 -1 -6 -3 -1
-3 -5 0 -5 0 -7
-1 -2 -8 -8 -9 -9
hourglass_1: -20 at (r=2,c=0)
hourglass_2: -20 at (r=2,c=0)
hourglass_3: -20 at (r=2,c=0)
hourglass_4: -20 at (r=2,c=0)
The error is probably in your sum
function. The way you did it is a bit of an overkill, it'd be much simpler (and readable!) for you to do sth like this:
#define GRID_SIZE (6)
int sum(int a[GRID_SIZE][GRID_SIZE], int i, int j)
{ // Define an hourglass by the index i,j of its central element
int sum = a[j-1][i-1] + a[j-1][i] + a[j-1][i+1] +
a[j][i] +
a[j+1][i-1] + a[j+1][i] + a[j+1][i+1];
return sum;
}
Then just be sure you iterate with sane values (in [1, len-2]):
for (int i = 1; i < (GRID_SIZE-1); i++)
{
for (int j = 1; j < (GRID_SIZE-1); j++)
{
n = sum(arr, i, j);
if (n > max)
max = n;
}
}
Edit: Check that it works here: http://www.cpp.sh/46jhy
Thanks, that was light fun :-).
PS: Make sure you check some coding standards document, it'll make your life a lot easier in the long run, just search for "C code format standard" and get used to trying to work with one you like. Unless you do something new and on your own, you will probably have to follow a standard and maybe not even have a say in which one, so get familiar with general rules and used to following one, whichever you like.
#include <stdio.h>
int main() {
int numbers[6][6];
for (int i = 0; i < 6; i++){
for (int j = 0; j < 6; j++){
scanf("%d",&numbers[i][j]);
}
}
int currentHourGlass;
int largestSum = -999;
for (int i = 1; i < 5; i++){
for (int j = 1; j < 5; j++){
currentHourGlass = 0;
currentHourGlass += numbers[i-1][j-1];
currentHourGlass += numbers[i-1][j];
currentHourGlass += numbers[i-1][j+1];
currentHourGlass += numbers[i][j];
currentHourGlass += numbers[i+1][j-1];
currentHourGlass += numbers[i+1][j];
currentHourGlass += numbers[i+1][j+1];
if (currentHourGlass > largestSum)
{
largestSum = currentHourGlass;
}
}
}
printf("%d", largestSum);
}