module Part2 where import Commons import Data.Array (Array, array, (!), (//), assocs, listArray) type Lens = (String, Int) type Hashmap = Array Int [Lens] initHashmap :: Hashmap initHashmap = listArray (0, 255) [[] | _ <- [0..255]] applyInstructionToList :: [Lens] -> Instruction -> [Lens] applyInstructionToList [] i | iType i == Set = [(label i, focal i)] | otherwise = [] applyInstructionToList ((l, f): t) i | iType i == Set && label i == l = (label i, focal i): t | iType i == Remove && label i == l = t | otherwise = (l, f): applyInstructionToList t i applyInstruction :: Hashmap -> Instruction -> Hashmap applyInstruction m i = let hash = getHash 0 (label i) in m // [(hash, applyInstructionToList (m ! hash) i)] applyInstructions :: [Instruction] -> Hashmap applyInstructions = foldl applyInstruction initHashmap getFocusingPowerFromList :: Int -> Int -> [Lens] -> [Int] getFocusingPowerFromList _ _ [] = [] getFocusingPowerFromList i slot ((_, f): t) = i * slot * f: getFocusingPowerFromList i (slot + 1) t getFocusingPower :: Hashmap -> [Int] getFocusingPower = concatMap (\ (i, h) -> getFocusingPowerFromList (i + 1) 1 h) . assocs getAllFocusingPower :: [Instruction] -> [Int] getAllFocusingPower = getFocusingPower . applyInstructions