Skip to content

Reflections 2025

github-actions[bot] edited this page Dec 1, 2025 · 17 revisions

2016 / 2018 / 2019 / 2020 / 2021 / 2022 / 2023 / 2024 / 2025

Table of Contents

Day 1

Top / Prompt / Code / Standalone

Another tradition of advent of code day 1 --- everything is just a scan!

Once we parse the input into a list of integers:

parseInp :: String -> [Int]
parseInp = read . mapMaybe rephrase . lines
  where
    rephrase 'R' = Nothing
    rephrase 'L' = Just '-'
    rephrase d = Just d

Then we can do the cumulative sum and count the zero's. It actually becomes even easier if we restrict ourselves to the integers modulo 100 using the finite-typelits library and Finite n, using modulo :: Integer -> Finite n to cast:

part1 :: [Finite 100] -> Int
part1 = length . filter (== 0) . scanl' (+) 50

Part 2 you can probably do using more modulo and division tricks but the simplest way is probably just to explode all of the ranges and do the same counts. We use mapAccumL to map a stateful function, where the state is our current position and our output is the list of all the traveled numbers:

part2 :: [Int] -> Int
part2 = length . filter (== 0) . concat . snd . mapAccumL go 50
  where
    go curr bump
      | bump > 0 = (curr + bump, [curr + 1 .. curr + bump])
      | otherwise = (curr + bump, [curr + bump .. curr - 1])

Because of lazy lists, this is constant space! :)

Day 1 Benchmarks

>> Day 01a
benchmarking...
time                 167.3 μs   (167.1 μs .. 167.8 μs)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 168.4 μs   (167.9 μs .. 169.1 μs)
std dev              1.947 μs   (1.349 μs .. 2.629 μs)

* parsing and formatting times excluded

>> Day 01b
benchmarking...
time                 229.4 μs   (228.9 μs .. 230.0 μs)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 229.2 μs   (229.0 μs .. 229.7 μs)
std dev              1.075 μs   (790.8 ns .. 1.538 μs)

* parsing and formatting times excluded

Clone this wiki locally