module Main import System alu : String alu = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGG\ \TCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGG\ \CGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGC\ \GGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA" iub : List (Char, Double) iub = [('a',0.27),('c',0.12),('g',0.12),('t',0.27),('B',0.02) ,('D',0.02),('H',0.02),('K',0.02),('M',0.02),('N',0.02) ,('R',0.02),('S',0.02),('V',0.02),('W',0.02),('Y',0.02)] homosapiens : List (Char, Double) homosapiens = [('a',0.3029549426680),('c',0.1979883004921) ,('g',0.1975473066391),('t',0.3015094502008)] takeRepeat : Int -> String -> String takeRepeat n s = if n > m then s ++ takeRepeat (n-m) s else pack $ take (cast n) $ unpack s where m = cast $ length s splitAt' : Nat -> String -> (String, String) splitAt' n s = let s' = unpack s in (pack $ take n s', pack $ drop n s') writeAlu : String -> String -> IO () writeAlu name s0 = putStrLn name *> go s0 where go "" = return () go s = let (h,t) = splitAt' 60 s in putStrLn h *> go t replicate : Int -> Char -> String replicate 0 c = "" replicate n c = singleton c <+> replicate (n-1) c scanl : (f : acc -> a -> acc) -> acc -> List a -> List acc scanl f q ls = q :: (case ls of [] => [] x::xs => scanl f (f q x) xs) accum : (Char,Double) -> (Char,Double) -> (Char,Double) accum (_,p) (c,q) = (c,p+q) make : String -> Int -> List (Char, Double) -> Int -> IO Int make name n0 tbl seed0 = do putStrLn name make' n0 0 seed0 "" where modulus : Int modulus = 139968 fill : List (Char,Double) -> Int -> List String fill ((c,p) :: cps) j = let k = min modulus (cast (cast modulus * p + 1)) in replicate (k - j) c :: fill cps k fill _ _ = [] lookupTable : String lookupTable = Foldable.concat (fill (scanl accum ('a',0) tbl) 0) make' : Int -> Int -> Int -> String -> IO Int make' 0 col seed buf = when (col > 0) (putStrLn buf) *> return seed make' n col seed buf = do let newseed = modInt (seed * 3877 + 29573) modulus let nextchar = strIndex lookupTable newseed let newbuf = buf <+> singleton nextchar if col+1 >= 60 then putStrLn newbuf *> make' (n-1) 0 newseed "" else make' (n-1) (col+1) newseed newbuf main : IO () main = do (_ :: n :: _) <- getArgs writeAlu ">ONE Homo sapiens alu" (takeRepeat (fromInteger (cast n)*2) alu) nseed <- make ">TWO IUB ambiguity codes" (fromInteger (cast n)*3) iub 42 make ">THREE Homo sapiens frequency" (fromInteger (cast n)*5) homosapiens nseed return ()