32 lines
1.2 KiB
Haskell
32 lines
1.2 KiB
Haskell
|
import Data.List.Split
|
||
|
import Data.List
|
||
|
|
||
|
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 (takeWhile (/=' ') . reverse) . filter (null . intersect "[]") . 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 f [] field = field
|
||
|
doMoves f (m:ms) field = doMoves f ms (move f m field)
|