# c ++ – The biggest product of the Euler project n ° 11 in a grid | Optimized Cache + Sliding Window (C ++ 14)

Source: HackerRank & ProjectEuler.net

Problem: The biggest product in a grid
In the 20 × 20 grid below, four numbers along a diagonal 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 18 38 64 70
67 26 20 68 02 62 12 20 95 (63) 94 39 63 08 40 91 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 (78) 78 96 83 14 88 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 (14) 00 61 33 97 34 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 best product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20 × 20 grid?

Contribution
The entry consists of 20 lines each containing 20 integers.

Exit

limitations
0 ≤ each integer in grid ≤ 100

Sample
Contribution

``````89 90 95 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 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 14 34 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
``````

Exit

``````73812150
``````

My solution (C ++ 14)

``````#understand
#understand
#understand
#understand
#understand

// 2D grid represented by a 1D vector for cache optimization
auto getGrid (int lines, int columns) {
automatic values ​​= rows * columns;
std :: vector grid (values);
std :: copy_n (std :: istream_iterator(std :: cin), values, grid.begin ());
return grid;
}

class LargestProductInAGrid {
public:
LargestProductInAGrid (std :: vector & grid, int rows, int columns, int nAdjacent): grid_ (grid), rows_ (rows),
columns_ (columns),

auto greatestProductInAGrid () {
long long largestProduct = 0;

for (auto row = 0; row <rows_; row ++) {
largest product = std :: max (largest product, largest product in a row);
}

for (auto column = 0; column <columns_; column ++) {
largerProduct = std :: max (greaterProduct, greaterProductInColumn (column));
largerProduct = std :: max (greaterProduct, greaterProductInARightDiagonal (column));
biggerProduct = std :: max (biggerProduct, biggerProductInALeftDiagonal (column));
}

return the largest product;
}

private:
long long largerProductInARow (int row) {
int low = line * columns_, end = low + columns_;
long long currentProduct = 0, mostProduct = 0;

while (low + nAdjacents_ - 1 <end) {
if (currentProduct == 0) {
currentProduct = std :: accumulate (grid_.begin () + bottom, grid_.begin () + bottom + nAdjacent_, 1LL,
std :: multiplies <> ());
} other {
currentProduct / = grid_[low - 1];
currentProduct * = grid_[low + nAdjacents_ - 1];
}

if (currentProduct == 0) {
automatic zero = std :: find (grid_.begin () + bottom, grid_.begin () + bottom + nAdjacent_, 0);
weak + = zero - (grid_.begin () + low) + 1;
} other {
weak ++;
}

mostProduct = std :: max (mostProduct, currentProduct);
}

return the highest product;
}

int oneDIndex (int row, int column) {
return line * columns_ + column;
}

long long greatestProductInAColumn (int column) {
int row = 0;
long long currentProduct = 0, mostProduct = 0;

while (row + nAdjacents_ - 1 <rows_) {
if (currentProduct == 0) {
currentProduct = 1;
for (int i = row; i <row + nAdjacents_; i ++) {
currentProduct * = grid_[oneDIndex(i, column)];
}
} other {
currentProduct / = grid_[oneDIndex(row - 1, column)];
currentProduct * = grid_[oneDIndex(row + nAdjacents_ - 1, column)];
}

if (currentProduct == 0) {
while (grid_[oneDIndex(row, column)] ! = 0) {
row ++;
}
}

row ++;

mostProduct = std :: max (mostProduct, currentProduct);
}

return the highest product;
}

long long largerProductInARightDiagonal (int startedColumn) {
int row = 0, column = startingColumn;
long long currentProduct = 0, mostProduct = 0;

while (line + nAdjacents_ - 1 <rows_ && column + nAdjacent_ - 1 <columns_) {
if (currentProduct == 0) {
currentProduct = 1;
for (int i = row; i <row + nAdjacents_; i ++) {
currentProduct * = grid_[oneDIndex(i, column + i)];
}
} other {
currentProduct / = grid_[oneDIndex(row - 1, column - 1)];
currentProduct * = grid_[oneDIndex(row + nAdjacents_ - 1, column + nAdjacents_ - 1)];
}

if (currentProduct == 0) {
while (grid_[oneDIndex(row, column)] ! = 0) {
row ++, column ++;
}
}

row ++, column ++;

mostProduct = std :: max (mostProduct, currentProduct);
}

return the highest product;
}

long longerProductInALeftDiagonal (int startedColumn) {
int row = 0, column = startingColumn;
long long currentProduct = 0, mostProduct = 0;

while (row + nAdjacents_ - 1 < rows_ && column - nAdjacents_ + 1 >= 0) {
if (currentProduct == 0) {
currentProduct = 1;
for (int i = row; i <row + nAdjacents_; i ++) {
currentProduct * = grid_[oneDIndex(i, column - i)];
}
} other {
currentProduct / = grid_[oneDIndex(row - 1, column + 1)];
currentProduct * = grid_[oneDIndex(row + nAdjacents_ - 1, column - nAdjacents_ + 1)];
}

if (currentProduct == 0) {
while (grid_[oneDIndex(row, column)] ! = 0) {
row ++, column--;
}
}

row ++, column--;

mostProduct = std :: max (mostProduct, currentProduct);
}

return the highest product;
}

std :: vector Grid_;
int rows_;
int columns_;
};

int main () {
const int ranks = 20, columns = 20, nAdjacent = 4;
automatic grid = getGrid (rows, columns);
The LargestProductInAGrid solution (grid, rows, columns, nAdjacent);
std :: cout << solution.largestProductInAGrid () << std :: endl;
}
``````

Analysis
Temporal complexity: $$O (r * c)$$
Complexity of space: $$O (1)$$, not counting the initial data