2023-12-15 19:33:31 +01:00
import Control.Arrow
2023-12-24 23:40:18 +01:00
import Control.Lens
2023-12-17 11:31:11 +01:00
import Data.Function
import Data.List
2023-12-15 19:33:31 +01:00
import Data.List.Split
2023-12-17 11:31:11 +01:00
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
2023-12-17 11:31:11 +01:00
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