Advent of Code 2024 day 1

    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.

    Neil Smith

    Read more posts by this author.