{-# Language QuasiQuotes #-}
{-|
Module      : Main
Description : Day 13 solution
Copyright   : (c) Eric Mertens, 2020
License     : ISC
Maintainer  : emertens@gmail.com

<https://adventofcode.com/2020/day/13>

-}
module Main (main) where

import Advent.Chinese (toMod, chinese)
import Advent.Format (format)
import Data.Foldable (traverse_)
import Data.List (foldl1')

-- |
-- >>> :main
-- 3215
-- 1001569619313439
main :: IO ()
IO ()
main =
  do (Integer
t,[Maybe Integer]
rawBusses) <- [format|2020 13 %lu%n(x|%lu)&,%n|]
     let busses :: [(Integer, Integer)]
busses = [(Integer
i,Integer
b) | (Integer
i, Just Integer
b) <- [Integer] -> [Maybe Integer] -> [(Integer, Maybe Integer)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Integer
0..] [Maybe Integer]
rawBusses]
     Integer -> IO ()
forall a. Show a => a -> IO ()
print (Integer -> [Integer] -> Integer
part1 Integer
t (((Integer, Integer) -> Integer)
-> [(Integer, Integer)] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map (Integer, Integer) -> Integer
forall a b. (a, b) -> b
snd [(Integer, Integer)]
busses))
     (Integer -> IO ()) -> Maybe Integer -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Integer -> IO ()
forall a. Show a => a -> IO ()
print ([(Integer, Integer)] -> Maybe Integer
part2 [(Integer, Integer)]
busses)

part1 :: Integer -> [Integer] -> Integer
part1 :: Integer -> [Integer] -> Integer
part1 Integer
t [Integer]
busses = (Integer -> Integer -> Integer) -> (Integer, Integer) -> Integer
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(*) ([(Integer, Integer)] -> (Integer, Integer)
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [((-Integer
t)Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod`Integer
b, Integer
b) | Integer
b <- [Integer]
busses])

part2 :: [(Integer, Integer)] -> Maybe Integer
part2 :: [(Integer, Integer)] -> Maybe Integer
part2 [(Integer, Integer)]
busses = [Mod] -> Maybe Integer
chinese [Integer -> Integer -> Mod
toMod (-Integer
x) Integer
y | (Integer
x,Integer
y) <- [(Integer, Integer)]
busses]