-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay5.hs
58 lines (48 loc) · 1.59 KB
/
Day5.hs
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
module Day5
( part1
, part2
) where
import Data.ByteString (ByteString)
import Data.List (minimumBy)
import Data.List.Split (chunksOf, splitWhen)
import Helpers.Parsers.ByteString (signedInts)
--parseInput :: [String] -> ([Int], Int -> Int)
--parseInput i = (map read . getNumbers . head $ i, getMaps i)
parseInput :: ByteString -> ([Int], Int -> Int)
parseInput s = (head parsed, getMaps . drop 2 $ parsed)
where
parsed = signedInts s
getMaps :: [[Int]] -> (Int -> Int)
getMaps = process . map (gardenMap . map truple) . splitWhen null
truple :: [Int] -> (Int, Int, Int)
truple [a, b, c] = (a, b, c)
gardenMap :: [(Int, Int, Int)] -> Int -> Int
gardenMap [] x = x
gardenMap ((d, s, l):rs) x
| x >= s && x - s < l = d + x - s
| otherwise = gardenMap rs x
ranges :: [Int] -> [(Int, Int)]
ranges [] = []
ranges (a:b:c) = (a, a + b - 1) : ranges c
continuityRanges :: (Int -> Int) -> (Int, Int) -> [(Int, Int)]
continuityRanges f (a, b)
| f b - f a == b - a = [(a, b)]
| otherwise = continuityRanges f (a, c) ++ continuityRanges f (c + 1, b)
where
c = a + div (b - a) 2
process :: [Int -> Int] -> Int -> Int
process fl x = foldl (\x f -> f x) x fl
part1 :: Bool -> ByteString -> String
part1 _ input = show . minimum . map mapping $ seeds
where
(seeds, mapping) = parseInput input
part2 :: Bool -> ByteString -> String
part2 _ input =
show
. minimum
. map (\(a, _) -> mapping a)
. concatMap (continuityRanges mapping)
. ranges
$ seeds
where
(seeds, mapping) = parseInput input