{-# Language QuasiQuotes, ImportQualifiedPost #-}
module Main (main) where
import Advent (format)
import Data.Array (accumArray, assocs)
import Data.Char (ord)
main :: IO ()
IO ()
main =
do input <- [format|2023 15 (%a+(-|=%d))!&,%n|]
print (sum [hash raw | (raw, _) <- input])
let boxes = ([(String, Int)] -> (String, Maybe Int) -> [(String, Int)])
-> [(String, Int)]
-> (Int, Int)
-> [(Int, (String, Maybe Int))]
-> Array Int [(String, Int)]
forall i e a.
Ix i =>
(e -> a -> e) -> e -> (i, i) -> [(i, a)] -> Array i e
accumArray [(String, Int)] -> (String, Maybe Int) -> [(String, Int)]
updateBox [] (Int
0, Int
255)
[(String -> Int
hash String
lbl, (String
lbl, Maybe Int
cmd)) | (String
_, (String
lbl, Maybe Int
cmd)) <- [(String, (String, Maybe Int))]
input]
print (sum [ (1 + box) * sum (zipWith (*) [1..] (map snd xs))
| (box, xs) <- assocs boxes])
hash :: String -> Int
hash :: String -> Int
hash String
str = (Int -> Char -> Int) -> Int -> String -> Int
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\Int
acc Char
x -> Int
17 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (Char -> Int
ord Char
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
acc)) Int
0 String
str Int -> Int -> Int
forall a. Integral a => a -> a -> a
`rem` Int
256
updateBox ::
[(String, Int)] ->
(String, Maybe Int) ->
[(String, Int)]
updateBox :: [(String, Int)] -> (String, Maybe Int) -> [(String, Int)]
updateBox [(String, Int)]
prev (String
lbl, Maybe Int
Nothing) = ((String, Int) -> Bool) -> [(String, Int)] -> [(String, Int)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((String
lbl String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/=) (String -> Bool)
-> ((String, Int) -> String) -> (String, Int) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, Int) -> String
forall a b. (a, b) -> a
fst) [(String, Int)]
prev
updateBox [(String, Int)]
prev (String
lbl, Just Int
n ) = [(String, Int)] -> [(String, Int)]
go [(String, Int)]
prev
where
go :: [(String, Int)] -> [(String, Int)]
go ((String
k, Int
_) : [(String, Int)]
xs) | String
lbl String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
k = (String
lbl, Int
n) (String, Int) -> [(String, Int)] -> [(String, Int)]
forall a. a -> [a] -> [a]
: [(String, Int)]
xs
go ((String, Int)
x : [(String, Int)]
xs) = (String, Int)
x (String, Int) -> [(String, Int)] -> [(String, Int)]
forall a. a -> [a] -> [a]
: [(String, Int)] -> [(String, Int)]
go [(String, Int)]
xs
go [] = [(String
lbl, Int
n)]