Problem:  What is the greatest product of four adjacent numbers in any direction (up,  down,  left, right,  or diagonally) in the 20×20 grid?

Commentary:  Well, it’s been a while since I’ve posted anything.  Once again, the semester and research get the better of me. 

As for this problem, like several before it I will be passing off some things to the shell for convenience.  This can all be done with R, but my feeling is that the right tool should be used for the job.  For text processing of any kind, R is not my favorite tool; in my book, for simple jobs, sed is king.  And so we use sed.

So the trick is to get that big matrix from Project Euler stored as a matrix in R.  Once that’s done, the problem is fairly simple. We just loop over the indices and at each step, find the biggest vertical, horizontal, diagonal, and off-diagonal product.  The end result is that we know the largest possible products in each way, and set our answer to the maximum of the four such products.

This solution is actually fairly overzealous, and could be optimized a great deal (and you would have to if the matrix were not so small).  However, there are conceivable benefits to this method, depending on what you plan to do with the code in the future.  For this application, the speed is more then sufficient.

R Code:

ElapsedTime <- system.time({
##########################
x <- system("echo '
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
' | sed -e 's/ /,/g' -e '/^$/d' -e 's/$/,/g' | tr -d '\\n' | sed 's/.$//'", intern=TRUE)
 
y <- t(matrix(scan(textConnection(x), sep=","), 20, 20))
closeAllConnections()
 
vert <- 1;horiz <- 1;diag1 <- 1;diag2 <- 1
vert.test <- 1;horiz.test <- 1;diag1.test <- 1;diag2.test <- 1
for (i in 1:17){
    for (j in 1:17){
        # Vertical
        vert.test <- prod(y[i, j], y[i, j+1], y[i, j+2], y[i, j+3])
        if (vert.test > vert){
            vert <- vert.test
        }
        # Horizontal
        horiz.test <- prod(y[i, j], y[i+1, j], y[i+2, j], y[i+3, j])
        if (horiz.test > horiz){
            horiz <- horiz.test
        }
        # Diagonal \
        diag1.test <- prod(y[i, j], y[i+1, j+1], y[i+2, j+2], y[i+3, j+3])
        if (diag1.test > diag1){
            diag1 <- diag1.test
        }
        # Diagonal /
        k <- i+3
        diag2.test <- prod(y[k, j], y[k-1, j+1], y[k-2, j+2], y[k-3, j+3])
        if (diag2.test > diag2){
            diag2 <- diag2.test
        }
    }
}
 
answer <- max(vert, horiz, diag1, diag2)
 
##########################
})[3]
ElapsedMins <- floor(ElapsedTime/60)
ElapsedSecs <- (ElapsedTime-ElapsedMins*60)
cat(sprintf("\nThe answer is:  %d\nTotal elapsed time:  %d minutes and %f seconds\n",
    answer, ElapsedMins, ElapsedSecs))

Output:

The answer is:  70600674
Total elapsed time:  0 minutes and 0.010000 seconds