{-# Language QuasiQuotes, ParallelListComp #-}
module Main (main) where
import Advent (counts, countBy, format)
main :: IO ()
IO ()
main =
do [(Int, Int, Int, Int)]
inp <- [format|2021 5 (%u,%u -> %u,%u%n)*|]
Int -> IO ()
forall a. Show a => a -> IO ()
print ([(Int, Int, Int, Int)] -> Int
solve (((Int, Int, Int, Int) -> Bool)
-> [(Int, Int, Int, Int)] -> [(Int, Int, Int, Int)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Int, Int, Int, Int) -> Bool
isStraight [(Int, Int, Int, Int)]
inp))
Int -> IO ()
forall a. Show a => a -> IO ()
print ([(Int, Int, Int, Int)] -> Int
solve [(Int, Int, Int, Int)]
inp)
solve :: [(Int, Int, Int, Int)] -> Int
solve :: [(Int, Int, Int, Int)] -> Int
solve = (Int -> Bool) -> Map (Int, Int) Int -> Int
forall (f :: * -> *) a. Foldable f => (a -> Bool) -> f a -> Int
countBy (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1) (Map (Int, Int) Int -> Int)
-> ([(Int, Int, Int, Int)] -> Map (Int, Int) Int)
-> [(Int, Int, Int, Int)]
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Int, Int)] -> Map (Int, Int) Int
forall (f :: * -> *) a. (Foldable f, Ord a) => f a -> Map a Int
counts ([(Int, Int)] -> Map (Int, Int) Int)
-> ([(Int, Int, Int, Int)] -> [(Int, Int)])
-> [(Int, Int, Int, Int)]
-> Map (Int, Int) Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Int, Int, Int) -> [(Int, Int)])
-> [(Int, Int, Int, Int)] -> [(Int, Int)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Int, Int, Int, Int) -> [(Int, Int)]
points
isStraight :: (Int, Int, Int, Int) -> Bool
isStraight :: (Int, Int, Int, Int) -> Bool
isStraight (Int
x1, Int
y1, Int
x2, Int
y2) = Int
x1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
x2 Bool -> Bool -> Bool
|| Int
y1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
y2
points :: (Int, Int, Int, Int) -> [(Int, Int)]
points :: (Int, Int, Int, Int) -> [(Int, Int)]
points (Int
x1, Int
y1, Int
x2, Int
y2)
| Int
x1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
x2 = [(Int
x1,Int
y) | Int
y <- Int -> Int -> [Int]
range Int
y1 Int
y2]
| Int
y1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
y2 = [(Int
x,Int
y1) | Int
x <- Int -> Int -> [Int]
range Int
x1 Int
x2]
| Bool
otherwise = [(Int
x,Int
y) | Int
x <- Int -> Int -> [Int]
range Int
x1 Int
x2 | Int
y <- Int -> Int -> [Int]
range Int
y1 Int
y2]
range :: Int -> Int -> [Int]
range :: Int -> Int -> [Int]
range Int
x Int
y
| Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
y = [Int
x .. Int
y]
| Bool
otherwise = [Int
x, Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1 .. Int
y]