HCVB4TXZG6OCOQEZ5JBZB3PT7QVL2NYJHXCOLPVLAR73Z6CTKSJQC
[Z] [W] [Z]
[D] [M] [L] [P] [G]
[S] [N] [R] [S] [F] [N]
[N] [J] [W] [J] [F] [D] [F]
[N] [H] [G] [J] [H] [Q] [H] [P]
[V] [J] [T] [F] [H] [Z] [R] [L] [M]
[C] [M] [C] [D] [F] [T] [P] [S] [S]
[S] [Z] [M] [T] [P] [C] [D] [C] [D]
1 2 3 4 5 6 7 8 9
move 3 from 9 to 6
move 7 from 6 to 2
move 1 from 1 to 5
move 7 from 7 to 1
move 3 from 9 to 7
move 1 from 9 to 1
move 1 from 7 to 2
move 11 from 1 to 8
move 9 from 8 to 2
move 1 from 6 to 7
move 3 from 7 to 3
move 7 from 3 to 4
move 9 from 8 to 7
move 3 from 3 to 1
move 2 from 5 to 2
move 6 from 7 to 3
move 1 from 1 to 7
move 1 from 9 to 2
move 1 from 5 to 3
move 1 from 8 to 2
move 2 from 7 to 5
move 1 from 1 to 4
move 3 from 5 to 8
move 2 from 8 to 7
move 1 from 8 to 9
move 7 from 3 to 1
move 8 from 2 to 5
move 3 from 7 to 3
move 1 from 5 to 1
move 1 from 9 to 6
move 1 from 7 to 4
move 1 from 6 to 3
move 1 from 7 to 1
move 9 from 4 to 5
move 8 from 1 to 2
move 3 from 3 to 2
move 1 from 1 to 6
move 7 from 5 to 6
move 1 from 1 to 5
move 1 from 3 to 5
move 21 from 2 to 3
move 8 from 6 to 3
move 5 from 4 to 9
move 9 from 3 to 8
move 17 from 3 to 5
move 6 from 2 to 1
move 2 from 9 to 1
move 3 from 3 to 6
move 3 from 2 to 5
move 7 from 8 to 2
move 3 from 6 to 9
move 2 from 2 to 4
move 1 from 2 to 6
move 2 from 2 to 6
move 2 from 6 to 5
move 1 from 6 to 1
move 2 from 2 to 7
move 1 from 8 to 2
move 4 from 9 to 1
move 4 from 1 to 6
move 1 from 8 to 5
move 3 from 6 to 9
move 1 from 9 to 1
move 2 from 9 to 2
move 4 from 4 to 5
move 1 from 7 to 8
move 1 from 7 to 5
move 8 from 1 to 8
move 1 from 1 to 9
move 1 from 6 to 8
move 2 from 2 to 6
move 1 from 1 to 3
move 1 from 2 to 5
move 1 from 3 to 4
move 3 from 9 to 4
move 4 from 4 to 1
move 29 from 5 to 1
move 2 from 6 to 3
move 2 from 3 to 5
move 2 from 5 to 9
move 7 from 8 to 1
move 3 from 8 to 6
move 6 from 1 to 6
move 2 from 9 to 8
move 2 from 5 to 3
move 3 from 5 to 6
move 2 from 5 to 6
move 1 from 5 to 1
move 2 from 3 to 9
move 1 from 8 to 6
move 1 from 8 to 3
move 1 from 3 to 5
move 5 from 1 to 5
move 5 from 6 to 2
move 25 from 1 to 9
move 9 from 9 to 3
move 7 from 6 to 8
move 9 from 5 to 9
move 2 from 6 to 5
move 6 from 9 to 7
move 1 from 6 to 8
move 3 from 2 to 1
move 3 from 8 to 1
move 5 from 9 to 6
move 3 from 9 to 1
move 4 from 6 to 9
move 2 from 7 to 4
move 1 from 4 to 1
move 1 from 6 to 2
move 7 from 1 to 6
move 1 from 9 to 8
move 9 from 3 to 9
move 5 from 1 to 7
move 1 from 5 to 7
move 3 from 1 to 7
move 3 from 6 to 7
move 8 from 9 to 1
move 3 from 7 to 3
move 1 from 5 to 6
move 3 from 1 to 7
move 4 from 1 to 4
move 2 from 8 to 5
move 1 from 4 to 2
move 3 from 2 to 7
move 2 from 6 to 4
move 1 from 1 to 2
move 18 from 7 to 5
move 1 from 7 to 5
move 1 from 2 to 3
move 4 from 5 to 9
move 1 from 2 to 1
move 2 from 3 to 9
move 2 from 3 to 4
move 2 from 6 to 5
move 1 from 8 to 3
move 4 from 9 to 7
move 1 from 1 to 9
move 3 from 5 to 2
move 2 from 8 to 6
move 2 from 6 to 1
move 5 from 5 to 7
move 7 from 9 to 7
move 11 from 5 to 9
move 3 from 7 to 6
move 6 from 4 to 9
move 5 from 7 to 3
move 6 from 3 to 6
move 2 from 1 to 2
move 2 from 4 to 9
move 6 from 9 to 2
move 1 from 7 to 5
move 10 from 2 to 9
move 4 from 9 to 4
move 1 from 4 to 3
move 31 from 9 to 3
move 1 from 9 to 4
move 6 from 3 to 8
move 1 from 5 to 8
move 5 from 6 to 4
move 4 from 3 to 2
move 1 from 4 to 6
move 22 from 3 to 7
move 6 from 4 to 7
move 4 from 6 to 2
move 8 from 8 to 1
move 3 from 2 to 8
move 2 from 1 to 9
move 1 from 2 to 6
move 3 from 2 to 5
move 2 from 5 to 4
move 2 from 6 to 4
move 24 from 7 to 4
move 1 from 7 to 4
move 2 from 1 to 5
move 2 from 9 to 6
move 10 from 4 to 6
move 3 from 1 to 6
move 6 from 7 to 1
move 2 from 2 to 3
move 1 from 7 to 4
move 2 from 8 to 4
move 1 from 8 to 5
move 4 from 5 to 2
move 5 from 4 to 1
move 2 from 7 to 8
move 2 from 8 to 4
move 5 from 6 to 3
move 2 from 4 to 3
move 1 from 7 to 5
move 2 from 3 to 6
move 1 from 5 to 1
move 3 from 6 to 8
move 11 from 4 to 3
move 7 from 6 to 1
move 3 from 8 to 1
move 1 from 2 to 3
move 2 from 6 to 9
move 2 from 2 to 3
move 3 from 4 to 3
move 2 from 9 to 4
move 1 from 6 to 3
move 5 from 1 to 2
move 2 from 4 to 3
move 24 from 3 to 7
move 3 from 3 to 9
move 1 from 2 to 6
move 1 from 2 to 5
move 1 from 6 to 1
move 4 from 2 to 1
move 2 from 9 to 2
move 1 from 2 to 4
move 18 from 7 to 5
move 1 from 2 to 1
move 1 from 9 to 1
move 2 from 5 to 7
move 13 from 1 to 8
move 3 from 4 to 9
move 7 from 1 to 7
move 13 from 7 to 6
move 1 from 9 to 5
move 3 from 4 to 3
move 1 from 9 to 8
move 3 from 1 to 3
move 1 from 9 to 5
move 2 from 1 to 4
move 2 from 7 to 3
move 4 from 3 to 1
move 1 from 1 to 5
move 9 from 6 to 7
move 5 from 7 to 1
move 2 from 4 to 1
move 4 from 6 to 1
move 3 from 5 to 3
move 3 from 3 to 5
move 7 from 1 to 6
move 6 from 6 to 1
move 1 from 6 to 8
move 2 from 7 to 9
move 2 from 1 to 5
move 1 from 3 to 7
move 7 from 5 to 9
move 10 from 1 to 5
move 8 from 8 to 4
move 6 from 4 to 8
move 1 from 4 to 1
move 2 from 9 to 8
move 2 from 1 to 3
move 2 from 7 to 3
move 1 from 7 to 8
move 4 from 3 to 8
move 1 from 3 to 2
move 20 from 5 to 8
move 1 from 2 to 4
move 4 from 9 to 4
move 4 from 4 to 5
move 18 from 8 to 6
move 3 from 9 to 6
move 1 from 3 to 9
move 10 from 8 to 7
move 7 from 7 to 9
move 7 from 8 to 5
move 3 from 7 to 8
move 6 from 5 to 1
move 6 from 9 to 4
move 1 from 9 to 6
move 1 from 3 to 6
move 1 from 8 to 5
move 1 from 9 to 4
move 12 from 6 to 7
move 5 from 7 to 1
move 6 from 8 to 5
move 1 from 5 to 1
move 3 from 5 to 3
move 8 from 4 to 9
move 2 from 3 to 7
move 4 from 7 to 2
move 10 from 5 to 6
move 11 from 1 to 6
move 4 from 2 to 5
move 1 from 3 to 8
move 1 from 8 to 9
move 1 from 4 to 7
move 3 from 7 to 4
move 1 from 1 to 6
move 1 from 4 to 7
move 1 from 7 to 1
move 4 from 5 to 2
move 3 from 7 to 1
move 2 from 4 to 8
move 20 from 6 to 8
move 4 from 1 to 5
move 2 from 5 to 2
move 6 from 6 to 1
move 5 from 1 to 8
move 7 from 6 to 2
move 6 from 9 to 7
move 2 from 9 to 8
move 2 from 7 to 4
move 4 from 2 to 6
move 3 from 5 to 8
move 12 from 8 to 7
move 1 from 4 to 3
move 1 from 2 to 9
move 1 from 9 to 2
move 1 from 6 to 8
move 1 from 3 to 1
move 2 from 1 to 6
move 1 from 4 to 2
move 3 from 6 to 2
move 2 from 5 to 7
move 1 from 9 to 8
move 6 from 2 to 4
move 17 from 7 to 1
move 10 from 1 to 7
move 4 from 2 to 6
move 10 from 7 to 8
move 3 from 6 to 2
move 4 from 4 to 1
move 2 from 6 to 4
move 4 from 2 to 6
move 1 from 7 to 1
move 2 from 4 to 3
move 12 from 1 to 7
move 5 from 6 to 3
move 17 from 8 to 2
move 4 from 3 to 8
move 1 from 4 to 2
move 20 from 8 to 7
move 19 from 2 to 6
move 7 from 6 to 3
move 7 from 3 to 5
move 2 from 5 to 7
move 4 from 6 to 9
move 1 from 4 to 2
move 1 from 2 to 1
move 2 from 3 to 6
move 1 from 2 to 6
move 1 from 3 to 1
move 4 from 6 to 2
move 1 from 5 to 9
move 7 from 7 to 3
move 7 from 3 to 8
move 5 from 8 to 1
move 2 from 8 to 3
move 1 from 2 to 1
move 3 from 5 to 6
move 1 from 3 to 9
move 2 from 9 to 2
move 8 from 1 to 7
move 3 from 7 to 6
move 2 from 2 to 4
move 21 from 7 to 3
move 10 from 3 to 1
move 2 from 9 to 2
move 7 from 3 to 4
move 3 from 3 to 7
move 4 from 2 to 3
move 3 from 7 to 8
move 1 from 3 to 6
move 1 from 3 to 2
move 4 from 7 to 9
move 10 from 1 to 6
move 1 from 5 to 9
move 6 from 7 to 2
move 24 from 6 to 5
move 2 from 8 to 4
move 1 from 8 to 6
move 2 from 2 to 9
move 5 from 2 to 7
move 1 from 2 to 9
move 11 from 4 to 1
move 3 from 3 to 2
move 4 from 9 to 7
move 1 from 1 to 5
move 1 from 6 to 1
move 5 from 1 to 9
move 5 from 9 to 7
move 5 from 7 to 5
move 23 from 5 to 2
move 5 from 7 to 8
move 6 from 5 to 6
move 1 from 3 to 7
move 1 from 5 to 7
move 6 from 7 to 8
move 3 from 6 to 1
move 2 from 8 to 7
move 4 from 2 to 1
move 4 from 8 to 5
move 7 from 2 to 3
move 1 from 7 to 4
move 1 from 4 to 7
move 4 from 3 to 8
move 6 from 1 to 9
move 4 from 8 to 6
move 3 from 1 to 5
move 3 from 8 to 5
move 1 from 1 to 8
move 3 from 9 to 1
move 3 from 6 to 7
move 1 from 7 to 9
move 3 from 8 to 3
move 8 from 5 to 7
move 11 from 2 to 8
move 5 from 8 to 3
move 1 from 8 to 7
move 10 from 3 to 4
move 2 from 5 to 8
move 3 from 9 to 2
move 1 from 9 to 6
move 7 from 2 to 7
move 6 from 9 to 4
move 1 from 8 to 5
move 3 from 6 to 8
move 1 from 5 to 3
move 2 from 3 to 1
move 6 from 1 to 3
move 13 from 7 to 5
move 16 from 4 to 3
move 2 from 1 to 5
move 5 from 5 to 4
move 11 from 3 to 4
move 2 from 7 to 1
move 7 from 3 to 1
move 2 from 8 to 3
move 8 from 1 to 9
move 12 from 4 to 8
move 1 from 1 to 4
move 2 from 6 to 2
move 3 from 7 to 8
move 2 from 4 to 6
move 5 from 8 to 1
move 3 from 7 to 5
move 6 from 5 to 7
move 2 from 2 to 5
move 1 from 4 to 9
move 5 from 1 to 8
move 6 from 3 to 1
move 7 from 5 to 7
move 7 from 9 to 2
move 1 from 6 to 7
move 1 from 1 to 9
move 2 from 5 to 3
move 2 from 9 to 6
move 13 from 7 to 3
move 2 from 6 to 1
move 1 from 9 to 2
move 16 from 8 to 7
move 6 from 8 to 5
move 3 from 2 to 5
move 4 from 2 to 1
move 3 from 1 to 8
move 2 from 8 to 9
move 1 from 8 to 7
move 1 from 2 to 1
move 8 from 3 to 1
move 1 from 4 to 5
move 1 from 6 to 3
move 2 from 9 to 7
move 5 from 1 to 4
move 15 from 7 to 9
move 11 from 9 to 3
move 7 from 1 to 3
move 2 from 1 to 6
move 1 from 6 to 3
move 2 from 4 to 5
move 2 from 4 to 9
move 7 from 5 to 9
move 5 from 9 to 3
move 1 from 1 to 6
move 5 from 5 to 9
move 1 from 4 to 8
move 1 from 8 to 4
move 3 from 7 to 4
move 8 from 9 to 5
move 1 from 6 to 4
move 4 from 9 to 3
move 1 from 9 to 3
move 23 from 3 to 1
move 12 from 1 to 2
move 6 from 1 to 9
move 5 from 9 to 7
move 3 from 3 to 7
move 6 from 4 to 3
move 1 from 6 to 8
move 6 from 1 to 2
move 3 from 7 to 3
move 3 from 2 to 5
move 10 from 3 to 5
move 1 from 1 to 8
move 12 from 2 to 5
move 3 from 2 to 9
move 2 from 8 to 4
move 13 from 5 to 1
move 2 from 9 to 2
move 2 from 1 to 3
move 11 from 3 to 1
move 2 from 2 to 1
move 2 from 1 to 9
move 16 from 1 to 7
move 17 from 5 to 8
move 1 from 1 to 2
move 3 from 9 to 6
[D]
[N] [C]
[Z] [M] [P]
1 2 3
move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2
module Main where
import Data.Bifunctor (bimap, first, second)
import Data.List
import Data.Char
import Data.Maybe
import Control.Applicative ((<|>))
import Text.ParserCombinators.ReadP
import Aoc
main :: IO ()
main = do
content <- input 5
let run = Aoc.run content
run "CNSZFDVLJ" (strategy reverse)
run "QNDWLMGNS" (strategy id)
where
strategy a = map head . uncurry (foldl' $ flip (runProcedure a)) . bimap parseStack procedures . sections
type Stack = [Crate]
type Crate = Char
data Procedure = Move Int Int Int
deriving Show
liftCrate :: Int -> [Stack] -> (Crate, [Stack])
liftCrate i stacks = doLift (i - 1) stacks
where
doLift :: Int -> [Stack] -> (Crate, [Stack])
doLift 0 (x:xs) = (head x, (tail x):xs)
doLift i (x:xs) = second (x:) $ doLift (i - 1) xs
liftNCrate :: ([Crate] -> [Crate]) -> Int -> Int -> [Stack] -> ([Crate], [Stack])
liftNCrate liftStrat count i stacks = doLift (i - 1) stacks
where
doLift :: Int -> [Stack] -> ([Crate], [Stack])
doLift 0 (x:xs) = (liftStrat . take count $ x, (drop count x):xs)
doLift i (x:xs) = second (x:) $ doLift (i - 1) xs
dropCrate :: Int -> Stack -> [Stack] -> [Stack]
dropCrate i crates stacks = doDrop (i - 1) stacks
where
doDrop :: Int -> [Stack] -> [Stack]
doDrop 0 (x:xs) = (crates ++ x) : xs
doDrop i (x:xs) = x : doDrop (i - 1) xs
doDrop _ [] = []
move :: ([Crate] -> [Crate]) -> Int -> Int -> Int -> [Stack] -> [Stack]
move f count from to stack = dropCrate to lifted remainder
where
(lifted, remainder) = liftNCrate f count from stack
runProcedure :: ([Crate] -> [Crate]) -> Procedure -> [Stack] -> [Stack]
runProcedure f (Move count from to) stack = move f count from to stack
sections :: String -> ([String], [String])
sections = bimap (init) (drop 1) . break null . lines
parseStack :: [String] -> [String]
parseStack = map (dropWhile (==' ')) . transpose . parseStrategy row
procedures :: [String] -> [Procedure]
procedures = parseStrategy procedureParser
parseStrategy :: ReadP a -> [String] -> [a]
parseStrategy a = map fst . map (head . readP_to_S a)
-- moves <- procedures . snd . sections <$> sample 5
-- stacks <- parseStack . fst . sections <$> sample 5
-- foldl' (\a x -> runProcedure x a) stacks moves
top :: [Stack] -> String
top = map head
-- Parsers
crate :: ReadP Crate
crate = between (char '[') (char ']') get
emptyStack :: ReadP Crate
emptyStack = do
count 3 (satisfy isSpace)
pure ' '
stack :: ReadP Crate
stack = crate <|> emptyStack
row :: ReadP [Crate]
row = manyTill (stack <* (optional (char ' '))) eof
-- Procedure parser
procedureParser :: ReadP Procedure
procedureParser = do
string "move "
amount <- read <$> munch1 isDigit
string " from "
from <- read <$> munch1 isDigit
string " to "
to <- read <$> munch1 isDigit
pure $ Move amount from to