module Sound.Conductive.MiscListUtils where
import System.Random
import Data.List
import Data.Array.ST
import Data.Time.Clock.POSIX
import Control.Monad
import Control.Monad.ST
import Data.STRef
import Sound.Conductive.MusicalTime
unconcat xs = map (\x -> [x]) xs
getSeed = getPOSIXTime >>= \x -> return $ truncate $ x * 100000000
slice :: [a] -> [Int] -> [a]
xs `slice` indices = map (xs !!) indices
replaceAt :: Int -> [a] -> [a] -> [a]
replaceAt i ys xs =
let xz = splitAt i xs
in (fst xz) ++ ys ++ (tail $ snd xz)
npletAt :: (Fractional a) => Int -> Int -> [a] -> [a]
npletAt n i xs =
let x = xs!!i
plet = replicate n $ x/(fromIntegral n)
in replaceAt i plet xs
joinVals :: (Num a) => Int -> Int -> [a] -> [a]
joinVals sp n xs = let
splitXs = splitAt sp xs
newFront = fst splitXs
oldRest = snd splitXs
newRest = [sum $ take n $ oldRest] ++ (snd $ splitAt n oldRest)
in newFront ++ newRest
stutter :: Int -> Int -> Int -> [a] -> [a]
stutter sp l n xs = let
splitList = splitAt sp xs
initial = fst splitList
toBeStuttered = take l $ snd splitList
remainder = snd $ splitAt l $ snd splitList
stuttered = concat $ replicate n toBeStuttered
in initial ++ stuttered ++ remainder
diff_select :: Int -> Int -> IO [Int]
diff_select n to = diff_select' n [0..to]
diff_select' 0 _ = return []
diff_select' _ [] = error "too few elements to choose from"
diff_select' n xs = do r <- randomRIO (0,(length xs)1)
let remaining = take r xs ++ drop (r+1) xs
rest <- diff_select' (n1) remaining
return ((xs!!r) : rest)
randomSubset xs subsetSize = let
len = length xs
in do is <- diff_select subsetSize $ (len 1)
return $ map (xs!!) is
shuffle' :: [a] -> StdGen -> ([a],StdGen)
shuffle' xs gen = runST (do
g <- newSTRef gen
let randomRST lohi = do
(a,s') <- liftM (randomR lohi) (readSTRef g)
writeSTRef g s'
return a
ar <- newArray n xs
xs' <- forM [1..n] $ \i -> do
j <- randomRST (i,n)
vi <- readArray ar i
vj <- readArray ar j
writeArray ar j vi
return vj
gen' <- readSTRef g
return (xs',gen'))
where
n = length xs
newArray :: Int -> [a] -> ST s (STArray s Int a)
newArray n xs = newListArray (1,n) xs
shuffle :: [a] -> IO [a]
shuffle xs = getStdRandom (shuffle' xs)rotate :: [a] -> Int -> [a]
rotate xs n = drop nn xs ++ take nn xs
where
nn = n `mod` length xs
lace :: [[a]] -> Int -> [a]
lace xss n = let
listNLengths = zip (map length xss) (xss)
selector t x = (snd x)!!(mod t $ fst x)
aRun t = map (selector t) listNLengths
o = ceiling $ (fromIntegral n)/(fromIntegral $ length xss)
in take n $ concat $ map aRun [0..o]
randomList :: Int -> StdGen -> [Int]
randomList n = take n . unfoldr (Just . random)
normalize xs = map (\x -> x/m) xs where m = maximum xs
normalizeTo t xs = map (\x -> x * m) xs where m = t/(maximum xs)
lerp (x1,y1) (x2,y2) x = y1 + (x x1) * (y2 y1) / (x2 x1)
rList :: Int -> IO [Int]
rList x = do
seed <- newStdGen
let rs = randomList x seed
return $ map abs rs
pick :: [a] -> IO a
pick [] = undefined
pick [x] = do return x
pick (x:xs) = pick' x xs (2 :: Int)
pick' curr [] _ = do return curr
pick' curr (next:rest) prob
= do r <- getStdRandom (randomR (1,prob))
let curr' = if r == 1 then next else curr
pick' curr' rest (prob+1)
pickN :: (Num a, Enum a) => a -> [b] -> IO [b]
pickN n xs = mapM (\_ -> pick xs) [1..n]
coin :: IO Bool
coin = pick [True,False]
odds :: Int -> Int -> IO Bool
odds n d = pick $ (replicate n False) ++ (replicate d True)
replicator :: [(Int, b)] -> [b]
replicator xs = concat $ map (\x -> replicate (fst x) $ snd x ) xs
weightedList = replicator
takeToValue' :: (Ord a, Num a) => [a] -> a -> a -> [a] -> [a]
takeToValue' xs val curVal ys
| xs == [] = if (val <= curVal)
then ys
else ys ++ [valcurVal]
| otherwise =
let c = head xs
d = curVal + c
adjustValue input comparison
| input >= comparison = (False,input comparison)
| input < comparison = (True,0)
test = adjustValue d val
in if (fst test)
then takeToValue' (tail xs) val d $ ys ++ [c]
else takeToValue' ([]) val d $ ys ++ [c (snd test)]
takeToValue :: (Num a, Ord a) => a -> [a] -> [a]
takeToValue val xs = takeToValue' xs val 0 []