Rebuilt as a fold
[advent-of-code-22.git] / advent25 / Main.hs
1 -- Writeup at https://work.njae.me.uk/2022/12/01/advent-of-code-2022-day-1/
2
3 import AoC
4 import Data.List
5
6
7 main :: IO ()
8 main =
9 do dataFileName <- getDataFileName
10 numStrs <- readFile dataFileName
11 let fuels = fmap readSnafu $ lines numStrs
12 putStrLn $ showSnafu $ sum fuels
13 -- print $ part1 fuels
14
15 readSnafu :: String -> Int
16 readSnafu cs = foldl' go 0 cs
17 where go acc c = acc * 5 + (snafuValue c)
18
19 snafuValue :: Char -> Int
20 snafuValue '2' = 2
21 snafuValue '1' = 1
22 snafuValue '0' = 0
23 snafuValue '-' = -1
24 snafuValue '=' = -2
25 snafuValue _ = error "Illegal digit in read"
26
27 showSnafu :: Int -> String
28 showSnafu = packSnafu . toBase5R
29
30 toBase5R :: Int -> [Int]
31 toBase5R 0 = []
32 toBase5R n = (r : (toBase5R k))
33 where (k, r) = n `divMod` 5
34
35 packSnafu :: [Int] -> String
36 packSnafu = snd . foldl' packSnafuDigit (0, "")
37
38 packSnafuDigit :: (Int, String) -> Int -> (Int, String)
39 packSnafuDigit (carry, acc) d
40 | d' <= 2 = (0, (snafuRep d') : acc)
41 | otherwise = (1, (snafuRep (d' - 5) : acc))
42 where d' = d + carry
43
44
45 snafuRep :: Int -> Char
46 snafuRep 2 = '2'
47 snafuRep 1 = '1'
48 snafuRep 0 = '0'
49 snafuRep -1 = '-'
50 snafuRep -2 = '='
51 snafuRep _ = error "Illegal number in show"