September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
164
Task/SEDOLs/JavaScript/sedols-2.js
Normal file
164
Task/SEDOLs/JavaScript/sedols-2.js
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
const main = () => {
|
||||
|
||||
// checkSumLR :: String -> Either String String
|
||||
const checkSumLR = s => {
|
||||
const
|
||||
tpl = partitionEithers(map(charValueLR, s));
|
||||
return 0 < tpl[0].length ? (
|
||||
Left(s + ' -> ' + unwords(tpl[0]))
|
||||
) : Right(rem(10 - rem(
|
||||
sum(zipWith(
|
||||
(a, b) => a * b,
|
||||
[1, 3, 1, 7, 3, 9],
|
||||
tpl[1]
|
||||
)), 10
|
||||
), 10).toString());
|
||||
};
|
||||
|
||||
// charValue :: Char -> Either String Int
|
||||
const charValueLR = c =>
|
||||
isAlpha(c) ? (
|
||||
isUpper(c) ? (
|
||||
elem(c, 'AEIOU') ? Left(
|
||||
'Unexpected vowel: ' + c
|
||||
) : Right(ord(c) - ord('A') + 10)
|
||||
) : Left('Unexpected lower case character: ' + c)
|
||||
) : isDigit(c) ? Right(
|
||||
parseInt(c, 10)
|
||||
) : Left('Unexpected character: ' + c);
|
||||
|
||||
// TESTS ------------------------------------------
|
||||
const [problems, checks] = Array.from(
|
||||
partitionEithers(map(s => bindLR(
|
||||
checkSumLR(s),
|
||||
c => Right(s + c)
|
||||
),
|
||||
[
|
||||
"710889", "B0YBKJ", "406566",
|
||||
"B0YBLH", "228276", "B0YBKL",
|
||||
"557910", "B0YBKR", "585284",
|
||||
"B0YBKT", "B00030"
|
||||
]
|
||||
))
|
||||
);
|
||||
return unlines(
|
||||
0 < problems.length ? (
|
||||
problems
|
||||
) : checks
|
||||
);
|
||||
};
|
||||
|
||||
// GENERIC FUNCTIONS ----------------------------
|
||||
|
||||
// Left :: a -> Either a b
|
||||
const Left = x => ({
|
||||
type: 'Either',
|
||||
Left: x
|
||||
});
|
||||
|
||||
// Right :: b -> Either a b
|
||||
const Right = x => ({
|
||||
type: 'Either',
|
||||
Right: x
|
||||
});
|
||||
|
||||
// Tuple (,) :: a -> b -> (a, b)
|
||||
const Tuple = (a, b) => ({
|
||||
type: 'Tuple',
|
||||
'0': a,
|
||||
'1': b,
|
||||
length: 2
|
||||
});
|
||||
|
||||
// bindLR (>>=) :: Either a -> (a -> Either b) -> Either b
|
||||
const bindLR = (m, mf) =>
|
||||
undefined !== m.Left ? (
|
||||
m
|
||||
) : mf(m.Right);
|
||||
|
||||
// elem :: Eq a => a -> [a] -> Bool
|
||||
const elem = (x, xs) => xs.includes(x);
|
||||
|
||||
// isAlpha :: Char -> Bool
|
||||
const isAlpha = c =>
|
||||
/[A-Za-z\u00C0-\u00FF]/.test(c);
|
||||
|
||||
// isDigit :: Char -> Bool
|
||||
const isDigit = c => {
|
||||
const n = ord(c);
|
||||
return 48 <= n && 57 >= n;
|
||||
};
|
||||
|
||||
// isUpper :: Char -> Bool
|
||||
const isUpper = c =>
|
||||
/[A-Z]/.test(c);
|
||||
|
||||
// Returns Infinity over objects without finite length.
|
||||
// This enables zip and zipWith to choose the shorter
|
||||
// argument when one is non-finite, like cycle, repeat etc
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs =>
|
||||
(Array.isArray(xs) || 'string' === typeof xs) ? (
|
||||
xs.length
|
||||
) : Infinity;
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = (f, xs) =>
|
||||
(Array.isArray(xs) ? (
|
||||
xs
|
||||
) : xs.split('')).map(f);
|
||||
|
||||
// ord :: Char -> Int
|
||||
const ord = c => c.codePointAt(0);
|
||||
|
||||
// partitionEithers :: [Either a b] -> ([a],[b])
|
||||
const partitionEithers = xs =>
|
||||
xs.reduce(
|
||||
(a, x) => undefined !== x.Left ? (
|
||||
Tuple(a[0].concat(x.Left), a[1])
|
||||
) : Tuple(a[0], a[1].concat(x.Right)),
|
||||
Tuple([], [])
|
||||
);
|
||||
|
||||
// rem :: Int -> Int -> Int
|
||||
const rem = (n, m) => n % m;
|
||||
|
||||
// sum :: [Num] -> Num
|
||||
const sum = xs => xs.reduce((a, x) => a + x, 0);
|
||||
|
||||
// take :: Int -> [a] -> [a]
|
||||
// take :: Int -> String -> String
|
||||
const take = (n, xs) =>
|
||||
'GeneratorFunction' !== xs.constructor.constructor.name ? (
|
||||
xs.slice(0, n)
|
||||
) : [].concat.apply([], Array.from({
|
||||
length: n
|
||||
}, () => {
|
||||
const x = xs.next();
|
||||
return x.done ? [] : [x.value];
|
||||
}));
|
||||
|
||||
// unlines :: [String] -> String
|
||||
const unlines = xs => xs.join('\n');
|
||||
|
||||
// unwords :: [String] -> String
|
||||
const unwords = xs => xs.join(' ');
|
||||
|
||||
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
|
||||
const zipWith = (f, xs, ys) => {
|
||||
const
|
||||
lng = Math.min(length(xs), length(ys)),
|
||||
as = take(lng, xs),
|
||||
bs = take(lng, ys);
|
||||
return Array.from({
|
||||
length: lng
|
||||
}, (_, i) => f(as[i], bs[i], i));
|
||||
};
|
||||
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue