45 lines
1.2 KiB
Haskell
45 lines
1.2 KiB
Haskell
-- 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 |