Pass Triangle challenge
int firstCandidate = 0;
int secondCandidate = 0;
int max = 0;



None of these need as wide a scope as they have. In particular, firstCandidate and secondCandidate are only used inside the nested loop, and are initialised every time they're used. They should be pushed in (if not eliminated...)




        firstCandidate = 0;
        secondCandidate = 0;

        if (j - 1 &gt;= 0)
        {
            firstCandidate = numbers[i][j] + numbers[i - 1][j - 1];
        }

        if (j &lt; numbers[i - 1].Length)
        {
            secondCandidate = numbers[i][j] + numbers[i - 1][j];
        }

        numbers[i][j] = firstCandidate &gt; secondCandidate ? firstCandidate : secondCandidate;



This can be simplified slightly with a simple algebraic rearrangement to factor out the numbers[i][j] from the two candidates, since we know that at least one candidate must exist. (Note that by using int.MinValue we also fix something which could be argued to be a bug, unless the spec clearly states that the triangle will never contain negative numbers).

I agree with TarkaDaal that Math.Max is slightly more readable. And I would also find it more readable with ternary operators. Bearing in mind the scope change mentioned above, I get:


        int firstCandidate = j &gt; 0 ? numbers[i - 1][j - 1] : int.MinValue;
        int secondCandidate = j &lt; numbers[i - 1].Length ? numbers[i - 1][j] : int.MinValue;
        numbers[i][j] += Math.Max(firstCandidate, secondCandidate);





To find the maximum of an array, Linq is more readable and you won't notice any speed difference.



Summarising, I would rewrite the d.p. method as

static int GetMaxSum(int[][] numbers)
{
    for(int i = 1; i &lt; numbers.Length; i++)
    {
        for(int j = 0; j &lt; numbers[i].Length; j++)
        {
            int firstCandidate = j &gt; 0 ? numbers[i - 1][j - 1] : int.MinValue;
            int secondCandidate = j &lt; numbers[i - 1].Length ? numbers[i - 1][j] : int.MinValue;
            numbers[i][j] += Math.Max(firstCandidate, secondCandidate);
        }
    }

    return numbers[numbers.Length - 1].Max();
}