Another year, another Advent of Code, the annual programming challenge from Eric Wastl and team. Yet, again, I'm taking the opportunity to do some recreational programming in Haskell.
Day 1 was the usual warm-up exercise, but a little trickier than most Day 1s because it was a Sunday.
The data input was to read two columns of numbers. I used the built-in lines
and words
functions to parse this into a list of pairs of numbers. Note the usual of lack of validation of the input.
main :: IO ()
main =
do dataFileName <- getDataFileName
text <- readFile dataFileName
let pairs = fmap readPair $ lines text
print $ part1 pairs
print $ part2 pairs
readPair :: String -> (Int, Int)
readPair s = (read a, read b)
where (a : b : _ ) = words s
Part 1
This part uses unzip
to convert the list of pairs into a pair of lists, which I then sort. I combine the sorted lists with zipWith
to find the differences, then fmap
over the results to find the absolute differences.
part1, part2 :: [(Int, Int)] -> Int
part1 pairs = sum $ fmap abs $ zipWith (-) (sort lefts) (sort rights)
where (lefts, rights) = unzip pairs
Part 2
I had to count how many times each number appears in column 2. The easiest way to do that was to use the Multiset library that counts how many times different things occur.
part2 pairs = sum $ fmap similarity lefts
where (lefts, rights) = unzip pairs
counts = MS.fromList rights
similarity l = l * (MS.occur l counts)
Code
You can get the code from my locally-hosted Git repo, or from Codeberg.