Done day 25
[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 n = reverse $ packSnafu 0 $ toBase5R n
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 -> [Int] -> String
36 packSnafu 0 [] = ""
37 packSnafu carry [] = [snafuRep carry]
38 packSnafu carry (d:ds)
39 | d' <= 2 = ((snafuRep d') : (packSnafu 0 ds))
40 | otherwise = ((snafuRep (d' - 5)) : (packSnafu 1 ds))
41 where d' = d + carry
42
43 snafuRep :: Int -> Char
44 snafuRep 2 = '2'
45 snafuRep 1 = '1'
46 snafuRep 0 = '0'
47 snafuRep -1 = '-'
48 snafuRep -2 = '='
49 snafuRep _ = error "Illegal number in show"