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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue