summaryrefslogtreecommitdiff
path: root/day12/day12.hs
diff options
context:
space:
mode:
Diffstat (limited to 'day12/day12.hs')
-rw-r--r--day12/day12.hs81
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))