import Control.Arrow import Data.Ix import Data.List.Split type SeedMap = [((Int, Int), Int)] main :: IO () main = do input <- map (map words . lines) . splitOn "\n\n" <$> readFile "input" let (seeds, maps) = parse input print $ day5a maps seeds print $ day5a maps (pairwise seeds) parse :: [[[String]]] -> ([Int], [SeedMap]) parse = parseSeeds &&& map parseMap . tail where parseSeeds = map read . tail . head . head parseMap :: [[String]] -> SeedMap parseMap = map (f . map read) . tail where f [x, y, z] = ((y, y + pred z), x - y) applyMap :: Int -> SeedMap -> Int applyMap x m = if null filtered then x else x + snd (head filtered) where filtered = filter ((`inRange` x) . fst) m day5a :: [SeedMap] -> [Int] -> Int day5a maps = minimum . map f where f x = foldl applyMap x maps pairwise :: [Int] -> [Int] pairwise [] = [] pairwise (x:y:xs) = take y [x ..] ++ pairwise xs pairwise _ = error "List length must be even"