AoC/2023/day15/day15.hs

40 lines
1.1 KiB
Haskell
Raw Normal View History

2023-12-15 19:33:31 +01:00
import Control.Arrow
2023-12-24 23:40:18 +01:00
import Control.Lens
import Data.Function
import Data.List
2023-12-15 19:33:31 +01:00
import Data.List.Split
import Data.Maybe
import Text.Read
2023-12-15 19:33:31 +01:00
type HASH = (String, Maybe Int)
main :: IO ()
2023-12-24 23:40:18 +01:00
main = interact $ show . (day15a &&& day15b . parse) . init
2023-12-15 19:33:31 +01:00
parse :: String -> [HASH]
parse = map (second (readMaybe . tail) . break (`elem` "=-")) . splitOn ","
day15a :: String -> Int
day15a = sum . map (foldl' hashAlg 0) . splitOn ","
2023-12-24 23:40:18 +01:00
day15b :: [HASH] -> Int
day15b =
sum .
zipWith (*) [1 ..] .
map (sum . zipWith (*) [1 ..] . map (fromJust . snd)) .
foldl' processInstruction (replicate 256 [])
2023-12-15 19:33:31 +01:00
hashAlg :: Int -> Char -> Int
hashAlg x y = (17 * (fromEnum y + x)) `mod` 256
2023-12-24 23:40:18 +01:00
processInstruction :: [[HASH]] -> HASH -> [[HASH]]
processInstruction bs (s, action) = (element box .~ l) bs
where
2023-12-24 23:40:18 +01:00
mInsert x = uncurry (++) . second (f x) . break (((==) `on` fst) x)
f a (_:xs) = a : xs
f a [] = [a]
box = foldl' hashAlg 0 s
newList = mInsert (s, action) (bs !! box)
newDelList = deleteBy ((==) `on` fst) (s, action) (bs !! box)
l = maybe newDelList (const newList) action