diff options
| author | Shivesh Mandalia <mail@shivesh.org> | 2023-02-05 21:16:44 +0000 |
|---|---|---|
| committer | Shivesh Mandalia <mail@shivesh.org> | 2023-02-05 21:16:44 +0000 |
| commit | 8b88150f788aae5e7d5ab53f8d6a2a253a4a6b5b (patch) | |
| tree | 8a079a45d837a9d4f4bcbfa23bad33e75812b8ff | |
| parent | 4cb3fa6de434d287bb46ca94c3026880164cb774 (diff) | |
| download | AOC_2022_haskell-master.tar.gz AOC_2022_haskell-master.zip | |
| -rw-r--r-- | day05/app/Main.hs | 41 | ||||
| -rw-r--r-- | day07/app/Main.hs | 28 |
2 files changed, 53 insertions, 16 deletions
diff --git a/day05/app/Main.hs b/day05/app/Main.hs index b56e45b..f22ed5a 100644 --- a/day05/app/Main.hs +++ b/day05/app/Main.hs @@ -145,6 +145,8 @@ module Main (main) where import Data.ByteString.Lazy (ByteString) import Data.Char (digitToInt) +import Data.List (filter) +import Data.Sequence (fromList, index, splitAt, update, (><)) import Options.Applicative (Parser, ParserInfo, argument, execParser, fullDesc, help, helper, info, metavar, str) import Relude hiding (ByteString, elem, empty, filter, fromList, length, null, optional, readFile, splitAt) import Text.Parsec (ParseError, parse, (<?>)) @@ -157,7 +159,7 @@ type Opts :: Type newtype Opts = Opts {_filename :: Text} deriving stock (Show) type Supplies :: Type -newtype Supplies = Supplies {_i :: [[Char]]} deriving stock (Show) +newtype Supplies = Supplies {_i :: Seq (Seq Char)} deriving stock (Show) type Order :: Type data Order = Order {_amount :: Int, _from :: Int, _to :: Int} deriving stock (Show) @@ -166,7 +168,7 @@ parseInput :: FilePath -> ByteString -> Either ParseError (Supplies, [Order]) parseInput = parse $ (,) <$> (supplies <* eol) <*> orders where supplies :: GenParser t st Supplies - supplies = Supplies <$> many1 (lineBlock <* eol) <* axis + supplies = (Supplies . fromList . map (fromList . filter (/= ' '))) . transpose <$> many1 (lineBlock <* eol) <* axis lineBlock :: GenParser t st [Char] lineBlock = block `sepBy1` space @@ -207,11 +209,38 @@ parseInput = parse $ (,) <$> (supplies <* eol) <*> orders <?> "end of line" ) -runPart1 :: (Supplies, [Order]) -> (Supplies, [Order]) -runPart1 x = x +move :: Int -> Int -> Int -> Supplies -> Supplies +move f t n s = Supplies $ update tp1 (fst moveElements >< toStack) (update fp1 (snd moveElements) (_i s)) + where + moveElements :: (Seq Char, Seq Char) + moveElements = splitAt n fromStack + + fromStack :: Seq Char + fromStack = index (_i s) fp1 + + toStack :: Seq Char + toStack = index (_i s) tp1 + + tp1 :: Int + tp1 = t - 1 + + fp1 :: Int + fp1 = f - 1 -runPart2 :: (Supplies, [Order]) -> Int -runPart2 = undefined +runPart1 :: (Supplies, [Order]) -> [Char] +runPart1 (sup, ors) = toList $ fmap (`index` 0) (_i run) + where + run :: Supplies + run = foldl' (\s o -> loop (_amount o) (move (_from o) (_to o) 1) s) sup ors + + loop :: Int -> (Supplies -> Supplies) -> Supplies -> Supplies + loop n f s = foldl' (\s' _ -> f s') s [1 .. n] + +runPart2 :: (Supplies, [Order]) -> [Char] +runPart2 (sup, ors) = toList $ fmap (`index` 0) (_i run) + where + run :: Supplies + run = foldl' (\s o -> move (_from o) (_to o) (_amount o) s) sup ors main :: IO () main = do diff --git a/day07/app/Main.hs b/day07/app/Main.hs index 413fcca..223f7f7 100644 --- a/day07/app/Main.hs +++ b/day07/app/Main.hs @@ -121,6 +121,9 @@ Find the smallest directory that, if deleted, would free up enough space on the run the update. What is the total size of that directory? -} {-# LANGUAGE DerivingStrategies #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} + +{-# HLINT ignore "Use 'foldl'' from Relude" #-} module Main (main) where @@ -154,12 +157,19 @@ data SystemEntry a = File a | Directory Text [SystemEntry a] deriving stock (Sho root :: SystemEntry FileData root = Directory "/" [] -foldrEntry :: Monoid b => (a -> b -> b) -> b -> SystemEntry a -> b -foldrEntry f b (File fd) = f fd b -foldrEntry f b (Directory _ xs) = mconcat $ fmap (foldrEntry f b) xs +foldrFile :: Monoid b => (a -> b -> b) -> b -> SystemEntry a -> b +foldrFile f b (File fd) = f fd b +foldrFile f b (Directory _ xs) = mconcat $ fmap (foldrFile f b) xs + +foldrDirectory :: Monoid b => (a -> b -> b) -> b -> SystemEntry a -> [b] +foldrDirectory _ _ (File _) = [] +foldrDirectory f b (Directory n xs) = b' : concatMap (foldrDirectory f mempty) xs + where + b' = foldrFile f b (Directory n xs) +-- | Foldable over Files instance Foldable SystemEntry where - foldMap fam = foldrEntry (mappend . fam) mempty + foldMap fam = foldrFile (mappend . fam) mempty parseInput :: FilePath -> ByteString -> Either ParseError [Queries] parseInput = parse $ queries <* (eol <|> eof) @@ -208,13 +218,8 @@ run (Directory n ses) (ChangeDir d : qs) = run (Directory n (ses' : ses)) qs' run (Directory n ses) (List fd : qs) = run (Directory n (fmap File fd ++ ses)) qs run _ _ = error "invalid operation" -getSize :: SystemEntry FileData -> Int -getSize = getSum . foldr ((<>) . Sum . _size) (Sum 0) - getDirSizes :: SystemEntry FileData -> [Int] -getDirSizes (File _) = [] -getDirSizes (Directory n ses) = - getSize (Directory n ses) : foldl (\a d -> a ++ getDirSizes d) [] ses +getDirSizes = map getSum . foldrDirectory ((<>) . Sum. _size) (Sum 0) runPart1 :: [Queries] -> Int runPart1 = sum . filter (<= minSize) . getDirSizes . fst . run root . drop 1 @@ -228,6 +233,9 @@ runPart2 qs = minimum $ filter (>= requiredSpace - unusedSpace) $ getDirSizes sy systemEntry :: SystemEntry FileData systemEntry = fst $ run root $ drop 1 qs + getSize :: SystemEntry FileData -> Int + getSize = getSum . foldr ((<>) . Sum . _size) (Sum 0) + unusedSpace :: Int unusedSpace = totalSpace - getSize systemEntry |
