Family Day update

This commit is contained in:
Ingy döt Net 2020-02-17 23:21:07 -08:00
parent aac6731f2c
commit 9ad63ea473
2442 changed files with 39761 additions and 8255 deletions

View file

@ -1,60 +1,56 @@
(() => {
'use strict';
console.log("Supplied examples");
var tests = ["", "[]", "][", "[][]", "][][", "[[][]]", "[]][[]"];
for (var test of tests)
{
console.log("The string '" + test + "' is " +
(isStringBalanced(test) ? "" : "not ") + "OK.");
}
console.log();
console.log("Random generated examples");
for (var example = 1; example <= 10; example++)
{
var test = generate(Math.floor(Math.random() * 10) + 1);
console.log("The string '" + test + "' is " +
(isStringBalanced(test) ? "" : "not ") + "OK.");
}
// Int -> String
let randomBrackets = n => range(1, n)
.map(() => Math.random() < 0.5 ? '[' : ']')
.join('');
function isStringBalanced(str)
{
var paired = 0;
for (var i = 0; i < str.length && paired >= 0; i++)
{
var c = str[i];
if (c == '[')
paired++;
else if (c == ']')
paired--;
}
return (paired == 0);
}
// imbalance :: String -> Integer
let imbalance = strBrackets => {
// iDepth: initial nesting depth (0 = closed)
// iIndex: starting character position
// errorIndex :: [Char] -> Int -> Int -> Int
let errorIndex = (xs, iDepth, iIndex) => {
if (xs.length > 0) {
let tail = xs.slice(1),
iNext = iDepth + (xs[0] === '[' ? 1 : -1);
if (iNext < 0) return iIndex; // unmatched closing bracket
else return tail.length ? errorIndex(
tail, iNext, iIndex + 1
) : iNext === 0 ? -1 : iIndex; // balanced ? problem index ?
} else return iDepth === 0 ? -1 : iIndex;
};
return errorIndex(strBrackets.split(''), 0, 0);
};
// GENERIC FUNCTION
// range :: Int -> Int -> [Int]
let range = (m, n) =>
Array.from({
length: Math.floor(n - m) + 1
}, (_, i) => m + i);
// TESTING AND FORMATTING OUTPUT
let lngPairs = 6,
strPad = Array(lngPairs * 2 + 4)
.join(' ');
return range(0, lngPairs)
.map(n => {
let w = n * 2,
s = randomBrackets(w),
i = imbalance(s),
blnOK = i === -1;
return "'" + s + "'" + strPad.slice(w + 2) +
(blnOK ? 'OK' : 'problem') +
(blnOK ? '' : '\n' + Array(i + 2)
.join(' ') + '^');
})
.join('\n');
})();
function generate(n)
{
var opensCount = 0, closesCount = 0;
// Choose at random until n of one type generated
var generated = "";
while (opensCount < n && closesCount < n)
{
switch (Math.floor(Math.random() * 2) + 1)
{
case 1:
opensCount++;
generated += "[";
break;
case 2:
closesCount++;
generated += "]";
break;
default:
break;
}
}
// Now pad with the remaining other brackets
generated +=
opensCount == n ? "]".repeat(n - closesCount) : "[".repeat(n - opensCount);
return generated;
}

View file

@ -0,0 +1,95 @@
(() => {
'use strict';
// findUnbalancedBracket :: String -> String -> Maybe Int
const findUnbalancedBracket = strBrackets => strHaystack => {
const
openBracket = strBrackets[0],
closeBracket = strBrackets[1];
const go = (xs, iDepth, iCharPosn) =>
// iDepth: initial nesting depth (0 = closed)
// iCharPosn: starting character position
0 < xs.length ? (() => {
const
h = xs[0],
tail = xs.slice(1),
iNext = iDepth + (
strBrackets.includes(h) ? (
openBracket === h ? (
1
) : -1
) : 0
);
return 0 > iNext ? (
Just(iCharPosn) // Unmatched closing bracket.
) : 0 < tail.length ? go(
tail, iNext, 1 + iCharPosn
) : 0 !== iNext ? (
Just(iCharPosn)
) : Nothing();
})() : 0 !== iDepth ? (
Just(iCharPosn)
) : Nothing();
return go(strHaystack.split(''), 0, 0);
};
// TEST -----------------------------------------------
// main :: IO ()
const main = () => {
const
intPairs = 6,
strPad = ' '.repeat(4 + (2 * intPairs));
console.log(
enumFromTo(0)(intPairs)
.map(pairCount => {
const
stringLength = 2 * pairCount,
strSample = randomBrackets(stringLength);
return "'" + strSample + "'" +
strPad.slice(2 + stringLength) + maybe('OK')(
iUnMatched => 'problem\n' +
' '.repeat(1 + iUnMatched) + '^'
)(
findUnbalancedBracket('[]')(strSample)
);
}).join('\n')
);
};
// Int -> String
const randomBrackets = n =>
enumFromTo(1)(n)
.map(() => Math.random() < 0.5 ? (
'['
) : ']').join('');
// GENERIC --------------------------------------------
// Just :: a -> Maybe a
const Just = x => ({
type: 'Maybe',
Nothing: false,
Just: x
});
// Nothing :: Maybe a
const Nothing = () => ({
type: 'Maybe',
Nothing: true,
});
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m => n =>
Array.from({
length: 1 + n - m
}, (_, i) => m + i);
// maybe :: b -> (a -> b) -> Maybe a -> b
const maybe = v => f => m =>
m.Nothing ? v : f(m.Just);
// ---
return main();
})();