@@ -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 :: Int , to :: Int , rlen :: Int }
9
+ data RangeMapping = RangeMapping { from :: Int , to :: Int , rmLen :: Int }
10
10
data Range = Range { start :: Int , len :: Int }
11
11
12
12
parseAlmanac :: String -> Almanac
@@ -44,28 +44,18 @@ transformRanges rs m = concatMap (`transformRange` m) rs
44
44
transformRange :: Range -> [RangeMapping ] -> [Range ]
45
45
transformRange r [] = [r]
46
46
transformRange r (rm: rms) = concatMap transform (intersections r rm)
47
- where transform x = case mapRange rm x of
48
- Nothing -> transformRange x rms
49
- Just y -> [y]
47
+ where transform x | within rm (start x) = [apply rm x]
48
+ | otherwise = transformRange x rms
49
+ within RangeMapping { from, rmLen = n } i = i >= from && i <= from + n
50
+ apply RangeMapping { from, to } r = Range (start r - from + to) (len r)
50
51
51
52
-- Not necessarily symmetric.
52
53
intersections :: Range -> RangeMapping -> [Range ]
53
- intersections r@ Range { start = s, len = n } RangeMapping { from = s', rlen = n' }
54
+ intersections r@ Range { start = s, len } RangeMapping { from = s', rmLen }
54
55
| s > e' = [r]
55
56
| e < s' = [r]
56
57
| s < s' = mk s (s' - 1 ) : if e <= e' then [mk s' e] else [mk s' e', mk (e' + 1 ) e]
57
58
| s <= e' = if e <= e' then [mk s e] else [mk s e', mk (e' + 1 ) e]
58
- where e = s + n
59
- e' = s' + n'
59
+ where e = s + len
60
+ e' = s' + rmLen
60
61
mk rs re = Range rs (re - rs)
61
-
62
- -- This is guaranteed to be called with a range that does not cross over the
63
- -- boundaries of the 'from' range mapping (i.e. either it falls completely
64
- -- within, or is completely outside).
65
- mapRange :: RangeMapping -> Range -> Maybe Range
66
- mapRange rm@ RangeMapping { from, to, rlen } r@ Range { start, len }
67
- | within rm start = Just $ Range (start - from + to) len
68
- | otherwise = Nothing
69
-
70
- within :: RangeMapping -> Int -> Bool
71
- within RangeMapping { from, rlen } i = i >= from && i <= from + rlen
0 commit comments