summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaura Orvokki Kursula <lav@vampires.gay>2024-12-09 18:44:21 +0100
committerLaura Orvokki Kursula <lav@vampires.gay>2024-12-09 18:44:21 +0100
commit1108945b4826e986d621349af0829ab087c3fd1d (patch)
treec191c757b453a9019ba8c06a0cec615a1e4560b4
parent5890a28fd2161ac0c003fae8d26ae88e2fd687eb (diff)
downloadaoc2024-1108945b4826e986d621349af0829ab087c3fd1d.tar.gz
aoc2024-1108945b4826e986d621349af0829ab087c3fd1d.zip
9-2
-rw-r--r--9-2.hs48
1 files changed, 48 insertions, 0 deletions
diff --git a/9-2.hs b/9-2.hs
new file mode 100644
index 0000000..361b9d1
--- /dev/null
+++ b/9-2.hs
@@ -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