-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDay04.hs
More file actions
42 lines (32 loc) · 1.47 KB
/
Day04.hs
File metadata and controls
42 lines (32 loc) · 1.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
module Day04 (task01, task02) where
import qualified Data.Set as Set
type Coord = (Int, Int)
task01 :: String -> String
task01 content =
let coord_set = Set.fromDistinctAscList $ extractCoords content
in show $ accessiblePaperRole coord_set
task02 :: String -> String
task02 content =
let coord_set = Set.fromDistinctAscList (extractCoords content)
in show $ recursiveAccessiblePaperRole coord_set
accessiblePaperRole :: Set.Set Coord -> Int
accessiblePaperRole coord_set = Set.size $ Set.filter (`isAccessible` coord_set) coord_set
recursiveAccessiblePaperRole :: Set.Set Coord -> Int
recursiveAccessiblePaperRole coord_set =
let new_coord_set = Set.filter (`isNotAccessible` coord_set) coord_set
accessible = Set.size coord_set - Set.size new_coord_set
in accessible + if accessible /= 0
then recursiveAccessiblePaperRole new_coord_set
else 0
isNotAccessible :: Coord -> Set.Set Coord -> Bool
isNotAccessible coord coords = not $ isAccessible coord coords
isAccessible :: Coord -> Set.Set Coord -> Bool
isAccessible coord coords = length filled_neighbors < 4
where neighbors = get8Neighbors coord
filled_neighbors = [x | x <- neighbors, Set.member x coords]
extractCoords :: String -> [Coord]
extractCoords content =
let rows = zip (lines content) [0..]
in [(i, j) | (row, i) <- rows, (c, j) <- zip row [0..], c == '@']
get8Neighbors :: Coord -> [Coord]
get8Neighbors (i, j) = [(i + di, j + dj) | di <- [-1, 0, 1], dj <- [-1, 0, 1], di /= 0 || dj /= 0]