2022-12-06 01:37:04 +01:00
import Data.List
2022-12-11 12:03:12 +01:00
import Data.List.Split
2022-12-06 01:37:04 +01:00
main :: IO ()
main = do
2022-12-11 12:03:12 +01:00
input <- map lines . splitOn " \ n \ n " <$> readFile " input "
2022-12-06 01:37:04 +01:00
let field = parseField $ head input
2022-12-11 12:03:12 +01:00
let moves = parseMoves $ last input
2022-12-06 01:37:04 +01:00
print $ map last $ doMoves reverse moves field
print $ map last $ doMoves id moves field
parseField :: [ String ] -> [ String ]
2022-12-11 12:03:12 +01:00
parseField =
filter ( not . null ) .
map ( reverse . filter ( not . flip elem " [] " ) ) . transpose . init
2022-12-06 01:37:04 +01:00
parseMoves :: [ String ] -> [ [ Int ] ]
2022-12-11 12:03:12 +01:00
parseMoves =
map
( map ( subtract 1 . read ) .
filter ( not . null . intersect [ '0' .. '9' ] ) . words )
2022-12-06 01:37:04 +01:00
move :: ( String -> String ) -> [ Int ] -> [ String ] -> [ String ]
2022-12-11 12:03:12 +01:00
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
2022-12-06 01:37:04 +01:00
doMoves :: ( String -> String ) -> [ [ Int ] ] -> [ String ] -> [ String ]
2022-12-11 12:03:12 +01:00
doMoves _ [] field = field
2022-12-06 01:37:04 +01:00
doMoves f ( m : ms ) field = doMoves f ms ( move f m field )