summaryrefslogtreecommitdiff
path: root/day09/day09.hs
diff options
context:
space:
mode:
Diffstat (limited to 'day09/day09.hs')
-rw-r--r--day09/day09.hs46
1 files changed, 46 insertions, 0 deletions
diff --git a/day09/day09.hs b/day09/day09.hs
new file mode 100644
index 0000000..0e03865
--- /dev/null
+++ b/day09/day09.hs
@@ -0,0 +1,46 @@
+import Data.Char
+import Data.List
+
+type Id = Int
+type Len = Int
+data Block = Data Id Len | Free Len deriving Show
+type HDD = [Block]
+
+getDataFree :: HDD -> Id -> [Len] -> HDD
+getDataFree acc id (d:[]) =
+ acc ++ [Data id d]
+getDataFree acc id (d:f:r) =
+ getDataFree (acc ++ [Data id d, Free f]) (id + 1) r
+
+consume :: String -> HDD
+consume file =
+ getDataFree [] 0 $ map digitToInt $ trim file
+ where trim = dropWhileEnd isSpace . dropWhile isSpace
+
+frag1 :: HDD -> HDD -> HDD -> HDD
+frag1 acc dt (Free _:rest) =
+ frag1 acc dt rest
+frag1 acc (Data di dl:dr) p@(Data pi pl:_)
+ | di == pi = acc ++ [Data pi pl]
+ | otherwise = frag1 (acc ++ [Data di dl]) dr p
+frag1 acc (Free f:rest) (Data id d:pack)
+ | d < f = frag1 (acc ++ [Data id d]) (Free (f - d):rest) pack
+ | d == f = frag1 (acc ++ [Data id d]) rest pack
+ | d > f = frag1 (acc ++ [Data id f]) rest (Data id (d - f):pack)
+
+frag :: HDD -> HDD
+frag hdd = frag1 [] hdd (reverse hdd)
+
+checksum :: Int -> Int -> HDD -> Int
+checksum acc _ [] = acc
+checksum acc ix (Data id len:rest) =
+ checksum (acc + (sum $ map (id*) [ix..ix+len-1])) (ix + len) rest
+
+part1 :: HDD -> Int
+part1 = (checksum 0 0) . frag
+
+main = do
+ file <- readFile "day09.input"
+ let hdd = consume file
+ putStrLn ("Part 1: " ++ (show $ part1 hdd))
+ --putStrLn ("Part 2: " ++ (show $ part2 hdd))