You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.2 KiB
Haskell
89 lines
2.2 KiB
Haskell
{- |
|
|
Module : Sapin
|
|
Description : Print a pine
|
|
Copyright : (c) Frédéric BISSON, 2015
|
|
License : GPL-3
|
|
Maintainer : zigazou@free.fr
|
|
Stability : experimental
|
|
Portability : POSIX
|
|
|
|
______________________________
|
|
* |
|
|
*** This is a stair |
|
|
***** |
|
|
base ------->*******___________________________|
|
|
***** | Branches
|
|
******* |
|
|
********* This is another stair |
|
|
*********** |
|
|
base ---->*************________________________|
|
|
|||
|
|
||| This is the pied
|
|
|
|
-}
|
|
module Main where
|
|
import System.Environment (getArgs)
|
|
|
|
{-|
|
|
Draw a pine stair of specific base width and height.
|
|
-}
|
|
stair :: Int -> Int -> [String]
|
|
stair width height =
|
|
reverse [ replicate width' '*' | width' <- take height [width, width-2..] ]
|
|
|
|
{-|
|
|
Gives list of the base width of each stair.
|
|
|
|
Returned list looks something like [7,13,21,29,39,49,61,73,87,101...]
|
|
|
|
Note:
|
|
|
|
- [ xx | x <- [6, 8..], xx <- [x, x] ] = [6,6,8,8,10,10,12,12,14,14...]
|
|
-}
|
|
baseWidths :: [Int]
|
|
baseWidths = tail $ scanl (+) 1 [ xx | x <- [6, 8..], xx <- [x, x] ]
|
|
|
|
{-|
|
|
Draws the branches of a pine
|
|
-}
|
|
branchs :: Int -> [String]
|
|
branchs n =
|
|
concat [ stair width (i + 3) | (width, i) <- zip baseWidths [1..n] ]
|
|
|
|
{-|
|
|
Draws the pied of a pine
|
|
|
|
(n + 1 - mod n 2) is a trick to always have an odd number. 1 - n mod 2 =
|
|
|
|
- 1 if n is even
|
|
- 0 if n is odd
|
|
-}
|
|
pied :: Int -> [String]
|
|
pied n = replicate n $ replicate (n + 1 - mod n 2) '|'
|
|
|
|
{-|
|
|
Centers a string according to a width
|
|
-}
|
|
center :: Int -> String -> String
|
|
center width s = replicate (div (width - length s) 2) ' ' ++ s
|
|
|
|
{-|
|
|
Draws a complete (branches and pied) and centered pine
|
|
|
|
(baseWidths !! (n - 1)) gives the maximum width of the pine (the largest
|
|
base width)
|
|
-}
|
|
sapin :: Int -> [String]
|
|
sapin n = concat
|
|
$ (fmap . fmap) (center (baseWidths !! (n - 1))) [branchs n, pied n]
|
|
|
|
{-|
|
|
Print a pine
|
|
-}
|
|
printSapin :: Int -> IO ()
|
|
printSapin = mapM_ putStrLn . sapin
|
|
|
|
main :: IO ()
|
|
main = do
|
|
arg:_ <- getArgs
|
|
printSapin $ read arg |