Optimised day 19
[advent-of-code-22.git] / advent25 / Main.hs
index 39ba5c16dff3170a329caa0c1365c2e98d2c6923..c58c47dc015da9bcd9e060d6eb1d885a2882c1db 100644 (file)
@@ -10,7 +10,6 @@ main =
       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
@@ -25,19 +24,23 @@ snafuValue '=' = -2
 snafuValue _ = error "Illegal digit in read"
 
 showSnafu :: Int -> String
-showSnafu n = reverse $ packSnafu 0 $ toBase5R n
+showSnafu = packSnafu . toBase5R
 
 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))
+packSnafu :: [Int] -> String
+packSnafu digits
+  | carry == 0 = shown
+  | otherwise = (snafuRep carry) : shown
+  where (carry, shown) = foldl' packSnafuDigit (0, "") digits
+
+packSnafuDigit :: (Int, String) -> Int -> (Int, String)
+packSnafuDigit (carry, acc) d 
+  | d' <= 2 = (0, (snafuRep d') : acc)
+  | otherwise = (1, (snafuRep (d' - 5) : acc))
   where d' = d + carry
 
 snafuRep :: Int -> Char