September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -1,45 +1,64 @@
(function (lstTest) {
(function () {
'use strict';
function rangeString(xs) {
var iRightmost = xs.length - 1,
// rangeFormat :: [Int] -> String
var rangeFormat = function (xs) {
return splitBy(function (a, b) {
return b - a > 1;
}, xs)
.map(rangeString)
.join(',');
};
// Using foldr/reduceRight proves simpler here than foldl/reduce
// (the left end of the list is easier to reach than the tip of the tail)
lstSeries = xs.reduceRight(function (a, x, i, l) {
// rangeString :: [Int] -> String
var rangeString = function (xs) {
return xs.length > 2 ? [head(xs), last(xs)].map(show)
.join('-') : xs.join(',');
};
return i < iRightmost ? (
// GENERIC FUNCTIONS
// new series if rightward gap > 1
l[i + 1] - x > 1 ? (
[[x]].concat(a)
) : (
// Splitting not on a delimiter, but whenever the relationship between
// two consecutive items matches a supplied predicate function
// This value prepended to current series (if a
// series-breaker, or the start of the list, is at left)
(i === 0 || (x - l[i - 1]) > 1) ? (
[[x].concat(a[0])].concat(a.slice(1))
// splitBy :: (a -> a -> Bool) -> [a] -> [[a]]
var splitBy = function (f, xs) {
if (xs.length < 2) return [xs];
var h = head(xs),
lstParts = xs.slice(1)
.reduce(function (a, x) {
var acc = a[0],
active = a[1],
prev = a[2];
// or, if the series continues to the left,
// just an unmodified copy of the accumulator
) : a
)
) : [[x]];
return f(prev, x) ? (
[acc.concat([active]), [x], x]
) : [acc, active.concat(x), x];
}, [
[],
[h], h
]);
return lstParts[0].concat([lstParts[1]]);
};
}, []);
// head :: [a] -> a
var head = function (xs) {
return xs.length ? xs[0] : undefined;
};
return lstSeries.map(function (r) {
var lng = r.length,
d = lng > 1 ? r[1] - r[0] : 0;
// last :: [a] -> a
var last = function (xs) {
return xs.length ? xs.slice(-1)[0] : undefined;
};
return d ? r[0] + (d > 1 ? '-' : ',') + r[1] : r[0];
// show :: a -> String
var show = function (x) {
return JSON.stringify(x);
};
}).join(',');
}
return rangeString(lstTest);
})([0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
37, 38, 39]);
// TEST
return rangeFormat([0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32,
33, 35, 36, 37, 38, 39
]);
})();

View file

@ -1 +1,55 @@
"0-2,4,6-8,11,12,14-25,27-33,35-39"
(() => {
'use strict';
// rangeFormat :: [Int] -> String
const rangeFormat = xs =>
splitBy((a, b) => b - a > 1, xs)
.map(rangeString)
.join(',');
// rangeString :: [Int] -> String
const rangeString = xs =>
xs.length > 2 ? (
[head(xs), last(xs)].map(show)
.join('-')
) : xs.join(',')
// GENERIC FUNCTIONS
// Splitting not on a delimiter, but whenever the relationship between
// two consecutive items matches a supplied predicate function
// splitBy :: (a -> a -> Bool) -> [a] -> [[a]]
const splitBy = (f, xs) => {
if (xs.length < 2) return [xs];
const
h = head(xs),
lstParts = xs.slice(1)
.reduce(([acc, active, prev], x) =>
f(prev, x) ? (
[acc.concat([active]), [x], x]
) : [acc, active.concat(x), x], [
[],
[h],
h
]);
return lstParts[0].concat([lstParts[1]]);
};
// head :: [a] -> a
const head = xs => xs.length ? xs[0] : undefined;
// last :: [a] -> a
const last = xs => xs.length ? xs.slice(-1)[0] : undefined;
// show :: a -> String
const show = x => JSON.stringify(x);
// TEST
return rangeFormat([0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
37, 38, 39
]);
})();