diff options
author | tzlil <tzlils@protonmail.com> | 2023-12-15 19:34:05 +0200 |
---|---|---|
committer | tzlil <tzlils@protonmail.com> | 2023-12-15 19:34:05 +0200 |
commit | 3dda0ec7cb4477259a1be52565fe27e0312b9d3b (patch) | |
tree | 99e9d7f9525369d68edf0d02224b5fb6bbd33a46 /5/1.hs | |
parent | 1fd224e40011ee0a63aa7955fe79b616a4dfa6dd (diff) |
wip 5
Diffstat (limited to '5/1.hs')
-rw-r--r-- | 5/1.hs | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/5/1.hs b/5/1.hs new file mode 100644 index 0000000..cdc583a --- /dev/null +++ b/5/1.hs @@ -0,0 +1,38 @@ +import Text.Parsec.String (Parser) +import Text.Parsec +import System.Environment +import Control.Monad +import Debug.Trace +import qualified Data.Map as M + +num :: Parser Int +num = read <$> many1 digit + +seeds :: Parser [Int] +seeds = string "seeds: " *> many1 (read <$> many1 digit <* space) <* newline + +almanacTitle = (,) <$> many1 (noneOf "-") <* string "-to-" <*> many1 (noneOf " ") <* string " map:" + +mapLine = (,,) <$> num <* space <*> num <* space <*> num + +almanacMap :: Parser ([(Int,Int,Int)]) +almanacMap = almanacTitle *> newline *> sepEndBy mapLine newline + +almanac = (,) <$> seeds <*> sepEndBy1 almanacMap newline + +buildRange :: (Int,Int,Int) -> M.Map Int Int +buildRange (dst,src,len) = M.fromList $ zip [src..src+len-1] [dst..dst+len-1] + +sectionMap :: [(Int,Int,Int)] -> M.Map Int Int +sectionMap xs = M.unionsWith (const id) $ (M.fromList $ zip [0..99] [0..99]):map buildRange xs + +locations :: ([Int], [[(Int,Int,Int)]]) -> [Int] +locations (seeds,sections) = do + let maps = map sectionMap sections + seed <- seeds + let location = foldr (M.!) seed (reverse maps) + return location + +solution = minimum . locations + +main = (>>=) <$> readFile <*> ((print . solution . either (error.show) id) .) . parse almanac =<< head <$> getArgs |