import Data.List.Split (splitOn) split3Ways :: [Int] -> Int -> Int -> ([Int], [Int], [Int]) split3Ways xs from to | to >= from = (take from xs, take (to - from) (drop from xs), drop to xs) | otherwise = split3Ways xs to from permute :: [Int] -> Int -> Int -> [Int] permute xs from to | to >= from = xs1 ++ reverse xs2 ++ xs3 | otherwise = xs1' ++ xs2 ++ xs3' where (xs1, xs2, xs3) = split3Ways xs from to xs4 = reverse (xs3 ++ xs1) (xs3', xs1') = splitAt (length xs3) xs4 step :: ([Int], Int, Int) -> Int -> ([Int], Int, Int) step (xs, skip, from) n = let m = length xs in (permute xs from ((from + n) `mod` m), skip + 1, (from + n + skip) `mod` m) solve1' :: [Int] -> Int solve1' xs = let (ys, _, _) = foldl step ([0 .. 255], 0, 0) xs in --solve1' xs = let (ys, _, _) = foldl step ([0 .. 4], 0, 0) xs in (head ys) * (head $ tail ys) parseInput :: [Char] -> [Int] parseInput = (fmap read) . (splitOn ",") solve1 :: [Char] -> Int solve1 = solve1' . parseInput input = "120,93,0,90,5,80,129,74,1,165,204,255,254,2,50,113"