-
Notifications
You must be signed in to change notification settings - Fork 0
/
17b.hs
49 lines (42 loc) · 1.38 KB
/
17b.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE DeriveFoldable #-}
import AOC
import Debug.Trace
import Data.Either
import qualified Prelude as P
main :: IO ()
main = interact' $ run . fromRight (error "Parse error") . parse p
p :: Parser ((Int,Int), (Int,Int))
p = do
string "target area: x="
xMin <- integer
string ".."
xMax <- integer
string ", y="
yMin <- read <$> (do
i <- char '-' <|> digit
rest <- many digit
pure $ i: rest)
string ".."
yMax <- read <$> (do
i <- char '-' <|> digit
rest <- many digit
pure $ i: rest)
pure ((xMin,xMax), (yMin, yMax))
step :: ((Int,Int),(Int,Int)) -> ((Int,Int), (Int,Int))
step ((x,y), (vx,vy)) = ((x+vx, y+vy), (decrease vx, vy - 1))
where
decrease vx = if vx == 0 then 0 else vx -1
isInTarget :: ((Int,Int), (Int,Int)) -> ((Int,Int), (Int,Int)) -> Bool
isInTarget ((xMin, xMax), (yMin, yMax)) ((x,y), _) = x >= xMin && x <= xMax && y >= yMin && y <= yMax
hits m@((xMin,xMax), (yMin,yMax)) = do
(vx, vy) <- [(vx,vy) | vx <- [0..xMax], vy <- [yMin.. (vx * (vx +1) `div` 2)]]
let steps = takeWhile (\((x,y), _) -> x <= xMax && y >= yMin - abs vy) $ iterate step ((0,0), (vx, vy))
guard $ any (isInTarget m) steps
pure (vx, vy)
run x = length $ hits x