From 82297cd5f27d2247b0bf837aa5d1c3fb966cff39 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 13 Dec 2020 12:48:10 +0000 Subject: [PATCH] [hs] Clean up 2020_13 even more --- hs/src/Aoc/Y2020/D13.hs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/hs/src/Aoc/Y2020/D13.hs b/hs/src/Aoc/Y2020/D13.hs index 0b33440..132dccb 100644 --- a/hs/src/Aoc/Y2020/D13.hs +++ b/hs/src/Aoc/Y2020/D13.hs @@ -7,7 +7,6 @@ module Aoc.Y2020.D13 import Control.Monad import Data.Foldable import Data.Function -import Data.Maybe import Aoc.Day import Aoc.Parse @@ -25,21 +24,24 @@ parser = do void newline pure (earliest, [Bus bid delta | (Just bid, delta) <- zip buses [0..]]) +waitTime :: Integer -> Bus -> Integer +waitTime time bus = time `mod` bId bus + departsAt :: Bus -> Integer -> Bool departsAt bus time = (time + bDelta bus) `mod` bId bus == 0 +-- See https://en.wikipedia.org/wiki/Chinese_remainder_theorem#Search_by_sieving earliestTimestamp :: [Bus] -> Integer -> Integer -> Integer -earliestTimestamp [] start _ = start -earliestTimestamp (b:bs) start step = earliestTimestamp bs time (lcm step $ bId b) - where - time = fromJust $ find (b `departsAt`) $ iterate (+ step) start +earliestTimestamp [] time _ = time +earliestTimestamp (b:bs) time step + | b `departsAt` time = earliestTimestamp bs time (step * bId b) + | otherwise = earliestTimestamp (b:bs) (time + step) step solver :: (Integer, [Bus]) -> IO () solver (earliest, buses) = do putStrLn ">> Part 1" - let busTimes = [(bid, earliest `mod` bid) | Bus bid _ <- buses] - (nextBus, waitTime) = minimumBy (compare `on` snd) busTimes - print $ nextBus * waitTime + let nextBus = minimumBy (compare `on` waitTime earliest) buses + print $ bId nextBus * waitTime earliest nextBus putStrLn "" putStrLn ">> Part 2"