{-# Language QuasiQuotes #-}
module Main where
import Advent.Format ( format )
import Data.List ( foldl', find )
type Scanners = [(Int,Int)]
main :: IO ()
IO ()
main =
do [(Int, Int)]
input <- [format|2017 13 (%u: %u%n)*|]
Int -> IO ()
forall a. Show a => a -> IO ()
print ([(Int, Int)] -> Int
part1 [(Int, Int)]
input)
Maybe Int -> IO ()
forall a. Show a => a -> IO ()
print ([(Int, Int)] -> Maybe Int
part2 [(Int, Int)]
input)
collides ::
Int ->
Int ->
Bool
collides :: Int -> Int -> Bool
collides Int
i Int
x = Int
i Int -> Int -> Int
forall a. Integral a => a -> a -> a
`rem` ((Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
2) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
part1 :: Scanners -> Int
part1 :: [(Int, Int)] -> Int
part1 [(Int, Int)]
xs = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [ Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
x | (Int
i,Int
x) <- [(Int, Int)]
xs, Int -> Int -> Bool
collides Int
i Int
x ]
part2 :: Scanners -> Maybe Int
part2 :: [(Int, Int)] -> Maybe Int
part2 [(Int, Int)]
xs = (Int -> Bool) -> [Int] -> Maybe Int
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ([(Int, Int)] -> Int -> Bool
safeStart [(Int, Int)]
xs) [Int
0..Int
periodInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1]
where
period :: Int
period = (Int -> Int -> Int) -> Int -> [Int] -> Int
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Int -> Int -> Int
forall a. Integral a => a -> a -> a
lcm Int
1 [ (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
2 | (Int
_,Int
x) <- [(Int, Int)]
xs ]
safeStart :: Scanners -> Int -> Bool
safeStart :: [(Int, Int)] -> Int -> Bool
safeStart [(Int, Int)]
xs Int
off = Bool -> Bool
not (((Int, Int) -> Bool) -> [(Int, Int)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\(Int
i,Int
x) -> Int -> Int -> Bool
collides (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i) Int
x) [(Int, Int)]
xs)