module Htirage.Bits where
import Data.Bool
import Data.Eq (Eq(..))
import Data.Int (Int)
import Data.List ((++), foldr, length, splitAt, tail)
import Data.Ord (Ord(..))
import Prelude (Integer, Integral(..), Num(..), error, undefined)
import Text.Show (Show(..))
bitSize :: Integer -> Int
bitSize n | 0<=n = go n
| otherwise = undefined
where go 0 = 0
go i = 1 + go (i`div`2)
integerOfBits :: [Bool] -> Integer
integerOfBits [] = 0
integerOfBits (b:bs) = integerOfBits bs * 2 + (if b then 1 else 0)
bitsOfInteger :: Int -> Integer -> [Bool]
bitsOfInteger m n | 0<=m,0<=n = go m n
| otherwise = undefined
where go 0 _ = []
go i j = (r==1) : go (i-1) q
where (q,r) = j`divMod`2
interleaveBits :: [[Bool]] -> [Bool]
interleaveBits [] = []
interleaveBits bss =
let (hs,ts) = unzip bss in
hs ++ interleaveBits ts
where
unzip = foldr (\bits ~(hs,ts) ->
case bits of
[] -> (hs,ts)
b:bs -> (b:hs,bs:ts)
) ([], [])
randomIntegerOfBits :: Integer -> [Bool] -> Integer
randomIntegerOfBits n bs | given < enough = error (show (enough - given) ++ " bits missing")
| n <= i = randomIntegerOfBits n (tail bits ++ bs')
| otherwise = i
where (bits, bs') = splitAt enough bs
i = integerOfBits bits
given = length bits
enough = bitSize (n - 1)