diff options
Diffstat (limited to 'day12/day12.hs')
-rw-r--r-- | day12/day12.hs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/day12/day12.hs b/day12/day12.hs new file mode 100644 index 0000000..cb35a0e --- /dev/null +++ b/day12/day12.hs @@ -0,0 +1,81 @@ +import Data.List +import Data.Maybe + +type Coo = (Int, Int) +type Region = (Plot, [Coo]) +type Plot = Char +type Grid = [[Plot]] + +(!?) :: Grid -> Coo -> Maybe Plot +grid !? (row, col) + | row < 0 = Nothing + | row >= length grid = Nothing + | col < 0 = Nothing + | col >= (length $ head grid) = Nothing + | otherwise = Just (grid !! row !! col) + +neighCoos :: Coo -> [Coo] +neighCoos (r,c) = + [(r-1, c), (r, c-1), (r, c+1), (r+1, c)] + +neighs :: Grid -> Plot -> Coo -> [Coo] +neighs grid p c = + mapMaybe match $ neighCoos c + where + match coo = if grid !? coo == Just p then Just coo else Nothing + +region :: Grid -> [Coo] -> [Coo] -> Region +region grid res@(h:_) [] = + (fromJust $ grid !? h, res) +region grid res (h:t) = + region grid (h:res) (t ++ filter f ns) + where + Just p = grid !? h + ns = neighs grid p h + f c = (not $ c `elem` res) && (not $ c `elem` t) + +consume1 :: Grid -> [Region] -> [Coo] -> [Region] +consume1 _ acc [] = + acc +consume1 grid acc (h:t) = + consume1 grid (r:acc) (t \\ cs) + where + r@(_,cs) = region grid [] [h] + +consume :: String -> [Region] +consume s = + consume1 grid [] allcoos + where + grid = lines s + allcoos = [(r, c) | r <- [0..((length grid) - 1)], c <- [0..((length $ head grid) - 1)]] + +area :: Region -> Int +area (_, cs) = + length cs + +perimeter1 :: Region -> Int -> [Coo] -> Int +perimeter1 _ s [] = + s +perimeter1 r@(_, cs) s (h:t) = + perimeter1 r (s + e) t + where + ncs = filter ((flip elem) cs) $ neighCoos h + e = 4 - (length ncs) + +perimeter :: Region -> Int +perimeter r@(_, cs) = + perimeter1 r 0 cs + +fenceCost :: Region -> Int +fenceCost r = + area r * perimeter r + +part1 :: [Region] -> Int +part1 = + sum . map fenceCost + +main = do + file <- readFile "day12.input" + let regions = consume file + putStrLn ("Part 1: " ++ (show $ part1 regions)) + --putStrLn ("Part 2: " ++ (show $ part2 regions)) |