@@ -6,7 +6,7 @@ main = interact $ (++ "\n") . show . ((,) <$> p1 <*> p2) . parseAlmanac
6
6
7
7
data Almanac = Almanac { seeds :: [Int ], maps :: [Map ] }
8
8
type Map = [RangeMapping ]
9
- data RangeMapping = RangeMapping { from :: Range , to :: Range }
9
+ data RangeMapping = RangeMapping { from :: Int , to :: Int , rlen :: Int }
10
10
data Range = Range { start :: Int , len :: Int }
11
11
12
12
parseAlmanac :: String -> Almanac
@@ -20,11 +20,10 @@ parseAlmanac s = case parse almanac "" s of
20
20
seeds = string " seeds: " *> nums <* count 2 newline
21
21
mapHeader = many1 (letter <|> char ' -' <|> sp) >> char ' :'
22
22
endOfLineOrFile = void endOfLine <|> eof
23
- rangeMapping = mkRangeMapping <$> (num <* sp) <*> (num <* sp) <*> num
23
+ rangeMapping = flip RangeMapping <$> (num <* sp) <*> (num <* sp) <*> num
24
24
map = mapHeader *> newline *> (rangeMapping `endBy` endOfLineOrFile)
25
25
maps = map `endBy` endOfLineOrFile
26
26
almanac = Almanac <$> seeds <*> maps
27
- mkRangeMapping a b c = RangeMapping (Range b c) (Range a c)
28
27
29
28
p1 , p2 :: Almanac -> Int
30
29
p1 Almanac { seeds, maps } = solve (map (`Range ` 1 ) seeds) maps
@@ -44,14 +43,14 @@ transformRanges rs m = concatMap (`transformRange` m) rs
44
43
-- may cause the range to split.
45
44
transformRange :: Range -> [RangeMapping ] -> [Range ]
46
45
transformRange r [] = [r]
47
- transformRange r (rm: rms) = concatMap transform (intersections r (from rm) )
46
+ transformRange r (rm: rms) = concatMap transform (intersections r rm )
48
47
where transform x = case mapRange rm x of
49
48
Nothing -> transformRange x rms
50
49
Just y -> [y]
51
50
52
51
-- Not necessarily symmetric.
53
- intersections :: Range -> Range -> [Range ]
54
- intersections r@ Range { start = s, len = n } r' @ Range { start = s', len = n' }
52
+ intersections :: Range -> RangeMapping -> [Range ]
53
+ intersections r@ Range { start = s, len = n } RangeMapping { from = s', rlen = n' }
55
54
| s > e' = [r]
56
55
| e < s' = [r]
57
56
| s < s' = mk s (s' - 1 ) : if e <= e' then [mk s' e] else [mk s' e', mk (e' + 1 ) e]
@@ -64,9 +63,9 @@ intersections r@Range { start = s, len = n } r'@Range { start = s', len = n' }
64
63
-- boundaries of the 'from' range mapping (i.e. either it falls completely
65
64
-- within, or is completely outside).
66
65
mapRange :: RangeMapping -> Range -> Maybe Range
67
- mapRange RangeMapping { from, to } r@ Range { start = s , len = n }
68
- | inRange from s = Just $ Range (s - start from + start to) n
66
+ mapRange rm @ RangeMapping { from, to, rlen } r@ Range { start, len }
67
+ | within rm start = Just $ Range (start - from + to) len
69
68
| otherwise = Nothing
70
69
71
- inRange :: Range -> Int -> Bool
72
- inRange r i = i >= start r && i <= (start r + len r)
70
+ within :: RangeMapping -> Int -> Bool
71
+ within RangeMapping { from, rlen } i = i >= from && i <= from + rlen
0 commit comments