{-# Language QuasiQuotes, LambdaCase, TemplateHaskell #-}
module Main (main) where
import Advent (format, stageTH, partialSums)
import Advent.Coord (Coord(..), east, north, south, west, scaleCoord, norm1)
import Data.List (tails)
data D = DD | DU | DR | DL
stageTH
main :: IO ()
IO ()
main =
do input <- [format|2023 18 (@D %d %(#%x%)%n)*|]
print (area [scaleCoord n (asUnitVec d) | (d,n,_) <- input])
print (area [scaleCoord n ([east, south, west, north] !! d) | (_,_,x) <- input, let (n,d) = x `quotRem` 16])
area :: [Coord] -> Int
area :: [Coord] -> Int
area [Coord]
input = Int -> Int
forall a. Num a => a -> a
abs ([Coord] -> Int
polyareaRect [Coord]
path) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
perimeter Int -> Int -> Int
forall a. Integral a => a -> a -> a
`quot` Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
where
path :: [Coord]
path = [Coord] -> [Coord]
forall a. Num a => [a] -> [a]
partialSums [Coord]
input
perimeter :: Int
perimeter = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ((Coord -> Int) -> [Coord] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Coord -> Int
norm1 [Coord]
input)
asUnitVec :: D -> Coord
asUnitVec :: D -> Coord
asUnitVec = \case
D
DR -> Coord
east
D
DD -> Coord
south
D
DL -> Coord
west
D
DU -> Coord
north
polyareaRect :: [Coord] -> Int
polyareaRect :: [Coord] -> Int
polyareaRect [Coord]
xs = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int
x1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
y2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
x2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
y1 | C Int
y1 Int
x1 : C Int
y2 Int
x2 : [Coord]
_ <- [Coord] -> [[Coord]]
forall a. [a] -> [[a]]
tails [Coord]
xs] Int -> Int -> Int
forall a. Integral a => a -> a -> a
`quot` Int
2