• Skill: Intermediate. I learned Haskell some months ago but didn't use it for a serious project so far.
• Time: 30 minutes

Code

module Main where

data Values = Values { money, lastCosts :: Double
, stock            :: [(Double, Double)] }

readClosingCosts :: String -> Double
readClosingCosts = read . last . words

notComment ('#':_) = False
notComment _       = True

readCosts :: IO [Double]
(return . map readClosingCosts . filter notComment . lines)

buy :: Values -> Double -> Double -> Values
buy v c amount = Values { money = (1 - amount) * money v
, stock = (amount * (money v) / c, c) : stock v
, lastCosts = c }

sellAll costs (bought, _) = bought * costs

sellFinally :: Double -> Values -> Double
sellFinally costs v = money v + (sum \$ map (sellAll costs) (stock v))

tooMuchUp costs (bought, origCosts) = costs >= 1.06 * origCosts

step1 costs v
| costs <= 0.97 * lastCosts v = buy v costs 0.1
| otherwise                   = v { lastCosts = costs }

step2 costs v = v { money = money v + newMoney
, stock = filter (not . tooMuchUp costs) (stock v) }
where newMoney = sum \$ map (sellAll costs)
(filter (tooMuchUp costs) (stock v))

step :: Double -> Values -> Values
step costs v = step2 costs (step1 costs v)

main = do