module Commons where import Data.List.Utils (split) import GHC.IO.Handle (isEOF) data ConversionEntry = ConversionEntry { sourceStart :: Int, destinationStart :: Int, size :: Int } deriving Show type ConversionMap = [ConversionEntry] data Almanac = Almanac { seeds :: [Int], toSoil :: ConversionMap, toFertilizer :: ConversionMap, toWater :: ConversionMap, toLight :: ConversionMap, toTemperature :: ConversionMap, toHumidity :: ConversionMap, toLocation :: ConversionMap } deriving Show parseSeeds :: [String] -> [Int] parseSeeds = map read parseSeedsRaw :: IO [Int] parseSeedsRaw = do line <- getLine getLine let seeds = parseSeeds $ tail $ split " " line return seeds parseConversionEntry :: [String] -> ConversionEntry parseConversionEntry (ds: ss: size: _) = ConversionEntry {sourceStart = read ss, destinationStart = read ds, size = read size} parseConversionMapRaw :: IO ConversionMap parseConversionMapRaw = do done <- isEOF if done then return [] else do line <- getLine case line of [] -> do return [] _ -> do let eMap = parseConversionEntry $ split " " line othersEMap <- parseConversionMapRaw return $ eMap: othersEMap parse :: IO Almanac parse = do seeds <- parseSeedsRaw getLine toSoil <- parseConversionMapRaw getLine toFertilizer <- parseConversionMapRaw getLine toWater <- parseConversionMapRaw getLine toLight <- parseConversionMapRaw getLine toTemperature <- parseConversionMapRaw getLine toHumidity <- parseConversionMapRaw getLine toLocation <- parseConversionMapRaw return Almanac {seeds = seeds, toSoil = toSoil, toFertilizer = toFertilizer, toWater = toWater, toLight = toLight, toTemperature = toTemperature, toHumidity = toHumidity, toLocation = toLocation}