Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
2024-12-06 22:04:56 +05:30
parent 22acd853d8
commit d5fae9fbef
2 changed files with 85 additions and 0 deletions

View File

@@ -59,3 +59,11 @@ executable day5
build-depends: build-depends:
, containers , containers
, libaoc , libaoc
executable day6
import: common
hs-source-dirs: src
main-is: Day6.hs
build-depends:
, containers
, libaoc

77
src/Day6.hs Normal file
View File

@@ -0,0 +1,77 @@
module Main where
import qualified Data.Set as S
type Grid = [[Char]]
type Dimensions = (Int, Int)
type Coord = (Int, Int)
data Dir = North | East | South | West deriving (Ord, Eq, Show)
type State = (Coord, Dir)
next :: Dir -> Coord -> Coord
next North (x, y) = (x, y - 1)
next East (x, y) = (x + 1, y)
next South (x, y) = (x, y + 1)
next West (x, y) = (x - 1, y)
rotate :: Dir -> Dir
rotate North = East
rotate East = South
rotate South = West
rotate West = North
getPath :: S.Set Coord -> Dimensions -> Coord -> S.Set Coord
getPath obs (m, n) start = go S.empty start North
where
oob :: Coord -> Bool
oob (x, y) = x < 0 || y < 0 || x >= m || y >= n
go :: S.Set Coord -> Coord -> Dir -> S.Set Coord
go path c d
| oob n = S.insert c path
| n `S.member` obs = go path c (rotate d)
| otherwise = go (S.insert c path) n d
where
n = next d c
isLoop :: S.Set Coord -> Dimensions -> Coord -> Bool
isLoop obs (m, n) start = go S.empty start North
where
oob :: Coord -> Bool
oob (x, y) = x < 0 || y < 0 || x >= m || y >= n
go :: S.Set State -> Coord -> Dir -> Bool
go states c d
| oob n = False
| (c, d) `S.member` states = True
| n `S.member` obs = go states c (rotate d)
| otherwise = go (S.insert (c, d) states) n d
where
n = next d c
main :: IO ()
main =
do
grid <- lines <$> readFile "./inputs/day6.in"
let m = length grid
n = length $ head grid
let grid' = [((x, y), ch) | (y, row) <- zip [0 ..] grid, (x, ch) <- zip [0 ..] row]
obstacles = S.fromList [coord | (coord, ch) <- grid', ch == '#']
start = head [coord | (coord, ch) <- grid', ch == '^']
path = getPath obstacles (m, n) start
let part1 = S.size path
part2 =
S.size $
S.filter
(\p -> isLoop (S.insert p obstacles) (m, n) start)
(S.delete start path)
putStr "Part 1: " >> print part1
putStr "Part 2: " >> print part2