Tim Varley Logo
Tim Varley Principal AI Engineer and Tech Leader
Problem #11 medium

Largest Product in a Grid

In the 20x20 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 x 63 x 78 x 14 = 1788696.

What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20x20 grid?

View on Project Euler

Implementations

cpp
// https://projecteuler.net/problem=11
// Largest product in a grid
//
// In the 20x20 grid below, four numbers along a diagonal line have been marked in red.
//
// 8 2 22 97 38 15 00 40 00 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 00
// 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 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 3 80 4 62 16 14 9 53 56 92
// 16 39 5 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
// 86 56 00 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
// The product of these numbers is 26 x 63 x 78 x 14 = 1788696.
//
// What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20x20 grid?
// Answer: 70600674
#include <iomanip>
#include <iostream>
#include <cmath>
#include <cstdint>
static const int 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,00,
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,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, 3,80, 4,62,16,14, 9,53,56,92,
16,39, 5,42,96,35,31,47,55,58,88,24,00,17,54,24,36,29,85,57,
86,56,00,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
};
uint64_t largest_grid_product_brute()
{
uint64_t max = 0;
for( size_t i = 0 ; i < 400; i++ ){
int r = std::floor(i/20);
int c = ((i-(r*20))%20);
uint64_t rl_sum = 0;
uint64_t ud_sum = 0;
uint64_t f_diag_sum = 0;
uint64_t b_diag_sum = 0;
if( c < 17 ){
rl_sum = grid[i] *
grid[i+1] *
grid[i+2] *
grid[i+3];
max = std::max(rl_sum,max);
if( r < 17 ){
f_diag_sum = grid[i] *
grid[i+21] *
grid[i+42] *
grid[i+63];
max = std::max(f_diag_sum,max);
}
}
if( r < 17 ){
ud_sum = grid[i] *
grid[i+20] *
grid[i+40] *
grid[i+60];
max = std::max(ud_sum,max);
if( c > 3 ){
b_diag_sum = grid[i] *
grid[i+19] *
grid[i+38] *
grid[i+57];
max = std::max(b_diag_sum,max);
}
// std::cout << '[' << std::setw(3) << i
// << "](" << r << '/' << c
// << ")rl[" << rl_sum
// << "]ud[" << ud_sum
// << "]fd[" << f_diag_sum
// << "]bd[" << b_diag_sum
// << "]=" << max
// << std::endl;
}
}
return max;
}
#if ! defined UNITTEST_MODE
int main(int argc, char const *argv[])
{
std::cout << "Answer: " << largest_grid_product_brute() << std::endl;
}
#endif // #if ! defined UNITTEST_MODE
View on GitHub
O(n) time complexity

Solution Notes

Mathematical Background

This problem involves finding the maximum product of k adjacent numbers in a grid, where adjacency can be horizontal, vertical, or diagonal. The grid is 20x20, so we need to check all possible windows of 4 consecutive numbers in 4 different directions:

  • Horizontal: Left to right in each row
  • Vertical: Top to bottom in each column
  • Diagonal (): Top-left to bottom-right
  • Diagonal (/): Top-right to bottom-left

For each direction, we calculate products of every possible 4-element window that fits within the grid boundaries. The search space is finite but requires systematic coverage of all directions.

Algorithm Analysis

The implementations use nested loops to check all possible 4-element windows in each direction:

Brute force enumeration: For each starting position and each direction, compute the product of 4 adjacent elements.

Boundary checks: Ensure windows don’t go outside grid boundaries (17x20 for horizontal, 20x17 for vertical, 17x17 for both diagonals).

Early termination: Some implementations use boundary constraints to limit loop ranges.

Time complexity is O(4 x 20²) = O(1600), making it effectively constant time for a fixed-size grid.

Key Insights

  • The maximum product (70,600,674) comes from a diagonal sequence: 89 x 94 x 97 x 87
  • All four directions must be checked systematically
  • Boundary conditions determine how far each direction can be checked from any position
  • Zero values in the grid can significantly reduce products (though not in this case)
  • The grid contains both very large (99) and very small (00) numbers, creating varied products
  • Systematic enumeration works well when the search space is small and well-defined

Educational Value

This problem teaches essential programming concepts:

  • Multi-dimensional array manipulation and indexing
  • Systematic enumeration of possibilities
  • Boundary checking and constraint handling
  • Direction-based algorithms (similar to graph traversal)
  • The importance of checking all possible cases
  • Performance considerations for grid-based problems
  • Pattern recognition in structured data