findMax Assertion Playground

node v8.17.0
version: 1.0.0
endpointsharetweet
// playing with algorithms series // // given a list of items (nested arrays may occur) // find the largest item and return it. (Items may be strings) // // signature: fn(num1, num2, arr1, ...) // // example: // // fn(1, 2, [5, 9], [3, [12, 7]]) should return 12 // used for functional implementations function flatten(...args) { return args.reduce( /* acc is short for "accumulator" here */ (acc, item) => [ ...acc, // spread the accumulator out /* we'll spread the following out into multiple arguments */ ...(Array.isArray(item) ? /* If the item is an array... * we need to use recursion, so spread the array out * and call ourselves again. */ flatten(...item) : /* Otherwise, return array containing a single item * so that spread can still work */ [item]), ], /* the starting result for Array#reduce is an array with no items. * This will be returned if there is nothing to flatten, but also * serves as the initial value to `acc` above (the accumulator) */ [] ); } const implementations = { imperative: function findMax(...args) { let largest; const stack = args; while (stack.length > 0) { const candidate = stack.pop(); if (Array.isArray(candidate)) { stack.push(...candidate); } else if (largest === undefined || candidate > largest) { largest = candidate; } } return largest; }, recursive: function findMax(...args) { let largest; for (let candidate of args) { if (Array.isArray(candidate)) { candidate = findMax(...candidate); } if (largest === undefined || candidate > largest) { largest = candidate; } } return largest; }, functional: function findMax(...args) { const largest = (a, b) => (([a = b, b = a] = [a, b]), a > b ? a : b); return flatten(args).reduce(largest, undefined); }, functionalWithSort: function findMax(...args) { const ascendingOrder = (a, b) => (a < b ? -1 : a > b ? 1 : 0); return flatten(args) .sort(ascendingOrder) .pop(); }, // cheating, though, since it doesn't handle strings correctly usingMax: function findMax(...args) { return Math.max(...flatten(args)); }, }; function assert({ fn, expectation } = {}) { try { let result = fn(); if (!(result === expectation)) { console.error(`[FAIL] Expected ${expectation}; got ${result}`); } else { console.log(`[PASS] Passed; got ${result}`); } } catch (err) { console.error(`[FAIL] ${err.message}; expected ${expectation}`); } } Object.entries(implementations).forEach(([name, fn]) => { console.log(`Testing ${name}...`); assert({ fn: () => fn(1, 2, 3, 4, 5), expectation: 5 }); assert({ fn: () => fn(1, 3, 5, 2, 1), expectation: 5 }); assert({ fn: () => fn(), expectation: undefined }); assert({ fn: () => fn(1), expectation: 1 }); assert({ fn: () => fn([1, 2, 9]), expectation: 9 }); assert({ fn: () => fn(-40, -90, -114), expectation: -40 }); assert({ fn: () => fn([1, 9, [459, 932, [19], [20, 21]], 1005, [32, 1543, 900]]), expectation: 1543, }); assert({ fn: () => fn(0), expectation: 0 }); assert({ fn: () => fn(-4, [-90, 0], -3), expectation: 0 }); assert({ fn: () => fn(1.25, 9.3932, Math.PI, Number.MAX_SAFE_INTEGER), expectation: Number.MAX_SAFE_INTEGER, }); assert({ fn: () => fn(1, 10, [5, 9], [12, [900], [34, 56, 7600]], 34), expectation: 7600, }); assert({ fn: () => fn('hello', 'world', 'strings', ['are', 'fun']), expectation: 'world', }); });
Loading…

no comments

    sign in to comment