It's that time again! It's Advent of Code again, and I'm doing it in Haskell again.
I've been using Stack as a build environment, but it seems all the cool kids have gone back to Cabal again. It took me a while to iron the wrinkles out, the most annoying one was updating the
cabal-version directive in the main Cabal file, so that
common stanzas could be included. But I got there in the end. We shall see how things go when it comes to profiling and debugging!
We're given a list of depths (2000 numbers). Part A was to find how many numbers that were strictly larger than their predecessor. Part B was to find size-three sliding windows on the input, sum in those windows, and find how many windows summed larger than their predecessor.
For the "compare against predecessor" I used the trick of
zipping a list with its own tail. I went through a few iterations of the "compare to previous" filter, before ending up just using
uncurry to unpick the tuple from
main :: IO () main = do numStrs <- readFile "data/advent01.txt" let nums = map (read @Int) $ lines numStrs print $ part1 nums part1 :: [Int] -> Int part1 = countIncreasing countIncreasing :: [Int] -> Int countIncreasing nums = length $ filter (uncurry (>)) $ zip (tail nums) nums
For part B, I used
Data.List) to find all the sufixes, take the first three elements of each suffix, then filter to keep only the windows with three items (thus dropping the short few at the end).
The code is this:
part2 :: [Int] -> Int part2 nums = countIncreasing $ map sum windows where windows = filter ((== 3) . length) $ map (take 3) $ tails nums
It's easiest to see how it works by putting the steps into ghci.
> ns = [1,2,3,4,5,6,7,8] > tails ns [[1,2,3,4,5,6,7,8],[2,3,4,5,6,7,8],[3,4,5,6,7,8],[4,5,6,7,8],[5,6,7,8],[6,7,8],[7,8],,] > map (take 3) $ tails ns [[1,2,3],[2,3,4],[3,4,5],[4,5,6],[5,6,7],[6,7,8],[7,8],,] > filter ((==3) . length) $ map (take 3) $ tails ns [[1,2,3],[2,3,4],[3,4,5],[4,5,6],[5,6,7],[6,7,8]
Then sum the windows and use the same
countIncreasing as before.