Day 4
This commit is contained in:
parent
e9187a27db
commit
d3d933d2a9
1 changed files with 79 additions and 0 deletions
79
src/Day2504.hs
Normal file
79
src/Day2504.hs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
module Main where
|
||||
|
||||
import Debug.Trace (trace)
|
||||
|
||||
guard :: Bool -> [()]
|
||||
guard True = [()]
|
||||
guard False = []
|
||||
|
||||
gridMap :: (a -> b) -> [[a]] -> [[b]]
|
||||
gridMap f = map (map f)
|
||||
|
||||
gridMapWithIndex :: ((Int, Int) -> a -> b) -> [[a]] -> [[b]]
|
||||
gridMapWithIndex f grid = map (\(y, row) -> map (\(x, cell) -> (f (x,y) cell)) $ zip [0..] row) $ zip [0..] grid
|
||||
|
||||
--------------------
|
||||
----- Problems -----
|
||||
--------------------
|
||||
|
||||
isReachable :: [String] -> (Int, Int) -> Bool
|
||||
isReachable input (x,y) = let
|
||||
w = length (head input)
|
||||
h = length input
|
||||
in ((< (4+1)) . length) $ do
|
||||
dy <- [-1..1]
|
||||
dx <- [-1..1]
|
||||
|
||||
let ax = dx+x
|
||||
let ay = dy+y
|
||||
|
||||
guard $ (ax >= 0 && ax < w && ay >= 0 && ay < h)
|
||||
|
||||
guard $ (input!!(y+dy))!!(x+dx) == '@'
|
||||
|
||||
return ()
|
||||
|
||||
part1 :: String -> Int
|
||||
part1 str = length $ filter id a
|
||||
where
|
||||
w = length (head input)
|
||||
h = length input
|
||||
|
||||
input = lines str
|
||||
a = do
|
||||
y <- [0..w-1]
|
||||
x <- [0..h-1]
|
||||
|
||||
guard $ (input!!y)!!x == '@'
|
||||
|
||||
return $ isReachable input (x,y)
|
||||
|
||||
part2 :: String -> Int
|
||||
part2 str = go grid
|
||||
where
|
||||
grid = lines str
|
||||
w = length (head grid)
|
||||
h = length grid
|
||||
|
||||
countBoxes = length . filter id . concat . gridMap (\c -> if c=='@' then True else False)
|
||||
|
||||
go :: [[Char]] -> Int
|
||||
go grid | startCount == endCount = 0
|
||||
| otherwise = (startCount - endCount) + go end
|
||||
where
|
||||
startCount = countBoxes grid
|
||||
end = iter grid
|
||||
endCount = countBoxes end
|
||||
|
||||
iter :: [[Char]] -> [[Char]]
|
||||
iter input = gridMapWithIndex select input
|
||||
where
|
||||
select = \(x,y) c -> if c == '@' then if isReachable input (x,y) then '.' else '@' else c
|
||||
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
str <- getContents
|
||||
|
||||
print $ part1 str
|
||||
print $ part2 str
|
||||
Loading…
Add table
Add a link
Reference in a new issue