Personal tools

Programming performance/JCAB Haskell

From HaskellWiki

< Programming performance
Revision as of 07:53, 13 December 2009 by Newacct (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
  • Language: Haskell
  • Skill: Intermediate. I don't use Haskell much, and I keep going back to the library documentation for the simplest of functions, but I believe I understand many of the scaries aspects of the language.
  • Time: Approx 50 minutes.
  • Notes: This is a bit of let-overkill, but to me it makes sense this way. I didn't see any of the other submissions prior to doing this. I used Visual Haskell for development. I needed two iterations (silly bugs!). I get 13754.97774 as the answer, which sounds more-or-less right (37% gain). It would be nice to know the (a?) correct answer ahead of time, so we know when we got the program right. The problem wasn't very clearly described, IMHO.

Code

module Main where
 
programmingPerformance file =
    let filteredFile = filter filterLine (lines file)
        filterLine [] = False
        filterLine ('#':_) = False
        filterLine _ = True
 
        closingList = reverse (map extractClosing filteredFile) :: [Double]
        extractClosing line = read ((tokenize line) !! 6)
        tokenize [] = []
        tokenize line = let (token, rest) = getToken line in token : tokenize rest
        getToken []       = ("", [])
        getToken (' ':xs) = ("", xs)
        getToken (x  :xs) = let (token, rest) = getToken xs in (x:token, rest)
 
        result = parseClosingSell 10000.0 [] closingList
        parseClosingSell :: Double -> [(Double, Double)] -> [Double] -> Double
        parseClosingSell cash shares c@(_:y:rest) =
            let (sale, remShares) = foldr maybeSell (0, []) shares
                maybeSell (shClosing, shNum) (accCash, accShares) | (y - shClosing) >= shClosing * 0.06 = (accCash + y * shNum, accShares)
                maybeSell sh                 (accCash, accShares)                                       = (accCash            , sh:accShares)
            in parseClosingBuy (cash + sale) remShares c
        parseClosingSell cash shares [y] =
            let sale = foldr sell 0 shares
                sell (shClosing, shNum) accCash = accCash + y * shNum
            in cash + sale
        parseClosingBuy cash shares (x:y:rest) | (x - y) >= x * 0.03 = parseClosingSell (cash * 0.90) ((y, cash*0.10 / y):shares) (y:rest)
        parseClosingBuy cash shares (x:rest) = parseClosingSell cash shares rest
 
    in result
 
main = do
    file <- readFile "C:\\JCAB\\ProgrammingPerformance\\gspc.txt"
    let result = programmingPerformance file
    print result