DEV Community

Discussion on: Daily Challenge #144 - Box Office Clerk

Collapse
 
craigmc08 profile image
Craig McIlwrath

Haskell:

import Control.Monad (foldM) 
import Data.Maybe (isJust)

data CashBox = CashBox { v25 :: Int, v50 :: Int }

emptyBox :: CashBox
emptyBox = CashBox 0 0

add25s :: Int -> CashBox -> CashBox 
add25s n (CashBox x y) = CashBox (x + n) y 
add25 :: CashBox -> CashBox
add25 = add25s 1
take25s :: Int -> CashBox -> CashBox 
take25s n = add25s (-n)
take25 :: CashBox -> CashBox 
take25 = take25s 1
add50s :: Int -> CashBox -> CashBox 
add50s n (CashBox x y) = CashBox x (y + 1)
add50 :: CashBox -> CashBox
add50 = add50s 1
take50s :: Int -> CashBox -> CashBox 
take50s n = add50s (-n)
take50 :: CashBox -> CashBox 
take50 = take50s 1

makeChange :: Int -> CashBox -> Maybe CashBox
makeChange 25  c = Just $ add25 c
makeChange 50  c = if v25 c > 0
                   then Just $ add50 $ take25 c
                   else Nothing
makeChange 100 c = case v50 c of
                     0 -> if v25 c > 2 then Just (take25s 3 c) else Nothing
                     _ -> if v25 c > 0 then Just (take25 (take50 c)) else Nothing
makeChange _   _ = Nothing

tickets :: [Int] -> Bool
tickets = isJust . foldM (flip makeChange) emptyBox

I think all my utility add and take kinda obscure the code a bit. Oh well. Also I'm flipping makeChange because I realized after that foldM applies the arguments in the other order, and I was too lazy to rewrite :P