Largest Product in a Grid
Let G = (g_(i,j))_(0 <= i,j <= 19) be a 20 x 20 matrix of non-negative integers (given below). Find the greatest product of four adjacent entries along any horizontal, vertical, or diagonal line.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
In the \(20 \times 20\) grid below, four numbers along a diagonal line have been marked in red. \[ \begin {tabular}{cccccccccccccccccccc} 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 & \textcolor {red}{26} & 38 & 40 & 67 & 59 & 54 & 70 & 66 & 18 & 38 & 64 & 70 \\ 67 & 26 & 20 & 68 & 02 & 62 & 12 & 20 & 95 & \textcolor {red}{63} & 94 & 39 & 63 & 08 & 40 & 91 & 66 & 49 & 94 & 21 \\ 24 & 55 & 58 & 05 & 66 & 73 & 99 & 26 & 97 & 17 & \textcolor {red}{78} & 78 & 96 & 83 & 14 & 88 & 34 & 89 & 63 & 72 \\ 21 & 36 & 23 & 09 & 75 & 00 & 76 & 44 & 20 & 45 & 35 & \textcolor {red}{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 \end {tabular} \] The product of these numbers is \(26 \times 63 \times 78 \times 14 = 1788696\).
What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the \(20 \times 20\) grid?
Problem 11: Largest Product in a Grid
Mathematical Development
Definitions
Definition 1. For a direction vector , define the -product of length starting at as
provided all indices for .
Definition 2. The feasible set for direction is
Theorems
Theorem 1 (Completeness of four directions). The four direction vectors , , , suffice to enumerate every set of collinear adjacent entries in the grid. No products are missed and none are double-counted.
Proof. An arbitrary direction vector for collinear adjacency has the form with . Consider any line segment of cells in direction starting at . Its reverse, in direction , starts at and traverses the same multiset of cells. Since multiplication is commutative, the product is identical. We pair directions:
- (horizontal),
- (vertical),
- (main diagonal),
- (anti-diagonal).
Each pair is represented by exactly one of our four chosen directions. Thus every product appears exactly once in .
Lemma 1 (Product count). For and , the total number of products is .
Proof. We compute for each direction:
| Direction | Row constraint | Column constraint | Count |
|---|---|---|---|
Total: .
Theorem 2 (Correctness of brute-force search). The algorithm below computes by exhaustive enumeration over all products.
Proof. The nested loops iterate over every for each of the four directions, computing each product exactly once and tracking the running maximum. By Theorem 1, this covers all possible products.
Editorial
We exhaustively evaluate the product of four adjacent entries in each relevant direction. The algorithm traverses every grid position, tests the horizontal, vertical, main-diagonal, and anti-diagonal directions whenever four cells remain in bounds, multiplies those four entries, and retains the largest product seen. This is sufficient because these four directions cover every possible set of four collinear adjacent cells.
Pseudocode
Algorithm: Maximum Grid Product Over Four Directions
Require: A rectangular grid G and a segment length 4.
Ensure: The greatest product of four adjacent grid entries in any allowed direction.
1: Initialize best ← 0.
2: For each cell (i, j) of G and each direction v in {(0, 1), (1, 0), (1, 1), (1, -1)} do:
3: If the 4-term segment starting at (i, j) in direction v stays inside the grid, compute its product P.
4: If P > best, set best ← P.
5: Return best.
Complexity Analysis
Proposition. The algorithm runs in time and space.
Proof. There are starting positions across all directions (precisely by Lemma 1, which is for fixed ). Each product requires multiplications, so total work is . The grid occupies space, and the algorithm uses auxiliary variables.
For , : exactly multiplications and comparisons.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
int main() {
int G[20][20] = {
{ 8, 2,22,97,38,15, 0,40, 0,75, 4, 5, 7,78,52,12,50,77,91, 8},
{49,49,99,40,17,81,18,57,60,87,17,40,98,43,69,48, 4,56,62, 0},
{81,49,31,73,55,79,14,29,93,71,40,67,53,88,30, 3,49,13,36,65},
{52,70,95,23, 4,60,11,42,69,24,68,56, 1,32,56,71,37, 2,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, 3,45, 2,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, 2,62,12,20,95,63,94,39,63, 8,40,91,66,49,94,21},
{24,55,58, 5,66,73,99,26,97,17,78,78,96,83,14,88,34,89,63,72},
{21,36,23, 9,75, 0,76,44,20,45,35,14, 0,61,33,97,34,31,33,95},
{78,17,53,28,22,75,31,67,15,94, 3,80, 4,62,16,14, 9,53,56,92},
{16,39, 5,42,96,35,31,47,55,58,88,24, 0,17,54,24,36,29,85,57},
{86,56, 0,48,35,71,89, 7, 5,44,44,37,44,60,21,58,51,54,17,58},
{19,80,81,68, 5,94,47,69,28,73,92,13,86,52,17,77, 4,89,55,40},
{ 4,52, 8,83,97,35,99,16, 7,97,57,32,16,26,26,79,33,27,98,66},
{88,36,68,87,57,62,20,72, 3,46,33,67,46,55,12,32,63,93,53,69},
{ 4,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, 4,36,16},
{20,73,35,29,78,31,90, 1,74,31,49,71,48,86,81,16,23,57, 5,54},
{ 1,70,54,71,83,51,54,69,16,92,33,48,61,43,52, 1,89,19,67,48}
};
const int N = 20, L = 4;
int dirs[][2] = {{0,1},{1,0},{1,1},{1,-1}};
long long best = 0;
for (auto& d : dirs)
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++) {
int ei = i + (L-1)*d[0], ej = j + (L-1)*d[1];
if (ei < 0 || ei >= N || ej < 0 || ej >= N) continue;
long long p = 1;
for (int k = 0; k < L; k++)
p *= G[i + k*d[0]][j + k*d[1]];
best = max(best, p);
}
cout << best << endl;
return 0;
}
"""Project Euler Problem 11: Largest Product in a Grid"""
def solve():
GRID = [
[ 8, 2,22,97,38,15, 0,40, 0,75, 4, 5, 7,78,52,12,50,77,91, 8],
[49,49,99,40,17,81,18,57,60,87,17,40,98,43,69,48, 4,56,62, 0],
[81,49,31,73,55,79,14,29,93,71,40,67,53,88,30, 3,49,13,36,65],
[52,70,95,23, 4,60,11,42,69,24,68,56, 1,32,56,71,37, 2,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, 3,45, 2,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, 2,62,12,20,95,63,94,39,63, 8,40,91,66,49,94,21],
[24,55,58, 5,66,73,99,26,97,17,78,78,96,83,14,88,34,89,63,72],
[21,36,23, 9,75, 0,76,44,20,45,35,14, 0,61,33,97,34,31,33,95],
[78,17,53,28,22,75,31,67,15,94, 3,80, 4,62,16,14, 9,53,56,92],
[16,39, 5,42,96,35,31,47,55,58,88,24, 0,17,54,24,36,29,85,57],
[86,56, 0,48,35,71,89, 7, 5,44,44,37,44,60,21,58,51,54,17,58],
[19,80,81,68, 5,94,47,69,28,73,92,13,86,52,17,77, 4,89,55,40],
[ 4,52, 8,83,97,35,99,16, 7,97,57,32,16,26,26,79,33,27,98,66],
[88,36,68,87,57,62,20,72, 3,46,33,67,46,55,12,32,63,93,53,69],
[ 4,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, 4,36,16],
[20,73,35,29,78,31,90, 1,74,31,49,71,48,86,81,16,23,57, 5,54],
[ 1,70,54,71,83,51,54,69,16,92,33,48,61,43,52, 1,89,19,67,48],
]
N, L = 20, 4
best = 0
for dr, dc in [(0, 1), (1, 0), (1, 1), (1, -1)]:
for i in range(N):
for j in range(N):
if not (0 <= i + (L - 1) * dr < N and 0 <= j + (L - 1) * dc < N):
continue
p = 1
for k in range(L):
p *= GRID[i + k * dr][j + k * dc]
best = max(best, p)
return best
answer = solve()
assert answer == 70600674
print(answer)