Done day 25
[advent-of-code-22.git] / advent25 / Main.hs
diff --git a/advent25/Main.hs b/advent25/Main.hs
new file mode 100644 (file)
index 0000000..39ba5c1
--- /dev/null
@@ -0,0 +1,49 @@
+-- Writeup at https://work.njae.me.uk/2022/12/01/advent-of-code-2022-day-1/
+
+import AoC
+import Data.List
+
+
+main :: IO ()
+main = 
+  do  dataFileName <- getDataFileName
+      numStrs <- readFile dataFileName
+      let fuels = fmap readSnafu $ lines numStrs
+      putStrLn $ showSnafu $ sum fuels
+      -- print $ part1 fuels
+
+readSnafu :: String -> Int
+readSnafu cs = foldl' go 0 cs
+  where go acc c = acc * 5 + (snafuValue c)
+
+snafuValue :: Char -> Int
+snafuValue '2' = 2
+snafuValue '1' = 1
+snafuValue '0' = 0
+snafuValue '-' = -1
+snafuValue '=' = -2
+snafuValue _ = error "Illegal digit in read"
+
+showSnafu :: Int -> String
+showSnafu n = reverse $ packSnafu 0 $ toBase5R n
+
+toBase5R :: Int -> [Int]
+toBase5R 0 = []
+toBase5R n = (r : (toBase5R k))
+  where (k, r) = n `divMod` 5
+
+packSnafu :: Int -> [Int] -> String
+packSnafu 0 [] = ""
+packSnafu carry [] = [snafuRep carry]
+packSnafu carry (d:ds)
+  | d' <= 2 = ((snafuRep d') : (packSnafu 0 ds))
+  | otherwise = ((snafuRep (d' - 5)) : (packSnafu 1 ds))
+  where d' = d + carry
+
+snafuRep :: Int -> Char
+snafuRep 2 = '2'
+snafuRep 1 = '1'
+snafuRep 0 = '0'
+snafuRep -1 = '-'
+snafuRep -2 = '='
+snafuRep _ = error "Illegal number in show"