28 lines
1.1 KiB
Haskell
28 lines
1.1 KiB
Haskell
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
import qualified Data.Text as T
|
|
import GHC.Utils.Misc (chunkList)
|
|
import Data.Char (isSpace, isNumber)
|
|
import Data.List (transpose)
|
|
|
|
parseState :: String -> [[Char]]
|
|
parseState = map (dropWhile isSpace) . transpose . map (map (!! 1) . chunkList 4) . init . lines
|
|
|
|
parseInstructions :: String -> [(Int, Int)]
|
|
parseInstructions = concatMap ((\[n, a, b] -> replicate n (a, b)) . map read . filter (isNumber . head) . words) . lines
|
|
|
|
evaluateState :: [[Char]] -> (Int, Int) -> [[Char]]
|
|
evaluateState state (a, b) = newState
|
|
where extracted = zipWith (\i l -> (if i == a then tail l else l)) [1..] state
|
|
movedChar = head $ state !! (a - 1)
|
|
newState = zipWith (\i l -> (if i == b then movedChar : l else l)) [1..] extracted
|
|
|
|
executeInstructions :: [[Char]] -> [(Int, Int)] -> [[Char]]
|
|
executeInstructions state (instruction:xs) = executeInstructions newState xs
|
|
where newState = evaluateState state instruction
|
|
executeInstructions state [] = state
|
|
|
|
main = interact $
|
|
map head
|
|
. (\[state, instructions] -> executeInstructions (parseState state) (parseInstructions instructions))
|
|
. map T.unpack . T.splitOn "\n\n" . T.pack |