Skip to content

Instantly share code, notes, and snippets.

@tekerson
Created January 10, 2017 14:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tekerson/137d1aeba598c8c1bc891c8b26764cd7 to your computer and use it in GitHub Desktop.
Save tekerson/137d1aeba598c8c1bc891c8b26764cd7 to your computer and use it in GitHub Desktop.
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