Family Day update
This commit is contained in:
parent
aac6731f2c
commit
9ad63ea473
2442 changed files with 39761 additions and 8255 deletions
|
|
@ -8,22 +8,24 @@ import VShuffle
|
|||
-- after, the i'th bracket. We assume the string contains only brackets.
|
||||
isBalanced :: String -> Maybe Int
|
||||
isBalanced = bal (-1) 0
|
||||
where bal :: Int -> Int -> String -> Maybe Int
|
||||
bal _ 0 [] = Nothing
|
||||
bal i _ [] = Just i
|
||||
bal i (-1) _ = Just i
|
||||
bal i n ('[':bs) = bal (i+1) (n+1) bs
|
||||
bal i n (']':bs) = bal (i+1) (n-1) bs
|
||||
where
|
||||
bal :: Int -> Int -> String -> Maybe Int
|
||||
bal _ 0 [] = Nothing
|
||||
bal i _ [] = Just i
|
||||
bal i (-1) _ = Just i
|
||||
bal i n ('[':bs) = bal (i + 1) (n + 1) bs
|
||||
bal i n (']':bs) = bal (i + 1) (n - 1) bs
|
||||
|
||||
-- Print a string, indicating whether it contains balanced brackets. If not,
|
||||
-- indicate the bracket at which the imbalance was found.
|
||||
check :: String -> IO ()
|
||||
check s = maybe (good s) (bad s) (isBalanced s)
|
||||
where good s = printf "Good \"%s\"\n" s
|
||||
bad s n = printf "Bad \"%s\"\n%*s^\n" s (n+6) " "
|
||||
where
|
||||
good = printf "Good \"%s\"\n"
|
||||
bad s n = printf "Bad \"%s\"\n%*s^\n" s (n + 6) " "
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
let bs = cycle "[]"
|
||||
rs <- replicateM 10 newStdGen
|
||||
zipWithM_ (\n r -> check $ shuffle (take n bs) r) [0,2..] rs
|
||||
zipWithM_ (\n r -> check $ shuffle (take n bs) r) [0,2 ..] rs
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
module VShuffle (shuffle) where
|
||||
module VShuffle
|
||||
( shuffle
|
||||
) where
|
||||
|
||||
import Data.List (mapAccumL)
|
||||
import System.Random
|
||||
|
|
@ -7,14 +9,22 @@ import qualified Data.Vector as V
|
|||
import qualified Data.Vector.Generic.Mutable as M
|
||||
|
||||
-- Generate a list of array index pairs, each corresponding to a swap.
|
||||
pairs :: (Enum a, Random a, RandomGen g) => a -> a -> g -> [(a, a)]
|
||||
pairs l u r = snd $ mapAccumL step r [l..pred u]
|
||||
where step r i = let (j, r') = randomR (i, u) r in (r', (i, j))
|
||||
pairs
|
||||
:: (Enum a, Random a, RandomGen g)
|
||||
=> a -> a -> g -> [(a, a)]
|
||||
pairs l u r = snd $ mapAccumL step r [l .. pred u]
|
||||
where
|
||||
step r i =
|
||||
let (j, r') = randomR (i, u) r
|
||||
in (r', (i, j))
|
||||
|
||||
-- Return a random permutation of the list. We use the algorithm described in
|
||||
-- http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm.
|
||||
shuffle :: (RandomGen g) => [a] -> g -> [a]
|
||||
shuffle xs r = V.toList . runST $ do
|
||||
v <- V.unsafeThaw $ V.fromList xs
|
||||
mapM_ (uncurry $ M.swap v) $ pairs 0 (M.length v - 1) r
|
||||
V.unsafeFreeze v
|
||||
shuffle
|
||||
:: (RandomGen g)
|
||||
=> [a] -> g -> [a]
|
||||
shuffle xs r =
|
||||
V.toList . runST $
|
||||
do v <- V.unsafeThaw $ V.fromList xs
|
||||
mapM_ (uncurry $ M.swap v) $ pairs 0 (M.length v - 1) r
|
||||
V.unsafeFreeze v
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
95
Task/Balanced-brackets/JavaScript/balanced-brackets-3.js
Normal file
95
Task/Balanced-brackets/JavaScript/balanced-brackets-3.js
Normal 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();
|
||||
})();
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
using Printf
|
||||
|
||||
function balancedbrackets(str::AbstractString)
|
||||
i = 0
|
||||
for c in str
|
||||
|
|
|
|||
98
Task/Balanced-brackets/X86-Assembly/balanced-brackets-2.x86
Normal file
98
Task/Balanced-brackets/X86-Assembly/balanced-brackets-2.x86
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
PROGRAM "balancedbrackets"
|
||||
VERSION "0.001"
|
||||
|
||||
IMPORT "xst"
|
||||
|
||||
DECLARE FUNCTION Entry()
|
||||
INTERNAL FUNCTION IsStringBalanced(str$)
|
||||
INTERNAL FUNCTION Generate$(n%%)
|
||||
|
||||
' Pseudo-random number generator
|
||||
' Based on the rand, srand functions from Kernighan & Ritchie's book
|
||||
' 'The C Programming Language'
|
||||
DECLARE FUNCTION Rand()
|
||||
DECLARE FUNCTION SRand(seed%%)
|
||||
|
||||
FUNCTION Entry()
|
||||
PRINT "Supplied examples"
|
||||
DIM tests$[6]
|
||||
tests$[0] = ""
|
||||
tests$[1] = "[]"
|
||||
tests$[2] = "]["
|
||||
tests$[3] = "[][]"
|
||||
tests$[4] = "][]["
|
||||
tests$[5] = "[[][]]"
|
||||
tests$[6] = "[]][[]"
|
||||
FOR example@@ = 0 TO UBOUND(tests$[])
|
||||
test$ = tests$[example@@]
|
||||
PRINT "The string '"; test$; "' is ";
|
||||
IFT IsStringBalanced(test$) THEN
|
||||
PRINT "OK."
|
||||
ELSE
|
||||
PRINT "not OK."
|
||||
END IF
|
||||
NEXT example@@
|
||||
PRINT
|
||||
PRINT "Random generated examples"
|
||||
XstGetSystemTime (@msec)
|
||||
SRand(INT(msec) MOD 32768)
|
||||
FOR example@@ = 1 TO 10
|
||||
test$ = Generate$(INT(Rand() / 32768.0 * 10.0) + 1)
|
||||
PRINT "The string '"; test$; "' is ";
|
||||
IFT IsStringBalanced(test$) THEN
|
||||
PRINT "OK."
|
||||
ELSE
|
||||
PRINT "not OK."
|
||||
END IF
|
||||
NEXT example@@
|
||||
END FUNCTION
|
||||
|
||||
FUNCTION IsStringBalanced(s$)
|
||||
paired& = 0
|
||||
i%% = 1
|
||||
DO WHILE i%% <= LEN(s$) && paired& >= 0
|
||||
c$ = MID$(s$, i%%, 1)
|
||||
SELECT CASE c$
|
||||
CASE "[":
|
||||
INC paired&
|
||||
CASE "]":
|
||||
DEC paired&
|
||||
END SELECT
|
||||
INC i%%
|
||||
LOOP
|
||||
END FUNCTION (paired& = 0)
|
||||
|
||||
FUNCTION Generate$(n%%)
|
||||
opensCount%% = 0
|
||||
closesCount%% = 0
|
||||
' Choose at random until n%% of one type generated
|
||||
generated$ = ""
|
||||
DO WHILE opensCount%% < n%% && closesCount%% < n%%
|
||||
SELECT CASE (INT(Rand() / 32768.0 * 2.0) + 1)
|
||||
CASE 1:
|
||||
INC opensCount%%
|
||||
generated$ = generated$ + "["
|
||||
CASE 2:
|
||||
INC closesCount%%
|
||||
generated$ = generated$ + "]"
|
||||
END SELECT
|
||||
LOOP
|
||||
' Now pad with the remaining other brackets
|
||||
IF opensCount%% = n%% THEN
|
||||
generated$ = generated$ + CHR$(']', n%% - closesCount%%)
|
||||
ELSE
|
||||
generated$ = generated$ + CHR$('[', n%% - opensCount%%)
|
||||
END IF
|
||||
END FUNCTION generated$
|
||||
|
||||
' Return pseudo-random integer on 0..32767
|
||||
FUNCTION Rand()
|
||||
#next&& = #next&& * 1103515245 + 12345
|
||||
END FUNCTION USHORT(#next&& / 65536) MOD 32768
|
||||
|
||||
' Set seed for Rand()
|
||||
FUNCTION SRand(seed%%)
|
||||
#next&& = seed%%
|
||||
END FUNCTION
|
||||
|
||||
END PROGRAM
|
||||
Loading…
Add table
Add a link
Reference in a new issue