Skip to content

Instantly share code, notes, and snippets.

@mtolly
Last active August 29, 2015 14:18
Show Gist options
  • Save mtolly/4df48c8d6bd7137b3406 to your computer and use it in GitHub Desktop.
Save mtolly/4df48c8d6bd7137b3406 to your computer and use it in GitHub Desktop.
{- |
No attempt made to golf, but I did throw some alternate solutions in.
-}
module HW3 where
import Data.List (transpose)
skips :: [a] -> [[a]]
skips xs = zipWith const (map (f xs) [0..]) xs where
-- "zipWith const" clamps the first list to be no longer than the second.
-- Credit to http://stackoverflow.com/a/16379034
-- Also would work: skips xs = takeWhile (not . null) $ map (f xs) [0..]
-- skips xs = map (f xs) [0 .. length xs - 1] -- how boring
f [] _ = []
f ys n = case drop n ys of
[] -> []
y : yt -> y : f yt n
-- | Straightforward recursion
localMaxima :: [Integer] -> [Integer]
localMaxima [] = []
localMaxima (x : y : xs@(z : _))
| y > x && y > z
= y : localMaxima xs
localMaxima (_ : xs) = localMaxima xs
-- | Zip-happy solution
localMaxima' :: [Integer] -> [Integer]
localMaxima' xs@(_ : ys@(_ : zs)) = let
lt = False : zipWith (<) xs ys
gt = False : zipWith (>) ys zs
in map snd $ filter fst $ zip (zipWith (&&) lt gt) xs
localMaxima' _ = []
-- | Compute each cell, much like Data.Vector.generate
histogram :: [Integer] -> String
histogram ns = unlines $ let
counts = [ length $ filter (== n) ns | n <- [0..9] ]
level i = [ if c >= i then '*' else ' ' | c <- counts ]
maxLevel = maximum counts
footer = ["==========", ['0'..'9']]
in map level [maxLevel, maxLevel - 1 .. 1] ++ footer
-- | Make each column as a row, then transpose
histogram' :: [Integer] -> String
histogram' ns = unlines $ let
counts = [ length $ filter (== n) ns | n <- [0..9] ]
levels = reverse $ transpose
[ take maxLevel $ replicate c '*' ++ repeat ' ' | c <- counts ]
maxLevel = maximum counts
footer = ["==========", ['0'..'9']]
in levels ++ footer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment