{-# Language QuasiQuotes #-}
module Main (main) where
import Advent (format, binSearchLargest)
main :: IO ()
IO ()
main =
do (times, distances) <- [format|2023 6 Time:( +%d!)*%nDistance:( +%d!)*%n|]
let input1 = [Int] -> [Int] -> [(Int, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip (((String, Int) -> Int) -> [(String, Int)] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (String, Int) -> Int
forall a b. (a, b) -> b
snd [(String, Int)]
times) (((String, Int) -> Int) -> [(String, Int)] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (String, Int) -> Int
forall a b. (a, b) -> b
snd [(String, Int)]
distances)
input2 = (String -> Int
forall a. Read a => String -> a
read (((String, Int) -> String) -> [(String, Int)] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String, Int) -> String
forall a b. (a, b) -> a
fst [(String, Int)]
times), String -> Int
forall a. Read a => String -> a
read (((String, Int) -> String) -> [(String, Int)] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String, Int) -> String
forall a b. (a, b) -> a
fst [(String, Int)]
distances))
print (product (map ways input1))
print (ways input2)
ways :: (Int, Int) -> Int
ways :: (Int, Int) -> Int
ways (Int
t, Int
d)
| Int -> Bool
valid Int
mid = Int
hi Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
tooLo
| Bool
otherwise = Int
0
where
valid :: Int -> Bool
valid Int
hold = (Int
t Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
hold) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
hold Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
d
mid :: Int
mid = Int
t Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2
tooLo :: Int
tooLo = (Int -> Bool) -> Int -> Int -> Int
binSearchLargest (Bool -> Bool
not (Bool -> Bool) -> (Int -> Bool) -> Int -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Bool
valid) Int
0 Int
mid
hi :: Int
hi = (Int -> Bool) -> Int -> Int -> Int
binSearchLargest Int -> Bool
valid Int
mid Int
t