{-# Language QuasiQuotes #-}
module Main (main) where
import Advent.Format (format)
import Control.Monad (when)
data Probe = P !Int !Int !Int !Int
deriving Int -> Probe -> ShowS
[Probe] -> ShowS
Probe -> String
(Int -> Probe -> ShowS)
-> (Probe -> String) -> ([Probe] -> ShowS) -> Show Probe
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Probe -> ShowS
showsPrec :: Int -> Probe -> ShowS
$cshow :: Probe -> String
show :: Probe -> String
$cshowList :: [Probe] -> ShowS
showList :: [Probe] -> ShowS
Show
step :: Probe -> Probe
step :: Probe -> Probe
step (P Int
x Int
y Int
vx Int
vy) = Int -> Int -> Int -> Int -> Probe
P (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
vx) (Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
vy) (Int
vxInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int -> Int
forall a. Num a => a -> a
signum Int
vx) (Int
vyInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
main :: IO ()
IO ()
main =
do (xlo,xhi,ylo,yhi) <- [format|2021 17 target area: x=%d..%d, y=%d..%d%n|]
when (xlo < 0 || yhi > 0) (fail "I didn't do enough math for this case")
let ys = [Int
y | Int
vx <- [Int
0 .. Int
xhi], Int
vy <- [Int
ylo .. -Int
ylo], Just Int
y <- [Int -> Int -> Int -> Int -> Int -> Int -> Maybe Int
sim Int
xlo Int
xhi Int
ylo Int
yhi Int
vx Int
vy]]
print (maximum ys)
print (length ys)
sim ::
Int ->
Int ->
Int ->
Int ->
Int ->
Int ->
Maybe Int
sim :: Int -> Int -> Int -> Int -> Int -> Int -> Maybe Int
sim Int
xlo Int
xhi Int
ylo Int
yhi Int
vx0 Int
vy0 = Int -> Probe -> Maybe Int
go Int
0 (Int -> Int -> Int -> Int -> Probe
P Int
0 Int
0 Int
vx0 Int
vy0)
where
go :: Int -> Probe -> Maybe Int
go Int
best p :: Probe
p@(P Int
x Int
y Int
_ Int
_)
| Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
ylo Bool -> Bool -> Bool
|| Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
xhi = Maybe Int
forall a. Maybe a
Nothing
| Int
xlo Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
x, Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
xhi, Int
ylo Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
y, Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
yhi = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
best
| Bool
otherwise = Int -> Probe -> Maybe Int
go (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
y Int
best) (Probe -> Probe
step Probe
p)