alternate day11 with no strings
This commit is contained in:
60
aoc2024/Day11b.newt
Normal file
60
aoc2024/Day11b.newt
Normal file
@@ -0,0 +1,60 @@
|
||||
module Day11b
|
||||
|
||||
import Prelude
|
||||
import Node
|
||||
import Aoc
|
||||
import SortedMap
|
||||
|
||||
-- Alternate version that doesn't use string
|
||||
|
||||
infixl 7 _%_
|
||||
pfunc _%_ : Int → Int → Int := `(x,y) => x % y`
|
||||
|
||||
-- 32 bit ints are too small
|
||||
pfunc div53 : Int → Int → Int := `(x,y) => Math.floor(x / y)`
|
||||
|
||||
stone : Int → Either Int (Int × Int)
|
||||
stone num = if num == 0 then Left 1 else go num num 1
|
||||
where
|
||||
go : Int → Int → Int → Either Int (Int × Int)
|
||||
go a b mod =
|
||||
if b == 0 then Right (a, num % mod)
|
||||
else if b < 10 then Left (2024 * num)
|
||||
else go (div53 a 10) (div53 b 100) (mod * 10)
|
||||
|
||||
foldMap : ∀ a b. {{Ord a}} {{Eq a}} → (b → b → b) → SortedMap a b → List (a × b) → SortedMap a b
|
||||
foldMap f m Nil = m
|
||||
foldMap f m ((a,b) :: xs) = case lookupMap a m of
|
||||
Nothing => foldMap f (updateMap a b m) xs
|
||||
Just (_, b') => foldMap f (updateMap a (f b' b) m) xs
|
||||
|
||||
step : List (Int × Int) → List (Int × Int)
|
||||
step xs = go Nil xs
|
||||
where
|
||||
go : List (Int × Int) → List (Int × Int) → List (Int × Int)
|
||||
go acc Nil = acc
|
||||
go acc ((x,c) :: xs) = case stone x of
|
||||
Left a => go ((a,c) :: acc) xs
|
||||
Right (a,b) => go ((a,c) :: (b,c) :: acc) xs
|
||||
|
||||
iter : Int → SortedMap Int Int → Int
|
||||
iter count parts = let x = go count parts in foldl _+_ 0 $ map snd $ toList x
|
||||
where
|
||||
go : Int → SortedMap Int Int → SortedMap Int Int
|
||||
go 0 stuff = stuff
|
||||
go x stuff = go (x - 1) $ foldMap _+_ EmptyMap $ step $ toList stuff
|
||||
|
||||
run : String -> IO Unit
|
||||
run fn = do
|
||||
putStrLn fn
|
||||
text <- readFile fn
|
||||
let stuff = foldMap _+_ EmptyMap $ map (\ x => (stringToInt x, 1)) $ split (trim text) " "
|
||||
let p1 = iter 25 stuff
|
||||
putStrLn $ "part1 " ++ show p1
|
||||
let p2 = iter 75 stuff
|
||||
putStrLn $ "part2 " ++ show p2
|
||||
|
||||
main : IO Unit
|
||||
main = do
|
||||
run "aoc2024/day11/eg.txt"
|
||||
run "aoc2024/day11/input.txt"
|
||||
Reference in New Issue
Block a user