diff options
author | Laura Orvokki Kursula <lav@vampires.gay> | 2024-12-09 18:44:21 +0100 |
---|---|---|
committer | Laura Orvokki Kursula <lav@vampires.gay> | 2024-12-09 18:44:21 +0100 |
commit | 1108945b4826e986d621349af0829ab087c3fd1d (patch) | |
tree | c191c757b453a9019ba8c06a0cec615a1e4560b4 | |
parent | 5890a28fd2161ac0c003fae8d26ae88e2fd687eb (diff) | |
download | aoc2024-1108945b4826e986d621349af0829ab087c3fd1d.tar.gz aoc2024-1108945b4826e986d621349af0829ab087c3fd1d.zip |
9-2
-rw-r--r-- | 9-2.hs | 48 |
1 files changed, 48 insertions, 0 deletions
@@ -0,0 +1,48 @@ +import Data.Foldable (toList) +import Data.Sequence hiding (replicate, zip) + +type FS = Seq File + +data File = File { fid :: Int, size :: Int } | Blank { size :: Int } + deriving (Eq, Show) + +doOne :: FS -> Maybe FS +doOne = go Empty + where + go :: FS -> FS -> Maybe FS + go _ Empty = Nothing + go _ (_ :|> (Blank _)) = Nothing + go res (y@(Blank l) :<| ys@(xs :|> x@(File _ k))) + | k <= l = Just $ res <> (x :<| Blank (l-k) :<| (xs :|> Blank k)) + | otherwise = go (res :|> y) ys + go res (x :<| xs) = go (res :|> x) xs + +rearrange :: FS -> FS +rearrange Empty = Empty +rearrange ys@(xs :|> x) = case doOne ys of + Nothing -> rearrange xs :|> x + Just zs -> rearrange zs + +parse :: String -> Seq File +parse = go 0 Empty + where + go :: Int -> Seq File -> String -> Seq File + go _ res [] = res + go n res (x:xs) = go' (n+1) (res :|> File n (f x)) xs + + go' :: Int -> Seq File -> String -> Seq File + go' _ res [] = res + go' n res (x:xs) = go n (res :|> Blank (f x)) xs + + f :: Char -> Int + f = read . pure + +expand :: File -> [Int] +expand (Blank n) = replicate n 0 +expand (File i n) = replicate n i + +checksum :: FS -> Int +checksum = sum . fmap (uncurry (*)) . zip [0..] . concatMap expand . toList + +main :: IO () +main = getLine >>= print . checksum . rearrange . parse |