2023-12-15 19:33:31 +01:00
import Control.Arrow
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-17 11:31:11 +01:00
main = interact $ show . genBuckets . 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 " , "
hashAlg :: Int -> Char -> Int
hashAlg x y = ( 17 * ( fromEnum y + x ) ) ` mod ` 256
2023-12-17 11:31:11 +01:00
removeHashes :: [ String ] -> [ HASH ] -> [ HASH ]
removeHashes _ [] = []
removeHashes rs ( ( label , Nothing ) : xs ) = removeHashes ( label : rs ) xs
removeHashes rs ( ( label , Just x ) : xs )
| label ` elem ` rs = removeHashes ( delete label rs ) xs
| otherwise = ( label , Just x ) : removeHashes rs xs
genBuckets :: [ HASH ] -> Int
genBuckets input =
sum
[ sum $ zipWith ( * ) [ 1 .. ] $ map ( ( * ( succ x ) ) . fromJust . snd ) ( sorted x )
| x <- [ 0 .. 255 ]
]
where
filterBucket x f =
nubBy ( ( == ) ` on ` fst ) $
f $ removeHashes [] ( reverse $ filter ( f1 x ) input )
sorted x =
sortOn
( \ y -> fst y ` elemIndex ` ( map fst ( filterBucket x reverse ) ) )
( filterBucket x id )
f1 n ( x , _ ) = foldl hashAlg 0 x == n