Project Euler Problem 11
Problem 11 : Largest product in a grid
In the 20×20 grid below, four numbers along a diagonal line have been marked in red.
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
The product of these numbers is 26 × 63 × 78 × 14 = 1788696.
What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid?
#include <iostream>
#include <cassert>
using namespace std;
const int MAX_SIZE = 20;
const int MAX_STEPS = 4;
int Matrix[MAX_SIZE][MAX_SIZE] = {
{ 8,02,22,97,38,15,00,40,00,75,04,05,07,78,52,12,50,77,91, 8},
{49,49,99,40,17,81,18,57,60,87,17,40,98,43,69,48,04,56,62,00},
{81,49,31,73,55,79,14,29,93,71,40,67,53,88,30,03,49,13,36,65},
{52,70,95,23,04,60,11,42,69,24,68,56,01,32,56,71,37,02,36,91},
{ 22,31,16,71,51,67,63,89,41,92,36,54,22,40,40,28,66,33,13,80},
{24,47,32,60,99,03,45,02,44,75,33,53,78,36,84,20,35,17,12,50},
{32,98,81,28,64,23,67,10,26,38,40,67,59,54,70,66,18,38,64,70},
{67,26,20,68,02,62,12,20,95,63,94,39,63, 8,40,91,66,49,94,21},
{24,55,58,05,66,73,99,26,97,17,78,78,96,83,14,88,34,89,63,72},
{21,36,23, 9,75,00,76,44,20,45,35,14,00,61,33,97,34,31,33,95},
{78,17,53,28,22,75,31,67,15,94,03,80,04,62,16,14, 9,53,56,92},
{16,39,05,42,96,35,31,47,55,58,88,24,00,17,54,24,36,29,85,57},
{86,56,00,48,35,71,89,07,05,44,44,37,44,60,21,58,51,54,17,58},
{19,80,81,68,05,94,47,69,28,73,92,13,86,52,17,77,04,89,55,40},
{04,52, 8,83,97,35,99,16,07,97,57,32,16,26,26,79,33,27,98,66},
{88,36,68,87,57,62,20,72,03,46,33,67,46,55,12,32,63,93,53,69},
{04,42,16,73,38,25,39,11,24,94,72,18, 8,46,29,32,40,62,76,36},
{20,69,36,41,72,30,23,88,34,62,99,69,82,67,59,85,74,04,36,16},
{20,73,35,29,78,31,90,01,74,31,49,71,48,86,81,16,23,57,05,54},
{01,70,54,71,83,51,54,69,16,92,33,48,61,43,52,01,89,19,67,48}
};
// #define UNIT_TEST
class PE0011
{
private:
int m_maxProduct;
#ifdef UNIT_TEST
int m_adjacentNumbersArray[MAX_STEPS];
#endif
void getMaxProductFromUpToDown();
void getMaxProductFromLeftToRight();
void getMaxProductFromLeftDownToRightUp();
void getMaxProductFromLeftUpToRightDown();
public:
PE0011() { m_maxProduct = 1;};
long int getMaxProduct();
#ifdef UNIT_TEST
void printAdjacentNumbers();
#endif
};
void PE0011::getMaxProductFromUpToDown()
{
long int product;
int loopCount = 0;
// from up to down (0 --> 19) && from left -> right (0 --> 19)
// Matrix[row][col], Matrix[row][col+1], Matrix[row][col+2], Matrix[row][col+3]
for (int row=0; row<MAX_SIZE; row++)
{
for (int col=0; col+3<MAX_SIZE; col++)
{
product = Matrix[row][col]*Matrix[row][col+1]*Matrix[row][col+2]*Matrix[row][col+3];
if (product > m_maxProduct)
{
m_maxProduct = product;
#ifdef UNIT_TEST
m_adjacentNumbersArray[0] = Matrix[row][col];
m_adjacentNumbersArray[1] = Matrix[row][col+1];
m_adjacentNumbersArray[2] = Matrix[row][col+2];
m_adjacentNumbersArray[3] = Matrix[row][col+3];
#endif
}
loopCount++;
}
}
// 17, 17, ... 17 (20 times) // (MAX_SIZE-MAX_STEPS+1)*MAX_SIZE
assert(17*20 == loopCount);
}
void PE0011::getMaxProductFromLeftToRight()
{
long int product;
int loopCount = 0;
// from left -> right (0 --> 19) && from up to down (0 --> 19)
// Matrix[col][row], Matrix[col][row+1], Matrix[col][row+2], Matrix[col][row+3]
for (int col=0; col<MAX_SIZE; col++)
{
for (int row=0; row+3<MAX_SIZE; row++)
{
product = Matrix[col][row]*Matrix[col][row+1]*Matrix[col][row+2]*Matrix[col][row+3];
if (product > m_maxProduct)
{
m_maxProduct = product;
#ifdef UNIT_TEST
m_adjacentNumbersArray[0] = Matrix[col][row];
m_adjacentNumbersArray[1] = Matrix[col][row+1];
m_adjacentNumbersArray[2] = Matrix[col][row+2];
m_adjacentNumbersArray[3] = Matrix[col][row+3];
#endif
}
loopCount++;
}
}
// 20, 20, ... 20 (17 times) // MAX_SIZE*(MAX_SIZE-MAX_STEPS+1)
assert(20*17 == loopCount);
}
void PE0011::getMaxProductFromLeftDownToRightUp()
{
long int product;
int loopCount = 0;
// diagonally1:left-down to right-up
// Matrix[row][col], Matrix[row-1][col+1], Matrix[row-2][col+2], Matrix[row-3][col+3]
for (int row=3; row<MAX_SIZE; row++)
{
for(int col=0; col+3<MAX_SIZE;col++)
{
product = Matrix[row][col]*Matrix[row-1][col+1]*Matrix[row-2][col+2]*Matrix[row-3][col+3];
if (product > m_maxProduct)
{
m_maxProduct = product;
#ifdef UNIT_TEST
m_adjacentNumbersArray[0] = Matrix[row][col];
m_adjacentNumbersArray[1] = Matrix[row-1][col+1];
m_adjacentNumbersArray[2] = Matrix[row-2][col+2];
m_adjacentNumbersArray[3] = Matrix[row-3][col+3];
#endif
}
loopCount++;
}
}
// 1, 2, ..., 16, 17, 16, .... , 2, 1
assert((16+1)*16 + 17 == loopCount);
}
void PE0011::getMaxProductFromLeftUpToRightDown()
{
long int product;
int loopCount = 0;
// diagonally2:left-up to right-down
// Matrix[row][col], Matrix[row+1][col+1], Matrix[row+2][col+2], Matrix[row+3][col+3]
loopCount = 0;
for (int row=0; row+3<MAX_SIZE; row++)
{
for(int col=0; col+3<MAX_SIZE;col++)
{
product = Matrix[row][col]*Matrix[row+1][col+1]*Matrix[row+2][col+2]*Matrix[row+3][col+3];
if (product > m_maxProduct)
{
m_maxProduct = product;
#ifdef UNIT_TEST
m_adjacentNumbersArray[0] = Matrix[row][col];
m_adjacentNumbersArray[1] = Matrix[row+1][col+1];
m_adjacentNumbersArray[2] = Matrix[row+2][col+2];
m_adjacentNumbersArray[3] = Matrix[row+3][col+3];
#endif
}
loopCount++;
}
}
// 1, 2, ..., 16, 17, 16, .... , 2, 1
assert((16+1)*16 + 17 == loopCount);
}
#ifdef UNIT_TEST
void PE0011::printAdjacentNumbers()
{
cout << "The four adjacent numbers are " << m_adjacentNumbersArray[0] << ", ";
cout << m_adjacentNumbersArray[1] << ", " << m_adjacentNumbersArray[2] << ", ";
cout << m_adjacentNumbersArray[3] << endl;
}
#endif
long int PE0011::