import System.IO import System.Random import Control.Monad import Data.List import Data.Maybe main :: IO () main = hSetEncoding stdout utf8 >> mapM_ (christmasTree >=> putStrLn) [1..7] ornaments :: [Char] ornaments = "*NiXJo%b" christmasTree :: Int -> IO String christmasTree h = do is <- mapM (flip replicateM (rollIkasamaDice dist)) ws let body = ["☆"] ++ map (map (ornaments !!)) is ++ ["||"] indent = reverse $ map spacer $ [h - 1] ++ map (`div` 2) ws ++ [h - 1] return $ unlines $ zipWith (++) indent body where dist = 30 : replicate (length ornaments - 1) 1 ws = [2, 4 .. (h - 1) * 2] spacer = flip replicate ' ' rollIkasamaDice :: [Double] -> IO Int rollIkasamaDice dist = do r <- getStdRandom (randomR (0, 1)) :: IO Double return $ snd $ fromJust $ find ((r <=) . fst) dice where thr = scanl1 (+) $ map . flip (/) =<< sum $ dist dice = zip thr [0..] :: [(Double, Int)]