Connect graph from 2D array I just completed Project Euler problem 18 which is a dynamic programming question through a graph of a triangle of numbers. The goal is to find the path from top to bottom of the triangle that has the largest sum.

In the example below the path is 3->7->4->9.

Say the numbers in the triangle are:

   3
  7 4
 2 4 6
8 5 9 3


I built a jagged array that looks like:

int[][] triangleNumbers = new int[4][]
{
    new int[] {3},
    new int[] {7, 4},
    new int[] {2, 4, 6},
    new int[] {8, 5, 9, 3},
};


Then I made a custom object TriangleNode and converted the numbers into TriangleNodes. Then I went through and connected the lower left and lower right nodes to their parent so I could graph traverse them easily.

//build triangle graph    
TriangleNode[][] triangleGraph = new TriangleNode[triangleNumbers.Length][];

for(int row = 0; row &lt; triangleNumbers.Length; row++)
{
    triangleGraph[row] = new TriangleNode[triangleNumbers[row].Length];
    for(int col = 0; col &lt; triangleNumbers[row].Length; col++)
    {
            //create the Node and save the value
        triangleGraph[row][col] = new TriangleNode(triangleNumbers[row][col]);
    }
}

//connect triangle graph
for(int row = 0; row &lt; triangleGraph.Length; row++)
{
    for(int col = 0; col &lt; triangleGraph[row].Length; col++)
    {
        if(row + 1 == triangleGraph.Length)
        {
                    //bool for easy graph traversing to check if I'm at the bottom row
            triangleGraph[row][col].IsEnd = true;
        }
        else
        {
                    //hook up the Left/Right pointers
            triangleGraph[row][col].Left = triangleGraph[row + 1][col];
            triangleGraph[row][col].Right = triangleGraph[row + 1][col + 1];
        }
    }
}


Obviously this is a ton of code just to build the graph.

Is there an easier way to build this graph? The requirements are that each TriangleNode holds its value and Left/Right pointers to the Nodes in the row directly below. I was thinking there might be some voodoo magic via LINQ to turn the triangleNumbers[][] into the triangleGraph[][], then some more voodoo to hook up the Left/Right pointers.
I don't know about "LINQ voodoo", but you could do this in one pass if you reversed the order you're processing the rows. Something like this:

        //build triangle graph    
        var triangleGraph = new TriangleNode[triangleNumbers.Length][];

        for (int row = triangleNumbers.Length - 1; row &gt;= 0; row--)
        {
            triangleGraph[row] = new TriangleNode[triangleNumbers[row].Length];
            for (int col = 0; col &lt; triangleGraph[row].Length; col++)
            {
                //create the Node and save the value
                bool isEnd = row == triangleNumbers.Length - 1;
                triangleGraph[row][col] = new TriangleNode(triangleNumbers[row][col])
                                              {
                                                  IsEnd = isEnd,
                                                  Left = isEnd ? null : triangleGraph[row + 1][col],
                                                  Right = isEnd ? null : triangleGraph[row + 1][col + 1]
                                              };
            }
        }


I'll admit, I didn't test