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`);
}
}