-- this is disgustingly slow but it Works -- i wish i had the energy to optimize this because it's very simple to do so import Common import Data.List (elemIndex, intercalate) import Data.Maybe (fromJust) wrap :: Int -> Int -> Int wrap length index = index `mod` (length - 1) coordinates = [1000, 2000, 3000] key = 811589153 decrypt :: [Int] -> Int decrypt a = sum $ map test coordinates where test n = mixed !! (zeroIndex + n) zeroIndex = fromJust $ elemIndex 0 mixed mixed = cycle $ fst $ iterateN mixList 10 (map (* key) a, allIndices) mixList (values, indices) = foldl step (values, indices) allIndices allIndices = [0 .. len - 1] len = length a step :: ([Int], [Int]) -> Int -> ([Int], [Int]) step (values, indices) i = (mix values index value, mix indices index value) where value = values !! index index = fromJust $ elemIndex i indices mix :: [Int] -> Int -> Int -> [Int] mix list i x = newList where newList = listStart ++ value : listEnd (listStart, listEnd) = splitAt newIndex list' newIndex = wrap len $ i + x list' = (\(l, r) -> l ++ tail r) $ splitAt i list value = list !! i main = interact $ show . decrypt . map read . lines