Created
November 26, 2012 07:03
-
-
Save qtamaki/4146955 to your computer and use it in GitHub Desktop.
Random Expression Generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import System.Random | |
------------------------------------------------------------------------------ | |
-- RANDOM Stream | |
------------------------------------------------------------------------------ | |
randomX x = randomR (0,x -1) | |
type RandomF = StdGen -> (Int, StdGen) | |
ranStImpl :: StdGen -> RandomF -> [Int] | |
ranStImpl sg = \rf -> | |
let (a, sg') = rf sg | |
in a : ranStImpl sg' rf | |
randomStream :: Int -> IO [Int] | |
randomStream x = getStdRandom (\g -> let (g',g'') = split g | |
r = randomX x | |
in (ranStImpl g' r, g'')) | |
-- TEST | |
-- randomStream >>= \l -> print $ foldl (+) 0 $ take 100 l | |
------------------------------------------------------------------------------ | |
-- Expr Generator | |
------------------------------------------------------------------------------ | |
-- Operator Stream | |
int2Ope :: Int -> Char | |
int2Ope x = case x of | |
0 -> '+' | |
1 -> '-' | |
2 -> '*' | |
3 -> '/' | |
opeStream = randomStream 4 >>= return . (map int2Ope) | |
-- Kakko Stream | |
data Kakko = Kak | Kok | None deriving Show | |
type Depth = Int | |
data KakkoNode = KakkoNode Kakko Kakko Depth deriving Show | |
kakkoStream = randomStream 2 >>= return . (map (\x -> if x == 0 then Kak else None)) | |
kokkaStream = randomStream 2 >>= return . (map (\x -> if x == 0 then Kok else None)) | |
calcDepth :: Kakko -> Kakko -> Depth -> KakkoNode | |
calcDepth Kak _ d = KakkoNode Kak None (d + 1) | |
calcDepth _ Kok d | d > 0 = KakkoNode None Kok (d - 1) | |
| otherwise = KakkoNode None None d | |
calcDepth ka ko d = KakkoNode ka ko d | |
knStream :: [Kakko] -> [Kakko] -> Depth -> [KakkoNode] | |
knStream [] _ _ = [] | |
knStream (ka:kas) (ko:kos) d = case calcDepth ka ko d of | |
(KakkoNode ka' ko' d') -> KakkoNode ka' ko' d' : knStream kas kos d' | |
-- Nodes | |
data ExprNode = ENumber Int| EOpe Char| EKakko Kakko deriving Show | |
endKokkas :: Int -> [ExprNode] | |
endKokkas depth = take depth $ repeat $ EKakko Kok | |
joinEx :: [Int] -> [Char] -> [KakkoNode] -> [ExprNode] | |
joinEx (i:[]) (o:opes) (k:kakkos) = case k of | |
(KakkoNode st en depth) -> EKakko st : ENumber i : EKakko en : endKokkas depth | |
joinEx (i:ints) (o:opes) (k:kakkos) = case k of | |
(KakkoNode st en _) -> EKakko st : ENumber i : EKakko en : EOpe o : joinEx ints opes kakkos | |
gen range nums = do ints <- randomStream range | |
opes <- opeStream | |
kas <- kakkoStream | |
kos <- kokkaStream | |
print $ printsE $ joinEx (take nums ints) opes (knStream kas kos 0) | |
-- Print Utility | |
printE :: ExprNode -> [Char] | |
printE e = case e of | |
ENumber i -> show i | |
EOpe c -> return c | |
EKakko k -> case k of | |
Kak -> return '(' | |
Kok -> return ')' | |
None -> [] | |
printsE :: [ExprNode] -> [Char] | |
printsE [] = [] | |
printsE (e:es) = printE e ++ printsE es | |
-- main function | |
main :: IO () | |
main = gen 1000 10 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment