cielux
10/24/2018 - 12:50 AM

Max Profit

Write an efficient function that takes stockPrices and returns the best profit I could have made from one purchase and one sale of one share of Apple stock yesterday.

For example:

const stockPrices = [10, 7, 5, 8, 11, 9];

getMaxProfit(stockPrices); // Returns 6 (buying for $5 and selling for $11)

function getMaxProfit(stockPrices) {
  if (stockPrices.length < 2) {
    throw new Error("Getting a profit requires at least 2 prices");
  }
  // Calculate the max profit
  let max = stockPrices[1] - stockPrices[0];
  let minPrice = stockPrices[0];
  for (let i = 1; i < stockPrices.length; i++) {
    const currentPrice = stockPrices[i];
    const currentProfit = stockPrices[i] - minPrice;
    max = Math.max(max, currentProfit);
    minPrice = Math.min(minPrice, currentPrice);
  }

  return max;
}

// Tests

let desc = 'price goes up then down';
let actual = getMaxProfit([1, 5, 3, 2]);
let expected = 4;
assertEqual(actual, expected, desc);

desc = 'price goes down then up';
actual = getMaxProfit([7, 2, 8, 9]);
expected = 7;
assertEqual(actual, expected, desc);

desc = 'price goes up all day';
actual = getMaxProfit([1, 6, 7, 9]);
expected = 8;
assertEqual(actual, expected, desc);

desc = 'price goes down all day';
actual = getMaxProfit([9, 7, 4, 1]);
expected = -2;
assertEqual(actual, expected, desc);

desc = 'price stays the same all day';
actual = getMaxProfit([1, 1, 1, 1]);
expected = 0;
assertEqual(actual, expected, desc);

desc = 'error with empty prices';
const emptyArray = () => (getMaxProfit([]));
assertThrowsError(emptyArray, desc);

desc = 'error with one price';
const onePrice = () => (getMaxProfit([1]));
assertThrowsError(onePrice, desc);

function assertEqual(a, b, desc) {
  if (a === b) {
    console.log(`${desc} ... PASS`);
  } else {
    console.log(`${desc} ... FAIL: ${a} != ${b}`);
  }
}

function assertThrowsError(func, desc) {
  try {
    func();
    console.log(`${desc} ... FAIL`);
  } catch (e) {
    console.log(`${desc} ... PASS`);
  }
}