It's that time again! It's Advent of Code again, and I'm doing it in Haskell again.
Build environment
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!
The problem
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 zip
ping a list with its own tail. I went through a few iterations of the "compare to previous" filter, before ending up just using (>)
in filter
(and uncurry
to unpick the tuple from zip
):
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 tails
(from 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],[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],[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.
Code
You can get the code from my locally-hosed Git repo, or from Gitlab.