temp_stats.hs in Haskell
Reports a week of daily highs with the low, high, mean, and a bar chart beside each day.
-- Daily highs in degrees Fahrenheit for one week.
week :: [(String, Int)]
week =
[ ("Mon", 63), ("Tue", 71), ("Wed", 68), ("Thu", 74)
, ("Fri", 80), ("Sat", 77), ("Sun", 66)
]
highs :: [Int]
highs = map snd week
mean :: [Int] -> Double
mean [] = 0
mean xs = fromIntegral (sum xs) / fromIntegral (length xs)
-- One block per two degrees above the coldest day keeps bars short.
bar :: Int -> Int -> String
bar base t = replicate (1 + (t - base) `div` 2) '#'
-- A day is marked against the weekly mean, not against its neighbors.
mark :: Double -> Int -> Char
mark avg t
| fromIntegral t > avg = '+'
| fromIntegral t < avg = '-'
| otherwise = '='
oneDecimal :: Double -> String
oneDecimal x = show whole ++ "." ++ show frac
where
(whole, frac) = round (x * 10) `divMod` (10 :: Int)
pad :: Int -> String -> String
pad n s = s ++ replicate (n - length s) ' '
lpad :: Int -> String -> String
lpad n s = replicate (n - length s) ' ' ++ s
row :: Double -> Int -> (String, Int) -> String
row avg base (day, t) =
pad 5 day ++ lpad 4 (show t) ++ " " ++ [mark avg t]
++ " " ++ bar base t
rule :: String
rule = replicate 26 '-'
main :: IO ()
main = do
let avg = mean highs
coldest = minimum highs
warmest = maximum highs
putStrLn "weekly highs, degrees F"
putStrLn (pad 5 "day" ++ lpad 4 "high" ++ " vs chart")
putStrLn rule
mapM_ (putStrLn . row avg coldest) week
putStrLn rule
putStrLn (pad 5 "low" ++ lpad 4 (show coldest))
putStrLn (pad 5 "high" ++ lpad 4 (show warmest))
putStrLn (pad 5 "mean" ++ lpad 6 (oneDecimal avg))
putStrLn (pad 5 "range" ++ lpad 4 (show (warmest - coldest)))
How it works
mean highsaverages the week, andminimum highsfixes the baseline the bars grow from.mark avg tyields'+','-', or'='according to how that day compares with the mean.rowbuilds each line frompad 5 day ++ lpad 4 (show t)followed by the mark and the bar.
Keywords and builtins used here
CharDoubleIOIntStringbardohighsletlpadmainmarkmeanoneDecimalpadrowruleweekwhere
The run, in numbers
- Lines
- 58
- Characters to type
- 1590
- Tokens
- 415
- Three-star pace
- 80 tpm
At the three-star pace of 80 tokens a minute, this run takes about 311 seconds.
Step 3 of 3 in Encore, step 27 of 27 in Language basics.