85 行
3.8 KiB
Haskell
85 行
3.8 KiB
Haskell
{-# LANGUAGE QuasiQuotes #-}
|
|
module Day5Spec (spec) where
|
|
|
|
import Test.Hspec
|
|
import Text.Heredoc
|
|
import qualified Data.Sequence as S
|
|
|
|
import Day5.Part1
|
|
import Day5.Part2
|
|
import Day5.Shared
|
|
|
|
inputPart1 :: String
|
|
inputPart1 = [str| [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
|
|
|]
|
|
|
|
inputStacks :: String
|
|
inputStacks = [str| [D]
|
|
|[N] [C]
|
|
|[Z] [M] [P]
|
|
| 1 2 3
|
|
|]
|
|
|
|
inputOperations :: String
|
|
inputOperations = [str|move 1 from 2 to 1
|
|
|move 3 from 1 to 3
|
|
|move 2 from 2 to 1
|
|
|move 1 from 1 to 2
|
|
|]
|
|
spec :: Spec
|
|
spec =
|
|
describe "Day5" $ do
|
|
describe "Part1" $ do
|
|
it "parses Operations" $ do
|
|
let operation = head . lines $ inputOperations
|
|
parseOperation operation `shouldBe` Operation { count = 1, from = StackIndex 2, to = StackIndex 1 }
|
|
it "parses stacks" $ do
|
|
parseStacks (lines inputStacks) `shouldBe` S.fromList [Stack "NZ", Stack "DCM", Stack "P"]
|
|
it "parses a single line of stacks" $ do
|
|
let row = head . lines $ inputStacks
|
|
parseRow row `shouldBe` S.fromList [Stack "", Stack "D"]
|
|
it "combines stacks" $ do
|
|
(Stack "AB" <> Stack "CD") `shouldBe` Stack "ABCD"
|
|
it "combines rows" $ do
|
|
S.fromList [Stack "", Stack "A"] `combineRows` S.fromList [Stack "B", Stack "B"] `shouldBe` S.fromList [Stack "B", Stack "AB"]
|
|
S.empty `combineRows` S.fromList [Stack "B", Stack "B"] `shouldBe` S.fromList [Stack "B", Stack "B"]
|
|
S.fromList [Stack "A", Stack "B"] `combineRows` S.empty `shouldBe` S.fromList [Stack "A", Stack "B"]
|
|
S.singleton (Stack "") `combineRows` S.fromList[Stack "B", Stack "B"] `shouldBe` S.fromList [Stack "B", Stack "B"]
|
|
S.fromList [Stack "A", Stack "B"] `combineRows` S.singleton (Stack "") `shouldBe` S.fromList [Stack "A", Stack "B"]
|
|
it "splits input into stacks and operations" $ do
|
|
parseInput inputPart1 `shouldBe`
|
|
(S.fromList [Stack "NZ", Stack "DCM", Stack "P"],
|
|
[ Operation { count = 1, from = StackIndex 2, to = StackIndex 1},
|
|
Operation { count = 3, from = StackIndex 1, to = StackIndex 3},
|
|
Operation { count = 2, from = StackIndex 2, to = StackIndex 1},
|
|
Operation { count = 1, from = StackIndex 1, to = StackIndex 2}])
|
|
it "exeutes a count=1 operation on a row" $ do
|
|
let op = Operation { count = 1, from = StackIndex 2, to = StackIndex 3}
|
|
let row = S.fromList [Stack "NZ", Stack "DCM", Stack "P"]
|
|
executeOperation row op `shouldBe` S.fromList [Stack "NZ", Stack "CM", Stack "DP"]
|
|
it "exeutes a count > 1 operation on a row" $ do
|
|
let op = Operation { count = 2, from = StackIndex 2, to = StackIndex 3}
|
|
let row = S.fromList [Stack "NZ", Stack "DCM", Stack "P"]
|
|
executeOperation row op `shouldBe` S.fromList [Stack "NZ", Stack "M", Stack "CDP"]
|
|
it "finds the top items on stacks" $ do
|
|
let row = S.fromList [Stack "NZ", Stack "DCM", Stack "P"]
|
|
findTopOfStacks row `shouldBe` S.fromList "NDP"
|
|
it "solves the demo" $ do
|
|
day5_1 inputPart1 `shouldBe` "CMZ"
|
|
describe "Part1" $ do
|
|
it "executes 9001 operations on a row" $ do
|
|
let op = Operation { count = 2, from = StackIndex 2, to = StackIndex 3}
|
|
let row = S.fromList [Stack "NZ", Stack "DCM", Stack "P"]
|
|
execute9001Operation row op `shouldBe` S.fromList [Stack "NZ", Stack "M", Stack "DCP"]
|
|
it "solves the demo" $ do
|
|
day5_2 inputPart1 `shouldBe` "MCD"
|
|
|