38 lines
1.1 KiB
Haskell
38 lines
1.1 KiB
Haskell
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)
|