1
1
module Day10 (partOne , partTwo ) where
2
2
3
3
import Data.Char (digitToInt )
4
- import Data.List (intersect )
4
+ import Data.List (nub )
5
5
import Data.Matrix (Matrix )
6
6
import qualified Data.Matrix as M
7
7
import Data.Point (Point )
8
8
9
9
partOne :: String -> Int
10
- partOne input = length $ filter (( > 0 ) . uncurry (rating matrix)) candidates
10
+ partOne input = sum $ map ( length . nub . trailEnds matrix) heads
11
11
where
12
12
matrix = parseMatrix input
13
- candidates = possibleTrails matrix
13
+ heads = trailHeads matrix
14
14
15
15
partTwo :: String -> Int
16
- partTwo input = sum $ map (uncurry (rating matrix)) candidates
16
+ partTwo input = sum $ map (length . trailEnds matrix) heads
17
17
where
18
18
matrix = parseMatrix input
19
- candidates = possibleTrails matrix
19
+ heads = trailHeads matrix
20
20
21
- rating :: Matrix Int -> Point -> Point -> Int
22
- rating matrix x y = go (getCandidates 1 x) [y] 1
21
+ trailHeads :: Matrix Int -> [Point ]
22
+ trailHeads matrix = M. points $ M. filter (== 0 ) matrix
23
+
24
+ parseMatrix :: String -> Matrix Int
25
+ parseMatrix = M. buildMatrix . map (map digitToInt) . lines
26
+
27
+ trailEnds :: Matrix Int -> Point -> [Point ]
28
+ trailEnds matrix x = go [x] 0
23
29
where
24
- go :: [Point ] -> [Point ] -> Int -> Int
25
- go leftFront rightFront step
26
- | step > 5 = 0
27
- | step < 5 =
28
- let leftFront' = concatMap (getCandidates (1 + step)) leftFront
29
- rightFront' = concatMap (getCandidates (9 - step)) rightFront
30
- in go leftFront' rightFront' (step + 1 )
31
- | otherwise =
32
- let intersectionA = intersect leftFront rightFront
33
- intersectionB = intersect rightFront leftFront
34
- intersection = if length intersectionA > length intersectionB then intersectionA else intersectionB
35
- in length intersection
30
+ go :: [Point ] -> Int -> [Point ]
31
+ go [] _ = []
32
+ go front step
33
+ | step < 9 =
34
+ let front' = concatMap (getCandidates (1 + step)) front
35
+ in go front' (step + 1 )
36
+ | otherwise = front
36
37
37
38
getCandidates :: Int -> Point -> [Point ]
38
39
getCandidates value (row, col) =
@@ -45,12 +46,3 @@ rating matrix x y = go (getCandidates 1 x) [y] 1
45
46
Just v -> v == value
46
47
)
47
48
$ zip positions values
48
-
49
- possibleTrails :: Matrix Int -> [(Point , Point )]
50
- possibleTrails matrix =
51
- let trailHeads = M. points $ M. filter (== 0 ) matrix
52
- trailEnds = M. points $ M. filter (== 9 ) matrix
53
- in concatMap (zip trailHeads . repeat ) trailEnds
54
-
55
- parseMatrix :: String -> Matrix Int
56
- parseMatrix = M. buildMatrix . map (map digitToInt) . lines
0 commit comments