Created
January 3, 2019 21:33
-
-
Save teppix/7a3aa73b84b16ee08b9dc8a6cd08eadf to your computer and use it in GitHub Desktop.
Ascii random filetree generator in haskell
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 | |
| import System.IO | |
| import System.Posix.Unistd (usleep) | |
| import System.Console.ANSI (clearScreen, hideCursor, showCursor) | |
| data Prefix = Root | |
| | Single | First | Middle | |
| | Last | |
| deriving (Show, Eq) | |
| type Name = String | |
| data Node = File Name | |
| | Folder Name [Node] | |
| deriving (Show) | |
| prefix :: Prefix -> String | |
| prefix Single = "---" | |
| prefix First = "-+-" | |
| prefix Middle = " |-" | |
| prefix Last = " `-" | |
| prefix Root = "" | |
| spacer :: Prefix -> String | |
| spacer Single = " " | |
| spacer First = " | " | |
| spacer Middle = " | " | |
| spacer Last = " " | |
| spacer Root = "" | |
| blank :: String -> String | |
| blank s = replicate (length s) ' ' | |
| positions :: [a] -> [Prefix] | |
| positions items | |
| | n==0 = [] | |
| | n==1 = [Single] | |
| | otherwise = [First] ++ (replicate (n-2) Middle) ++ [Last] | |
| where n = length items | |
| showNode :: Prefix -> Node -> [String] | |
| showNode pos (File name) = [(prefix pos) ++ name] | |
| showNode pos (Folder name []) = [ (prefix pos) ++ name ++ (prefix Single) ] | |
| showNode pos (Folder name items) = | |
| zipWith (++) prefixes $ concat $ zipWith showNode (positions items) items | |
| where | |
| prefix' = (prefix pos) ++ name | |
| prefixes = [prefix'] ++ repeat ((spacer pos) ++ (blank name)) | |
| showTree :: Node -> String | |
| showTree node = unlines $ showNode Root node | |
| printTree :: Node -> IO () | |
| printTree t = clearScreen >> putStr (showTree t) >> hFlush stdout | |
| randomNodes :: StdGen -> Float -> Int -> [Node] | |
| randomNodes gen0 ratio maxfiles = (n : ns) | |
| where (gen1, gen2) = split gen0 | |
| n = randomTree gen1 ratio maxfiles | |
| ns = randomNodes gen2 ratio maxfiles | |
| randomFolder :: StdGen -> Float -> Int -> Node | |
| randomFolder gen0 ratio maxfiles = | |
| Folder "mapp" childNodes | |
| where | |
| (rnd, gen1) = random gen0 :: (Float, StdGen) | |
| childCount = round (rnd * fromIntegral maxfiles) | |
| childNodes = take childCount $ randomNodes gen1 ratio maxfiles | |
| randomTree :: StdGen -> Float -> Int -> Node | |
| randomTree gen0 ratio maxfiles = | |
| if x1 < ratio then randomFolder gen1 (ratio * 0.8) maxfiles | |
| else File "fil" | |
| where (x1, gen1) = random gen0 :: (Float, StdGen) | |
| mainLoop :: StdGen -> IO () | |
| mainLoop gen = do | |
| let (gen1, gen2) = split gen | |
| printTree $ randomFolder gen1 0.5 5 | |
| getLine >> mainLoop gen2 | |
| setup :: IO () | |
| setup = hSetBuffering stdout $ BlockBuffering (Just 2048) | |
| main :: IO () | |
| main = setup >> getStdGen >>= mainLoop |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment