Day 5
This commit is contained in:
@@ -36,3 +36,11 @@ executable day04
|
|||||||
build-depends: base ^>=4.15.1.0, MissingH
|
build-depends: base ^>=4.15.1.0, MissingH
|
||||||
hs-source-dirs: day04
|
hs-source-dirs: day04
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
|
executable day05
|
||||||
|
main-is: Main.hs
|
||||||
|
other-modules: Commons Part1 Part2
|
||||||
|
|
||||||
|
build-depends: base ^>=4.15.1.0, MissingH
|
||||||
|
hs-source-dirs: day05
|
||||||
|
default-language: Haskell2010
|
||||||
|
|||||||
55
day05/Commons.hs
Normal file
55
day05/Commons.hs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
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}
|
||||||
12
day05/Main.hs
Normal file
12
day05/Main.hs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
module Main where
|
||||||
|
|
||||||
|
import Commons
|
||||||
|
import qualified Part1
|
||||||
|
import qualified Part2
|
||||||
|
|
||||||
|
|
||||||
|
main = do almanac <- parse
|
||||||
|
let part1Res = minimum $ Part1.getLocations almanac
|
||||||
|
print part1Res
|
||||||
|
let part2Res = minimum $ Part2.getLocationsStarts almanac
|
||||||
|
print part2Res
|
||||||
18
day05/Part1.hs
Normal file
18
day05/Part1.hs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
module Part1 where
|
||||||
|
|
||||||
|
import Commons
|
||||||
|
|
||||||
|
|
||||||
|
applyConversionMap :: ConversionMap -> Int -> Int
|
||||||
|
applyConversionMap [] v = v
|
||||||
|
applyConversionMap (e: t) v | v >= sourceStart e && v <= sourceStart e + size e = destinationStart e - sourceStart e + v
|
||||||
|
| otherwise = applyConversionMap t v
|
||||||
|
|
||||||
|
applyConversionMapToList :: ConversionMap -> [Int] -> [Int]
|
||||||
|
applyConversionMapToList cm = map $ applyConversionMap cm
|
||||||
|
|
||||||
|
getLocations :: Almanac -> [Int]
|
||||||
|
getLocations a = applyConversionMapToList (toLocation a) . applyConversionMapToList (toHumidity a)
|
||||||
|
. applyConversionMapToList (toTemperature a) . applyConversionMapToList (toLight a)
|
||||||
|
. applyConversionMapToList (toWater a) . applyConversionMapToList (toFertilizer a)
|
||||||
|
. applyConversionMapToList (toSoil a) $ seeds a
|
||||||
33
day05/Part2.hs
Normal file
33
day05/Part2.hs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
module Part2 where
|
||||||
|
|
||||||
|
import Commons
|
||||||
|
|
||||||
|
|
||||||
|
applyConversionMap :: ConversionMap -> Int -> Int -> [Int]
|
||||||
|
applyConversionMap [] v vs = [v, vs]
|
||||||
|
applyConversionMap _ _ 0 = []
|
||||||
|
applyConversionMap (e: t) v vs
|
||||||
|
| v >= sourceStart e && v <= sourceStart e + size e =
|
||||||
|
let newVs = min (sourceStart e + size e) (v + vs) - v
|
||||||
|
in (destinationStart e - sourceStart e + v): newVs: applyConversionMap t (v + newVs) (vs - newVs)
|
||||||
|
| v < sourceStart e && v + vs >= sourceStart e =
|
||||||
|
let newVs = v + vs - sourceStart e
|
||||||
|
in applyConversionMap (e: t) (sourceStart e) newVs ++ applyConversionMap t v (vs - newVs)
|
||||||
|
| otherwise = applyConversionMap t v vs
|
||||||
|
|
||||||
|
applyConversionMapToList :: ConversionMap -> [Int] -> [Int]
|
||||||
|
applyConversionMapToList cm [] = []
|
||||||
|
applyConversionMapToList cm (v: vs: t) = applyConversionMap cm v vs ++ applyConversionMapToList cm t
|
||||||
|
|
||||||
|
getLocations :: Almanac -> [Int]
|
||||||
|
getLocations a = applyConversionMapToList (toLocation a) . applyConversionMapToList (toHumidity a)
|
||||||
|
. applyConversionMapToList (toTemperature a) . applyConversionMapToList (toLight a)
|
||||||
|
. applyConversionMapToList (toWater a) . applyConversionMapToList (toFertilizer a)
|
||||||
|
. applyConversionMapToList (toSoil a) $ seeds a
|
||||||
|
|
||||||
|
dropLocationsSizes :: [Int] -> [Int]
|
||||||
|
dropLocationsSizes [] = []
|
||||||
|
dropLocationsSizes (start: size: t) = start: dropLocationsSizes t
|
||||||
|
|
||||||
|
getLocationsStarts :: Almanac -> [Int]
|
||||||
|
getLocationsStarts = dropLocationsSizes . getLocations
|
||||||
Reference in New Issue
Block a user