Created
January 10, 2017 14:45
-
-
Save tekerson/137d1aeba598c8c1bc891c8b26764cd7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const posLens = R.lensProp('positives') | |
const negLens = R.lensProp('negatives') | |
const positives = R.view(posLens) | |
const negatives = R.view(negLens) | |
const incrementPositiveCount = R.over(posLens, R.inc) | |
const incrementNegativeCount = R.over(negLens, R.inc) | |
const seenBoth = c => R.allPass([ | |
R.compose(R.gt(R.__, 0), positives), | |
R.compose(R.gt(R.__, 0), negatives), | |
])(c) | |
const updateCounts = (counts, num) => R.cond([ | |
[R.equals(1), R.always(incrementPositiveCount)], | |
[R.equals(-1), R.always(incrementNegativeCount)], | |
[R.equals(0), R.always(R.identity)], | |
[R.T, R.always(() => { throw new Error(`ERR: Unexpected value (${num})`) })] | |
])(num)(counts) | |
const onlyPositives = R.allPass([ | |
R.compose(R.gt(R.__, 0), positives), | |
R.compose(R.equals(0), negatives), | |
]) | |
const onlyNegatives = R.allPass([ | |
R.compose(R.gt(R.__, 0), negatives), | |
R.compose(R.equals(0), positives), | |
]) | |
const classifyResults = length => R.cond([ | |
[R.propEq('positives', length), R.always(Infinity)], | |
[R.propEq('negatives', length), R.always(-Infinity)], | |
[onlyPositives, positives], | |
[onlyNegatives, R.compose(R.negate, negatives)], | |
[R.T, R.always(0)] | |
]) | |
const produceSummary = R.reduce( | |
R.compose(R.when(seenBoth, R.reduced), updateCounts), | |
{ negatives: 0, positives: 0}) | |
const example = arr => R.compose( | |
classifyResults(arr.length), | |
produceSummary | |
)(arr) | |
// Tests | |
const assert = (expr, to, description) => { const r = expr(); console.log(`${R.equals(r, to)} : ${description}`); }; | |
console.log('== TESTS ==') | |
assert(() => example([0,0,0,0]), 0, 'if all elements of an array are 0, return 0.') | |
assert(() => example([1,1,1,1]), Infinity, 'if all elements of an array are 1, return Infinity.') | |
assert(() => example([-1,-1,-1,-1]), -Infinity, 'if all elements of an array are -1, return -Infinity.') | |
assert(() => example([1,0,1,1]), 3, 'if all elements of an array are either 0 or 1, return number of 1s.') | |
assert(() => example([-1,0,-1,-1]), -3, 'if all elements of an array are either 0 or -1, return -1 * number of 1s.') | |
assert(() => example([1,0,-1]), 0, 'if all the above fail, return 0.') | |
assert(() => example([1,-1,undefined]), 0, 'short circuits when an incompatible state is reached.') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment