YAPC::EU 2018 Glasgow Update!
This commit is contained in:
parent
22f33d4004
commit
4e2d22a71d
1170 changed files with 15042 additions and 3047 deletions
|
|
@ -1,67 +1,122 @@
|
|||
(n => {
|
||||
(() => {
|
||||
'use strict';
|
||||
|
||||
// spiral :: the first row plus a smaller spiral rotated 90 degrees clockwise
|
||||
// spiral :: Int -> Int -> Int -> [[Int]]
|
||||
function spiral(lngRows, lngCols, nStart) {
|
||||
return lngRows ? [range(nStart, (nStart + lngCols) - 1)]
|
||||
.concat(
|
||||
transpose(
|
||||
spiral(lngCols, lngRows - 1, nStart + lngCols)
|
||||
// main :: () -> String
|
||||
const main = () =>
|
||||
unlines(
|
||||
map(unwords, spiral(5))
|
||||
);
|
||||
|
||||
// spiral :: Int -> [[Int]]
|
||||
const spiral = n => {
|
||||
const go = (rows, cols, start) =>
|
||||
0 < rows ? [
|
||||
enumFromTo(start, start + pred(cols)),
|
||||
...map(
|
||||
reverse,
|
||||
transpose(
|
||||
go(
|
||||
cols,
|
||||
pred(rows),
|
||||
start + cols
|
||||
)
|
||||
)
|
||||
)
|
||||
.map(reverse)
|
||||
) : [[]];
|
||||
}
|
||||
] : [
|
||||
[]
|
||||
];
|
||||
return go(n, n, 0);
|
||||
};
|
||||
|
||||
// transpose :: [[a]] -> [[a]]
|
||||
function transpose(xs) {
|
||||
return xs[0]
|
||||
.map((_, iCol) => xs
|
||||
.map((row) => row[iCol]));
|
||||
}
|
||||
// GENERIC FUNCTIONS ----------------------------------
|
||||
|
||||
// comparing :: (a -> b) -> (a -> a -> Ordering)
|
||||
const comparing = f =>
|
||||
(x, y) => {
|
||||
const
|
||||
a = f(x),
|
||||
b = f(y);
|
||||
return a < b ? -1 : (a > b ? 1 : 0);
|
||||
};
|
||||
|
||||
// concatMap :: (a -> [b]) -> [a] -> [b]
|
||||
const concatMap = (f, xs) =>
|
||||
0 < xs.length ? (() => {
|
||||
const unit = 'string' !== typeof xs ? (
|
||||
[]
|
||||
) : '';
|
||||
return unit.concat.apply(unit, xs.map(f))
|
||||
})() : [];
|
||||
|
||||
// enumFromTo :: Int -> Int -> [Int]
|
||||
const enumFromTo = (m, n) =>
|
||||
m <= n ? iterateUntil(
|
||||
x => n <= x,
|
||||
x => 1 + x,
|
||||
m
|
||||
) : [];
|
||||
|
||||
// iterateUntil :: (a -> Bool) -> (a -> a) -> a -> [a]
|
||||
const iterateUntil = (p, f, x) => {
|
||||
const vs = [x];
|
||||
let h = x;
|
||||
while (!p(h))(h = f(h), vs.push(h));
|
||||
return vs;
|
||||
};
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs => xs.length;
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = (f, xs) => xs.map(f);
|
||||
|
||||
// Ordering: (LT|EQ|GT):
|
||||
// GT: 1 (or other positive n)
|
||||
// EQ: 0
|
||||
// LT: -1 (or other negative n)
|
||||
|
||||
// maximumBy :: (a -> a -> Ordering) -> [a] -> a
|
||||
const maximumBy = (f, xs) =>
|
||||
0 < xs.length ? (
|
||||
xs.slice(1)
|
||||
.reduce((a, x) => 0 < f(x, a) ? x : a, xs[0])
|
||||
) : undefined;
|
||||
|
||||
|
||||
// pred :: Enum a => a -> a
|
||||
const pred = x => x - 1;
|
||||
|
||||
// reverse :: [a] -> [a]
|
||||
function reverse(xs) {
|
||||
return xs.slice(0)
|
||||
.reverse();
|
||||
}
|
||||
const reverse = xs =>
|
||||
'string' !== typeof xs ? (
|
||||
xs.slice(0).reverse()
|
||||
) : xs.split('').reverse().join('');
|
||||
|
||||
// range(intFrom, intTo, optional intStep)
|
||||
// Int -> Int -> Maybe Int -> [Int]
|
||||
function range(m, n, step) {
|
||||
let d = (step || 1) * (n >= m ? 1 : -1);
|
||||
// replicate :: Int -> a -> [a]
|
||||
const replicate = (n, x) =>
|
||||
Array.from({
|
||||
length: n
|
||||
}, () => x);
|
||||
|
||||
return Array.from({
|
||||
length: Math.floor((n - m) / d) + 1
|
||||
}, (_, i) => m + (i * d));
|
||||
}
|
||||
// transpose :: [[a]] -> [[a]]
|
||||
const transpose = tbl => {
|
||||
const
|
||||
gaps = replicate(
|
||||
length(maximumBy(comparing(length), tbl)), []
|
||||
),
|
||||
rows = map(xs => xs.concat(gaps.slice(xs.length)), tbl);
|
||||
return map(
|
||||
(_, col) => concatMap(row => [row[col]], rows),
|
||||
rows[0]
|
||||
);
|
||||
};
|
||||
|
||||
// unlines :: [String] -> String
|
||||
const unlines = xs => xs.join('\n');
|
||||
|
||||
// unwords :: [String] -> String
|
||||
const unwords = xs => xs.join(' ');
|
||||
|
||||
// TESTING
|
||||
|
||||
// replicate :: Int -> String -> String
|
||||
function replicate(n, a) {
|
||||
var v = [a],
|
||||
o = '';
|
||||
|
||||
if (n < 1) return o;
|
||||
while (n > 1) {
|
||||
if (n & 1) o = o + v;
|
||||
n >>= 1;
|
||||
v = v + v;
|
||||
}
|
||||
return o + v;
|
||||
}
|
||||
|
||||
|
||||
return spiral(n, n, 0)
|
||||
.map(
|
||||
xs => xs.map(x => {
|
||||
let s = `${x}`;
|
||||
return replicate(4 - s.length, ' ') + s;
|
||||
})
|
||||
.join('')
|
||||
)
|
||||
.join('\n');
|
||||
|
||||
})(5);
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue