import Data.List import Data.List.Split main :: IO () main = do input <- map lines . splitOn "\n\n" <$> readFile "input" let field = parseField $ head input let moves = parseMoves $ last input print $ map last $ doMoves reverse moves field print $ map last $ doMoves id moves field parseField :: [String] -> [String] parseField = filter (not . null) . map (reverse . filter (not . flip elem "[] ")) . transpose . init parseMoves :: [String] -> [[Int]] parseMoves = map (map (subtract 1 . read) . filter (not . null . intersect ['0' .. '9']) . words) move :: (String -> String) -> [Int] -> [String] -> [String] move f [p, a, b] field = newFieldA ++ [new] ++ newFieldB where line = field !! a (rmn, splt) = splitAt (length line - 1 - p) line new = field !! b ++ f splt (fieldA, _) = splitAt a field (_, fieldB) = splitAt (a + 1) field removedField = fieldA ++ [rmn] ++ fieldB (newFieldA, _) = splitAt b removedField (_, newFieldB) = splitAt (b + 1) removedField doMoves :: (String -> String) -> [[Int]] -> [String] -> [String] doMoves _ [] field = field doMoves f (m:ms) field = doMoves f ms (move f m field)