Project Euler Problem 11: Largest product in a grid Here is my implementation to project Euler Problem 11. I did this problem a bit later, when I learned how to input from a txt file. The problem context can be seen here. I did add "\n" to the end of each line, after copying the numbers into a txt file, I'm not sure of any other way to do that. Any other improvements anyone can think of?

#include &lt;fstream&gt;
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;


//splitting stream into ints.
std::vector&lt;int&gt; split(std::string line){
    std::stringstream ss (line);
    std::vector&lt;int&gt; result;
    std::string num;
    while(std::getline(ss, num, ' '))
        result.push_back(std::stoi(num));
    return result;
}
//comparing all int's that are horizontally next to each other
unsigned long long Horizontal(int a, int b, std::vector&lt;std::vector&lt;int&gt;&gt; grid){
    if(b &lt; grid[a].size()-3){
        return (grid[a][b] * grid[a][b+1] * grid[a][b+2] * grid[a][b+3]);
    }
}
//comparing all int's that are vertically next to each other
unsigned long long Vertical(int a, int  b, std::vector&lt;std::vector&lt;int&gt;&gt; grid){
    if(a &lt; grid.size()-3){
        return (grid[a][b] * grid[a+1][b] * grid[a+2][b] * grid[a+3][b]);
    }
}
//all int's that are diagonally(forward) next to each other
unsigned long long ForDiag(int a, int b, std::vector&lt;std::vector&lt;int&gt;&gt;grid){
    if (a &lt; grid.size()-3 &amp;&amp; b &lt; grid[a].size()-3){
        return (grid[a][b] * grid[a+1][b+1] * grid[a+2][b+2] * grid[a+3][b+3]);
    }
}
//all int's that are diagonally(backward) next to each outher
unsigned long long BackDiag(int a, int b, std::vector&lt;std::vector&lt;int&gt;&gt;grid){
    b+=3; // b needs to be 3 larger for this function
    if(a &lt; grid.size()-3 &amp;&amp; b &lt; grid[a].size()){
        return (grid[a][b] * grid[a+1][b-1] * grid[a+2][b-2] * grid[a+3][b-3]);
    }
}

//Calls the calculation functions, and compares them for the largest.
unsigned long long Largest(std::vector&lt;std::vector&lt;int&gt;&gt; grid ){
    int gwidth = grid[0].size();
    int glength = grid.size();
    unsigned long long largest = 0;

    for(int a = 0; a &lt; gwidth; ++a){
        for(int b = 0; b &lt; glength; ++b){
            largest = std::max(largest,Horizontal(a,b,grid));
            largest = std::max(largest,Vertical(a,b,grid));
            largest = std::max(largest,ForDiag(a,b,grid));
            largest = std::max(largest,BackDiag(a,b,grid));

        }
    }
    return largest;
}




int main(){
    std::vector&lt;std::vector&lt;int&gt;&gt; grid;

    //opening file.
    std::ifstream nums;
    nums.open("grid.txt");
    std::string row;

    //Calling function, and pushing back into the vector
    while(std::getline(nums, row, '\n')){
        grid.push_back(split(row));
    }

    std::cout &lt;&lt; Largest(grid);

}
Your functions returning a unsigned long long are missing a return which leads to undefined behavior (more details on this question). You could throw an exception to handle this or you could just return 0.



Not a real issue and mostly a matter of personal preference but the way you check that you are not going out of the bounds of the array could be written in a more natural way.

To check that index b + 3 is in the array, I'd rather read b + 3 &lt; a.size() than b &lt; a.size() - 3.



Even more unusual is the pre-increment in the case of BackDiag() : you add 3 to b and then you consider b - 3.



Once your code re-written to take into account these comments, it looks like :

unsigned long long Horizontal(int a, int b, std::vector&lt;std::vector&lt;int&gt;&gt; grid){
    return (b + 3 &lt; grid[a].size()) ?
        (grid[a][b] * grid[a][b+1] * grid[a][b+2] * grid[a][b+3]) :
        0;
}
//comparing all int's that are vertically next to each other
unsigned long long Vertical(int a, int  b, std::vector&lt;std::vector&lt;int&gt;&gt; grid){
    return (a + 3 &lt; grid.size()) ?
        (grid[a][b] * grid[a+1][b] * grid[a+2][b] * grid[a+3][b]) :
        0;
}
unsigned long long ForDiag(int a, int b, std::vector&lt;std::vector&lt;int&gt;&gt;grid){
    return (a + 3 &lt; grid.size() &amp;&amp; b + 3 &lt; grid[a].size()) ?
        (grid[a][b] * grid[a+1][b+1] * grid[a+2][b+2] * grid[a+3][b+3]) :
        0;
}
unsigned long long BackDiag(int a, int b, std::vector&lt;std::vector&lt;int&gt;&gt;grid){
    return (a + 3 &lt; grid.size() &amp;&amp; b + 3 &lt; grid[a].size()) ?
        (grid[a][b+3] * grid[a+1][b+2] * grid[a+2][b+1] * grid[a+3][b]) :
        0;
}




Now, one thing to notice is that this good is basically always the same. You should try to write a generic function that you can reuse.

The signature would be something like :

unsigned long long computeProduct(int a, int b, int incrA, int incrB, std::vector&lt;std::vector&lt;int&gt;&gt;grid)