diff --git a/sapin/zigazou/README.md b/sapin/zigazou/README.md new file mode 100644 index 0000000..294da8b --- /dev/null +++ b/sapin/zigazou/README.md @@ -0,0 +1,10 @@ +Sapin by Zigazou +================ + +Ma contribution au programming challenge du sapin. + +Plusieurs versions : + +- `sapin.c` : version C plutôt mal codée mais respectant l’utilisation de la seule fonction `putchar` +- `sapin.hs` : version Haskell mieux codée (23 lignes de code, 66 lignes de commentaires) +- `sapino.hs` : version Haskell golfée de 351 caractères (directement issue de `sapin.hs`) diff --git a/sapin/zigazou/sapin.hs b/sapin/zigazou/sapin.hs new file mode 100644 index 0000000..df8878c --- /dev/null +++ b/sapin/zigazou/sapin.hs @@ -0,0 +1,89 @@ +{- | +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 \ No newline at end of file diff --git a/sapin/zigazou/sapino.hs b/sapin/zigazou/sapino.hs new file mode 100644 index 0000000..c19bb97 --- /dev/null +++ b/sapin/zigazou/sapino.hs @@ -0,0 +1,11 @@ +module Main where +import System.Environment +b=tail$scanl(+)1[y|x<-[6,8..],y<-[x,x]] +s w h=reverse[replicate w' '*'|w'<-take h[w, w-2..]] +d n=concat[s w$i+3|(w,i)<-zip b[1..n]] +q n=replicate n$replicate(n+1-mod n 2)'|' +c m s=replicate(div(m-length s)2)' '++s +t n=concat$(fmap.fmap)(c(b!!(n-1)))[d n,q n] +main = do + a:_<-getArgs + mapM_ putStrLn.t$read a \ No newline at end of file