pootzko
12/21/2016 - 2:43 PM

Translation for: https://gist.github.com/gameguy43/c4bb482652d62e31d1bee9d09e331999

public int highestProductOf3(int[] arrayOfInts)
{
    if (arrayOfInts.Length < 3)
    {
        throw new ArgumentException("Less than 3 items!");
    }

    // Firstly we will separate specific array elements
    // into their own variables for better clarity and maintainability.
    // Working directly with specific array elements is generally
    // considered a bad practice which leads to errors because
    // it's hard to manage and refactor.
    int first = arrayOfInts[0];
    int second = arrayOfInts[1];
    int third = arrayOfInts[2];

    // We're going to start at the 3rd item (at index 2)
    // so pre-populate highests and lowests based on the first 2 items.
    // We could also start these as null and check below if they're set
    // but this is arguably cleaner.
    int highest = Math.Max(first, second);
    int lowest = Math.Min(first, second);

    int highestProductOf2 = first * second;
    int lowestProductOf2 = first * second;

    // Except this one - we pre-populate it for the first /3/ items.
    // This means in our first pass it'll check against itself, which is fine.
    int highestProductOf3 = first * second * third;

    // Walk through items, starting at index 2.
    for (var i = 2; i < arrayOfInts.Length; i++)
    {
        int current = arrayOfInts[i];

        // Do we have a new highest product of 3?
        // It's either the current highest,
        // or the current times the highest product of two
        // or the current times the lowest product of two.
        highestProductOf3 = new int[] {
            highestProductOf3,
            current * highestProductOf2,
            current * lowestProductOf2
        }.Max();

        // Do we have a new highest product of two?
        highestProductOf2 = new int[] {
            highestProductOf2,
            current * highest,
            current * lowest
        }.Max();

        // Do we have a new lowest product of two?
        lowestProductOf2 = new int[] {
            lowestProductOf2,
            current * highest,
            current * lowest
        }.Max();

        // Do we have a new highest?
        highest = Math.Max(highest, current);

        // Do we have a new lowest?
        lowest = Math.Min(lowest, current);
    }

    return highestProductOf3;
}