Skip to content

Instantly share code, notes, and snippets.

Created February 1, 2013 07:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4689847 to your computer and use it in GitHub Desktop.
Save anonymous/4689847 to your computer and use it in GitHub Desktop.
Challenge #119
-- Types used
data Coin = Quarter | Dime | Nickle | Penny deriving (Show, Eq)
type CoinBag = [Coin]
-- variables
allCoins :: CoinBag
allCoins = [Quarter,Dime,Nickle,Penny]
-- Pretty printing helper
pretty :: CoinBag -> IO ()
pretty bag = do
mapM_ putOne allCoins
where putOne = \coin -> prettyLine coin (countCoins bag coin)
prettyLine :: Coin -> Int -> IO ()
prettyLine coin 0 = return ()
prettyLine coin count = putStrLn $ show coin ++ ": " ++ show count
countCoins :: CoinBag -> Coin -> Int
countCoins bag coin = length $ filter (== coin) bag
-- Determine the value of a Coin or CoinBag
val :: Coin -> Integer
val coin = case coin of
Quarter -> 25
Dime -> 10
Nickle -> 5
Penny -> 1
bagVal :: CoinBag -> Integer
bagVal [] = 0
bagVal bag = sum $ map val bag
-- Algorithm for determining coins needed
addCoins :: CoinBag -> Integer -> Coin -> CoinBag
addCoins bag maxVal coin =
let potentialBag = coin:bag
in if bagVal potentialBag > maxVal
then bag
else addCoins potentialBag maxVal coin
addAllCoins :: CoinBag -> Integer -> CoinBag -> CoinBag
addAllCoins bag maxVal [] = undefined
addAllCoins bag maxVal (coin:otherCoins) =
if bagVal bagWithC == maxVal
then bagWithC
else addAllCoins bagWithC maxVal otherCoins
where bagWithC = addCoins bag maxVal coin
-- Helper for reading a Double value and converting to an Integer
getInteger :: IO Integer
getInteger = getLine >>= \x -> return . truncate . (100*) $ (read x :: Double)
-- Main method
main :: IO ()
main = do
putStrLn "Enter a value:"
amount <- getInteger
pretty $ addAllCoins [] amount allCoins
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment