From 8b15b5f2c6d6601683029c65eb07bf79d792e1ce Mon Sep 17 00:00:00 2001 From: HeNine <> Date: Mon, 5 Dec 2022 12:15:11 +0100 Subject: [PATCH] day 5 --- aoc2022.cabal | 158 +++++++----- data/input050.txt | 9 + data/input051.txt | 514 ++++++++++++++++++++++++++++++++++++++ src/day05/Day5Lib.hs | 115 +++++++++ src/day05/test/AoCTest.hs | 41 +++ src/day05/test/Basic.hs | 89 +++++++ 6 files changed, 860 insertions(+), 66 deletions(-) create mode 100644 data/input050.txt create mode 100644 data/input051.txt create mode 100644 src/day05/Day5Lib.hs create mode 100644 src/day05/test/AoCTest.hs create mode 100644 src/day05/test/Basic.hs diff --git a/aoc2022.cabal b/aoc2022.cabal index 93c9eed..d323620 100644 --- a/aoc2022.cabal +++ b/aoc2022.cabal @@ -26,39 +26,39 @@ test-suite day01aoctest ghc-options: -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010 -executable day011 - hs-source-dirs: src/day01 - main-is: Main1.hs - other-modules: - Day1Lib - default-language: Haskell2010 - build-depends: base >= 4.7 && < 5, split - ghc-options: -Wall - -Wcompat - -Widentities - -Wincomplete-record-updates - -Wincomplete-uni-patterns - -Wmissing-export-lists - -Wmissing-home-modules - -Wpartial-fields - -Wredundant-constraints - -executable day012 - hs-source-dirs: src/day01 - main-is: Main2.hs - other-modules: - Day1Lib - default-language: Haskell2010 - build-depends: base >= 4.7 && < 5, split - ghc-options: -Wall - -Wcompat - -Widentities - -Wincomplete-record-updates - -Wincomplete-uni-patterns - -Wmissing-export-lists - -Wmissing-home-modules - -Wpartial-fields - -Wredundant-constraints +-- executable day011 +-- hs-source-dirs: src/day01 +-- main-is: Main1.hs +-- other-modules: +-- Day1Lib +-- default-language: Haskell2010 +-- build-depends: base >= 4.7 && < 5, split +-- ghc-options: -Wall +-- -Wcompat +-- -Widentities +-- -Wincomplete-record-updates +-- -Wincomplete-uni-patterns +-- -Wmissing-export-lists +-- -Wmissing-home-modules +-- -Wpartial-fields +-- -Wredundant-constraints + +-- executable day012 +-- hs-source-dirs: src/day01 +-- main-is: Main2.hs +-- other-modules: +-- Day1Lib +-- default-language: Haskell2010 +-- build-depends: base >= 4.7 && < 5, split +-- ghc-options: -Wall +-- -Wcompat +-- -Widentities +-- -Wincomplete-record-updates +-- -Wincomplete-uni-patterns +-- -Wmissing-export-lists +-- -Wmissing-home-modules +-- -Wpartial-fields +-- -Wredundant-constraints -- Day 2 @@ -73,39 +73,39 @@ test-suite day02aoctest ghc-options: -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010 -executable day021 - hs-source-dirs: src/day02 - main-is: Main1.hs - other-modules: - Day2Lib - default-language: Haskell2010 - build-depends: base >= 4.7 && < 5, split - ghc-options: -Wall - -Wcompat - -Widentities - -Wincomplete-record-updates - -Wincomplete-uni-patterns - -Wmissing-export-lists - -Wmissing-home-modules - -Wpartial-fields - -Wredundant-constraints - -executable day022 - hs-source-dirs: src/day02 - main-is: Main2.hs - other-modules: - Day2Lib - default-language: Haskell2010 - build-depends: base >= 4.7 && < 5, split - ghc-options: -Wall - -Wcompat - -Widentities - -Wincomplete-record-updates - -Wincomplete-uni-patterns - -Wmissing-export-lists - -Wmissing-home-modules - -Wpartial-fields - -Wredundant-constraints +-- executable day021 +-- hs-source-dirs: src/day02 +-- main-is: Main1.hs +-- other-modules: +-- Day2Lib +-- default-language: Haskell2010 +-- build-depends: base >= 4.7 && < 5, split +-- ghc-options: -Wall +-- -Wcompat +-- -Widentities +-- -Wincomplete-record-updates +-- -Wincomplete-uni-patterns +-- -Wmissing-export-lists +-- -Wmissing-home-modules +-- -Wpartial-fields +-- -Wredundant-constraints + +-- executable day022 +-- hs-source-dirs: src/day02 +-- main-is: Main2.hs +-- other-modules: +-- Day2Lib +-- default-language: Haskell2010 +-- build-depends: base >= 4.7 && < 5, split +-- ghc-options: -Wall +-- -Wcompat +-- -Widentities +-- -Wincomplete-record-updates +-- -Wincomplete-uni-patterns +-- -Wmissing-export-lists +-- -Wmissing-home-modules +-- -Wpartial-fields +-- -Wredundant-constraints -- Day 3 @@ -157,4 +157,30 @@ test-suite day04aoctest , HUnit , split ghc-options: -threaded -rtsopts -with-rtsopts=-N + default-language: Haskell2010 + +-- Day 5 + +test-suite day05basictest + type: exitcode-stdio-1.0 + hs-source-dirs: src/day05/test, src/day05 + main-is: Basic.hs + other-modules: + Day5Lib + build-depends: base + , HUnit + , parsec + ghc-options: -threaded -rtsopts -with-rtsopts=-N + default-language: Haskell2010 + +test-suite day05aoctest + type: exitcode-stdio-1.0 + hs-source-dirs: src/day05/test, src/day05 + main-is: AoCTest.hs + other-modules: + Day5Lib + build-depends: base + , HUnit + , parsec + ghc-options: -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010 \ No newline at end of file diff --git a/data/input050.txt b/data/input050.txt new file mode 100644 index 0000000..814e919 --- /dev/null +++ b/data/input050.txt @@ -0,0 +1,9 @@ + [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 \ No newline at end of file diff --git a/data/input051.txt b/data/input051.txt new file mode 100644 index 0000000..a51dc11 --- /dev/null +++ b/data/input051.txt @@ -0,0 +1,514 @@ + [B] [B] [S] + [M] [P] [L] [B] [J] + [D] [R] [V] [D] [Q] [D] + [T] [R] [Z] [H] [H] [G] [C] + [P] [W] [J] [B] [J] [F] [J] [S] +[N] [S] [Z] [V] [M] [N] [Z] [F] [M] +[W] [Z] [H] [D] [H] [G] [Q] [S] [W] +[B] [L] [Q] [W] [S] [L] [J] [W] [Z] + 1 2 3 4 5 6 7 8 9 + +move 3 from 5 to 2 +move 5 from 3 to 1 +move 4 from 4 to 9 +move 6 from 1 to 4 +move 6 from 8 to 7 +move 5 from 2 to 7 +move 1 from 5 to 4 +move 11 from 9 to 7 +move 1 from 1 to 9 +move 6 from 4 to 6 +move 12 from 6 to 7 +move 1 from 9 to 2 +move 2 from 4 to 6 +move 1 from 8 to 9 +move 1 from 9 to 4 +move 1 from 6 to 1 +move 2 from 7 to 5 +move 2 from 6 to 7 +move 2 from 1 to 6 +move 2 from 4 to 7 +move 1 from 5 to 4 +move 1 from 5 to 6 +move 1 from 6 to 1 +move 1 from 1 to 3 +move 1 from 4 to 1 +move 1 from 1 to 4 +move 1 from 4 to 5 +move 1 from 3 to 9 +move 1 from 5 to 1 +move 4 from 2 to 1 +move 20 from 7 to 8 +move 24 from 7 to 3 +move 3 from 6 to 4 +move 1 from 1 to 9 +move 1 from 9 to 3 +move 2 from 1 to 2 +move 2 from 4 to 1 +move 2 from 2 to 1 +move 14 from 3 to 6 +move 6 from 1 to 6 +move 10 from 3 to 2 +move 1 from 2 to 3 +move 6 from 6 to 5 +move 2 from 3 to 4 +move 13 from 8 to 4 +move 1 from 9 to 7 +move 1 from 6 to 3 +move 10 from 4 to 2 +move 1 from 3 to 6 +move 2 from 8 to 7 +move 1 from 7 to 2 +move 11 from 6 to 8 +move 2 from 6 to 1 +move 2 from 1 to 3 +move 1 from 8 to 6 +move 1 from 3 to 9 +move 3 from 8 to 2 +move 1 from 3 to 6 +move 2 from 6 to 4 +move 1 from 6 to 5 +move 11 from 2 to 9 +move 2 from 4 to 6 +move 1 from 6 to 1 +move 1 from 1 to 5 +move 11 from 2 to 7 +move 12 from 7 to 5 +move 1 from 6 to 2 +move 10 from 8 to 7 +move 6 from 5 to 3 +move 4 from 5 to 4 +move 11 from 9 to 7 +move 7 from 4 to 9 +move 4 from 9 to 6 +move 12 from 7 to 3 +move 1 from 8 to 9 +move 1 from 5 to 1 +move 1 from 1 to 2 +move 1 from 6 to 9 +move 3 from 4 to 1 +move 1 from 9 to 7 +move 8 from 7 to 2 +move 3 from 6 to 1 +move 8 from 2 to 3 +move 1 from 7 to 4 +move 2 from 7 to 2 +move 1 from 5 to 2 +move 8 from 5 to 1 +move 3 from 9 to 6 +move 1 from 6 to 2 +move 1 from 4 to 5 +move 1 from 5 to 4 +move 2 from 9 to 3 +move 1 from 8 to 6 +move 1 from 4 to 5 +move 1 from 5 to 1 +move 1 from 6 to 8 +move 1 from 8 to 1 +move 7 from 1 to 5 +move 11 from 3 to 7 +move 1 from 1 to 9 +move 4 from 2 to 1 +move 5 from 1 to 3 +move 1 from 5 to 9 +move 1 from 6 to 3 +move 6 from 2 to 1 +move 5 from 7 to 3 +move 1 from 6 to 8 +move 1 from 8 to 4 +move 6 from 7 to 9 +move 4 from 9 to 8 +move 2 from 8 to 9 +move 2 from 5 to 8 +move 13 from 3 to 7 +move 1 from 3 to 8 +move 2 from 1 to 9 +move 3 from 1 to 5 +move 1 from 4 to 1 +move 6 from 5 to 9 +move 8 from 9 to 8 +move 2 from 7 to 3 +move 1 from 9 to 7 +move 1 from 5 to 2 +move 5 from 9 to 8 +move 1 from 8 to 7 +move 1 from 2 to 9 +move 7 from 1 to 2 +move 4 from 7 to 5 +move 6 from 2 to 3 +move 1 from 2 to 1 +move 10 from 8 to 9 +move 3 from 8 to 9 +move 4 from 5 to 1 +move 2 from 8 to 6 +move 9 from 9 to 8 +move 1 from 9 to 6 +move 8 from 8 to 4 +move 12 from 3 to 5 +move 1 from 4 to 2 +move 3 from 8 to 1 +move 3 from 9 to 7 +move 1 from 3 to 2 +move 1 from 6 to 9 +move 8 from 3 to 8 +move 6 from 4 to 5 +move 1 from 7 to 6 +move 1 from 8 to 1 +move 6 from 8 to 7 +move 1 from 3 to 6 +move 7 from 1 to 5 +move 1 from 4 to 9 +move 4 from 6 to 5 +move 13 from 7 to 5 +move 1 from 8 to 2 +move 2 from 9 to 3 +move 4 from 7 to 2 +move 1 from 3 to 8 +move 1 from 3 to 4 +move 4 from 1 to 2 +move 1 from 5 to 7 +move 23 from 5 to 6 +move 1 from 8 to 6 +move 1 from 9 to 4 +move 5 from 2 to 6 +move 1 from 4 to 9 +move 1 from 9 to 3 +move 1 from 7 to 8 +move 1 from 4 to 3 +move 1 from 3 to 7 +move 1 from 7 to 5 +move 1 from 8 to 7 +move 12 from 6 to 1 +move 1 from 2 to 5 +move 1 from 3 to 1 +move 20 from 5 to 2 +move 14 from 2 to 4 +move 11 from 2 to 6 +move 1 from 7 to 8 +move 13 from 1 to 8 +move 9 from 8 to 4 +move 3 from 8 to 6 +move 10 from 6 to 8 +move 6 from 6 to 4 +move 4 from 8 to 5 +move 26 from 4 to 2 +move 2 from 5 to 2 +move 5 from 8 to 1 +move 1 from 8 to 3 +move 2 from 1 to 3 +move 2 from 3 to 7 +move 27 from 2 to 7 +move 2 from 8 to 1 +move 1 from 3 to 7 +move 6 from 6 to 2 +move 4 from 6 to 1 +move 4 from 6 to 4 +move 2 from 5 to 4 +move 4 from 2 to 1 +move 3 from 1 to 8 +move 1 from 2 to 8 +move 8 from 4 to 3 +move 1 from 2 to 8 +move 5 from 8 to 6 +move 1 from 4 to 2 +move 1 from 2 to 1 +move 6 from 3 to 1 +move 13 from 7 to 1 +move 1 from 2 to 8 +move 1 from 8 to 2 +move 1 from 6 to 2 +move 1 from 2 to 8 +move 1 from 8 to 2 +move 14 from 7 to 1 +move 5 from 6 to 3 +move 2 from 3 to 1 +move 3 from 3 to 2 +move 3 from 7 to 4 +move 1 from 4 to 9 +move 1 from 9 to 7 +move 2 from 3 to 6 +move 5 from 2 to 7 +move 1 from 7 to 6 +move 5 from 7 to 6 +move 2 from 6 to 7 +move 1 from 6 to 8 +move 1 from 4 to 7 +move 4 from 6 to 9 +move 35 from 1 to 8 +move 3 from 7 to 2 +move 1 from 2 to 5 +move 24 from 8 to 3 +move 1 from 5 to 8 +move 13 from 3 to 6 +move 2 from 2 to 6 +move 6 from 6 to 4 +move 11 from 1 to 6 +move 12 from 6 to 1 +move 1 from 8 to 1 +move 2 from 1 to 3 +move 5 from 4 to 1 +move 1 from 6 to 4 +move 1 from 8 to 3 +move 13 from 3 to 9 +move 3 from 8 to 2 +move 3 from 2 to 7 +move 1 from 3 to 6 +move 3 from 7 to 8 +move 14 from 1 to 3 +move 1 from 1 to 9 +move 6 from 3 to 8 +move 17 from 8 to 6 +move 1 from 3 to 7 +move 1 from 7 to 8 +move 26 from 6 to 7 +move 1 from 1 to 9 +move 3 from 4 to 1 +move 2 from 3 to 8 +move 1 from 8 to 4 +move 14 from 9 to 7 +move 12 from 7 to 3 +move 2 from 1 to 4 +move 2 from 7 to 8 +move 2 from 8 to 3 +move 4 from 9 to 8 +move 1 from 4 to 7 +move 1 from 1 to 3 +move 2 from 4 to 2 +move 24 from 7 to 6 +move 1 from 8 to 1 +move 1 from 7 to 2 +move 1 from 7 to 9 +move 3 from 2 to 9 +move 1 from 1 to 6 +move 5 from 8 to 2 +move 5 from 3 to 4 +move 1 from 2 to 5 +move 3 from 9 to 8 +move 2 from 4 to 9 +move 16 from 6 to 3 +move 14 from 3 to 8 +move 1 from 7 to 9 +move 8 from 6 to 9 +move 4 from 8 to 5 +move 8 from 8 to 3 +move 1 from 5 to 8 +move 1 from 2 to 4 +move 4 from 8 to 7 +move 1 from 5 to 6 +move 12 from 9 to 5 +move 15 from 5 to 8 +move 1 from 6 to 1 +move 2 from 2 to 6 +move 3 from 4 to 2 +move 4 from 2 to 7 +move 8 from 7 to 3 +move 1 from 1 to 4 +move 3 from 6 to 9 +move 16 from 8 to 3 +move 3 from 9 to 4 +move 1 from 8 to 9 +move 2 from 9 to 4 +move 24 from 3 to 8 +move 19 from 8 to 7 +move 2 from 8 to 7 +move 7 from 4 to 5 +move 13 from 7 to 5 +move 4 from 7 to 8 +move 7 from 8 to 1 +move 3 from 5 to 3 +move 3 from 7 to 2 +move 1 from 1 to 4 +move 1 from 7 to 2 +move 3 from 2 to 4 +move 8 from 3 to 1 +move 11 from 1 to 3 +move 12 from 3 to 4 +move 1 from 2 to 5 +move 18 from 3 to 8 +move 3 from 1 to 9 +move 1 from 3 to 5 +move 15 from 5 to 4 +move 4 from 5 to 1 +move 23 from 4 to 6 +move 3 from 1 to 6 +move 13 from 8 to 3 +move 25 from 6 to 2 +move 1 from 9 to 5 +move 5 from 3 to 8 +move 17 from 2 to 8 +move 4 from 4 to 1 +move 1 from 9 to 7 +move 5 from 2 to 6 +move 2 from 2 to 4 +move 1 from 9 to 4 +move 6 from 3 to 9 +move 16 from 8 to 3 +move 2 from 1 to 8 +move 1 from 7 to 4 +move 5 from 4 to 7 +move 1 from 5 to 3 +move 2 from 7 to 1 +move 9 from 8 to 4 +move 3 from 7 to 2 +move 2 from 8 to 3 +move 10 from 4 to 1 +move 1 from 2 to 3 +move 5 from 3 to 7 +move 2 from 8 to 9 +move 2 from 9 to 8 +move 1 from 2 to 1 +move 3 from 9 to 6 +move 2 from 2 to 8 +move 4 from 7 to 3 +move 4 from 8 to 6 +move 1 from 7 to 1 +move 1 from 4 to 8 +move 4 from 3 to 4 +move 4 from 4 to 2 +move 6 from 1 to 2 +move 1 from 4 to 3 +move 5 from 3 to 8 +move 6 from 3 to 8 +move 2 from 2 to 8 +move 3 from 2 to 9 +move 8 from 1 to 6 +move 3 from 2 to 7 +move 2 from 7 to 2 +move 13 from 6 to 5 +move 7 from 5 to 9 +move 3 from 2 to 7 +move 1 from 2 to 9 +move 2 from 5 to 2 +move 3 from 8 to 5 +move 5 from 3 to 4 +move 2 from 2 to 1 +move 9 from 8 to 7 +move 1 from 1 to 8 +move 6 from 5 to 2 +move 4 from 2 to 8 +move 4 from 7 to 1 +move 1 from 2 to 6 +move 5 from 1 to 6 +move 1 from 8 to 2 +move 1 from 2 to 9 +move 13 from 6 to 5 +move 2 from 7 to 2 +move 1 from 8 to 7 +move 4 from 4 to 7 +move 1 from 4 to 1 +move 4 from 8 to 4 +move 6 from 5 to 9 +move 2 from 1 to 4 +move 1 from 8 to 6 +move 11 from 9 to 5 +move 1 from 7 to 8 +move 1 from 8 to 1 +move 1 from 1 to 3 +move 6 from 4 to 8 +move 1 from 8 to 4 +move 1 from 1 to 6 +move 6 from 9 to 7 +move 1 from 4 to 5 +move 3 from 2 to 1 +move 1 from 8 to 2 +move 1 from 3 to 2 +move 20 from 5 to 6 +move 3 from 1 to 6 +move 2 from 2 to 9 +move 3 from 8 to 3 +move 5 from 3 to 8 +move 1 from 1 to 6 +move 2 from 8 to 9 +move 7 from 9 to 5 +move 3 from 5 to 4 +move 3 from 8 to 3 +move 9 from 7 to 9 +move 1 from 8 to 5 +move 7 from 7 to 9 +move 2 from 5 to 2 +move 9 from 9 to 2 +move 1 from 7 to 3 +move 2 from 9 to 1 +move 2 from 5 to 9 +move 2 from 1 to 4 +move 2 from 3 to 7 +move 18 from 6 to 7 +move 7 from 9 to 1 +move 7 from 6 to 8 +move 4 from 4 to 9 +move 4 from 8 to 3 +move 2 from 8 to 2 +move 1 from 8 to 5 +move 1 from 4 to 7 +move 1 from 5 to 1 +move 2 from 9 to 3 +move 12 from 2 to 5 +move 6 from 5 to 6 +move 5 from 7 to 2 +move 3 from 6 to 4 +move 1 from 4 to 7 +move 1 from 4 to 1 +move 2 from 5 to 8 +move 1 from 8 to 2 +move 2 from 9 to 7 +move 8 from 1 to 8 +move 11 from 7 to 1 +move 5 from 8 to 2 +move 7 from 7 to 5 +move 1 from 9 to 4 +move 1 from 7 to 5 +move 7 from 5 to 7 +move 2 from 6 to 1 +move 1 from 8 to 2 +move 12 from 1 to 7 +move 2 from 1 to 2 +move 3 from 8 to 5 +move 3 from 5 to 2 +move 8 from 7 to 3 +move 1 from 3 to 1 +move 3 from 6 to 4 +move 4 from 5 to 6 +move 14 from 2 to 9 +move 3 from 6 to 9 +move 3 from 4 to 2 +move 1 from 1 to 7 +move 1 from 7 to 1 +move 3 from 3 to 5 +move 8 from 7 to 4 +move 1 from 5 to 9 +move 3 from 2 to 4 +move 1 from 3 to 4 +move 4 from 2 to 6 +move 2 from 6 to 7 +move 3 from 5 to 4 +move 16 from 4 to 1 +move 7 from 9 to 8 +move 1 from 5 to 1 +move 3 from 7 to 9 +move 3 from 9 to 4 +move 7 from 1 to 7 +move 6 from 7 to 1 +move 5 from 3 to 1 +move 11 from 9 to 2 +move 3 from 4 to 6 +move 9 from 2 to 8 +move 6 from 3 to 5 +move 2 from 8 to 6 +move 5 from 5 to 3 +move 2 from 7 to 1 +move 3 from 3 to 9 +move 1 from 2 to 4 +move 1 from 5 to 1 +move 13 from 1 to 2 +move 5 from 8 to 6 +move 2 from 3 to 9 +move 2 from 4 to 7 +move 5 from 6 to 9 +move 7 from 9 to 1 +move 3 from 7 to 2 +move 6 from 8 to 6 +move 5 from 6 to 2 +move 2 from 8 to 3 +move 2 from 9 to 4 +move 6 from 2 to 5 +move 1 from 3 to 7 \ No newline at end of file diff --git a/src/day05/Day5Lib.hs b/src/day05/Day5Lib.hs new file mode 100644 index 0000000..f99fa27 --- /dev/null +++ b/src/day05/Day5Lib.hs @@ -0,0 +1,115 @@ +module Day5Lib + ( Crate (..), + Command (..), + crate, + crateOrNothing, + crateRow, + crateNumbers, + command, + transposeRows, + -- + processInput1, + processInput2, + ) +where + +-- import Text.ParserCombinators.Parsec +import Debug.Trace +import Text.Parsec + +newtype Crate = Crate Char deriving (Show, Eq) + +data Command = Command + { cnt :: Int, + from :: Int, + to :: Int + } + deriving (Show, Eq) + +crate :: Parsec String () Crate +crate = do + char '[' + crateLabel <- oneOf ['A' .. 'Z'] + char ']' + return $ Crate crateLabel + +nothing = do + string " " + return Nothing + +crateOrNothing :: Parsec String () (Maybe Crate) +crateOrNothing = nothing <|> (crate >>= return . return) + +crateRow :: Parsec String () [Maybe Crate] +crateRow = do + c <- crateOrNothing `sepBy1` (char ' ') + char '\n' + return c + +crateNumbers :: Parsec String () () +crateNumbers = do + char ' ' + oneOf ['1' .. '9'] `sepBy1` try (string " ") + char ' ' + char '\n' + return () + +command :: Parsec String () Command +command = do + string "move " + countS <- many $ oneOf ['0' .. '9'] + char ' ' + string "from " + from <- many $ oneOf ['0' .. '9'] + char ' ' + string "to " + to <- many $ oneOf ['0' .. '9'] + -- char '\n' + return Command {cnt = read countS, from = read from - 1, to = read to - 1} + +taskFile = do + crateRows <- many (try crateRow) + crateNumbers + char '\n' + commands <- sepBy command (char '\n') + eof + return (transposeRows crateRows, commands) + +transposeRows :: [[Maybe Crate]] -> [[Crate]] +transposeRows = foldr applyRow (repeat []) + +applyRow :: [Maybe Crate] -> [[Crate]] -> [[Crate]] +applyRow (Nothing : ow) (s : tacks) = s : (applyRow ow tacks) +applyRow ((Just c) : ow) (s : tacks) = (c : s) : (applyRow ow tacks) +applyRow [] stacks = [] +applyRow _ [] = error "stacks error" + +applyCommand1 :: [[Crate]] -> Command -> [[Crate]] +applyCommand1 crates cmd = last . take (cnt cmd + 1) . iterate applyThisMove $ crates + where + applyThisMove = applyMove 1 (from cmd) (to cmd) + +applyCommand :: [[Crate]] -> Command -> [[Crate]] +applyCommand crates cmd = applyMove (cnt cmd) (from cmd) (to cmd) crates + +applyMove :: Int -> Int -> Int -> [[Crate]] -> [[Crate]] +applyMove cnt from to crates = + let (lf, f : rf) = splitAt from crates + (lt, t : rt) = splitAt to (lf ++ (drop cnt f) : rf) + in lt ++ ((take cnt f) ++ t) : rt + +-- #################### + +processInput1 :: String -> String +processInput1 input = + let (crates, commands) = case parse taskFile "" input of + Left e -> error (show e) + Right p -> p + in map ((\(Crate a) -> a) . head) $ foldl applyCommand1 crates commands + +processInput2 :: String -> String +processInput2 input = + let (crates, commands) = case parse taskFile "" input of + Left e -> error (show e) + Right p -> p + in map ((\(Crate a) -> a) . head) $ foldl applyCommand crates commands diff --git a/src/day05/test/AoCTest.hs b/src/day05/test/AoCTest.hs new file mode 100644 index 0000000..c41488b --- /dev/null +++ b/src/day05/test/AoCTest.hs @@ -0,0 +1,41 @@ +import Day5Lib (processInput1, processInput2) +import System.IO +import Test.HUnit + +testCases1 = + [ ("data/input050.txt", "CMZ"), + ("data/input051.txt", "MQSHJMWNH") + ] + +testCase1 (file, result) = do + withFile + file + ReadMode + ( \handle -> do + contents <- hGetContents handle + assertEqual "input test" result $ processInput1 contents + ) + +testCases2 = + [ ("data/input050.txt", "MCD"), + ("data/input051.txt", "LLWJRBHVZ") + ] + +testCase2 (file, result) = do + withFile + file + ReadMode + ( \handle -> do + contents <- hGetContents handle + assertEqual "input test" result $ processInput2 contents + ) + +tests = + TestList $ + [TestCase (testCase1 c) | c <- testCases1] + ++ [TestCase (testCase2 c) | c <- testCases2] + +main :: IO () +main = do + runTestTT tests + return () diff --git a/src/day05/test/Basic.hs b/src/day05/test/Basic.hs new file mode 100644 index 0000000..7e79677 --- /dev/null +++ b/src/day05/test/Basic.hs @@ -0,0 +1,89 @@ +import Day5Lib +import Test.HUnit +import Text.Parsec + +-- trange = TestCase (assertEqual "1-2" (Range (1,2)) $ parseRange "1-2") +-- trangel = TestCase (assertEqual "131231-215562" (Range (131231,215562)) $ parseRange "1-2") + +-- trow = TestCase (assertEqual "1-2,3-4" [Range (1,2), Range(3,4)] $ parseRow "1-2,3-4") +-- trowl = TestCase (assertEqual "1-2,3-4" [Range (1,2), Range(34524,62345)] $ parseRow "1-2,34524-62345") + +tParseCrate = TestCase $ assertEqual "parse crate" (Right (Crate 'A')) (parse crate "" "[A]") + +tParseCrateOrNothing1 = + TestCase $ + assertEqual + "parse crate or nothing: crate" + (Right (Just (Crate 'A'))) + (parse crateOrNothing "" "[A]") + +tParseCrateOrNothing2 = + TestCase $ + assertEqual + "parse crate or nothing: nothing" + (Right Nothing) + (parse crateOrNothing "" " ") + +tCrateRow = + TestCase $ + assertEqual + "parse row" + (Right [Nothing, Just (Crate 'D'), Nothing]) + (parse crateRow "" " [D] \n") + +tNumberRow = + TestCase $ + assertEqual + "number row" + (Right ()) + (parse crateNumbers " " " 1 2 3 \n") + +tCommand1 = + TestCase $ + assertEqual + "command" + (Right Command {cnt = 1, from = 0, to = 1}) + (parse command " " "move 1 from 1 to 2\n") + +tCommand2 = + TestCase $ + assertEqual + "command" + (Right Command {cnt = 1, from = 0, to = 1}) + (parse command " " "move 1 from 1 to 2") + +tStackBuild1 = + TestCase $ + assertEqual + "stack build" + [[], [Crate 'D'], []] + (transposeRows [[Nothing, Just (Crate 'D'), Nothing]]) + +tStackBuild2 = + TestCase $ + assertEqual + "stack build" + [[Crate 'A'], [Crate 'D', Crate 'B'], [Crate 'C']] + ( transposeRows + [ [Nothing, Just (Crate 'D'), Nothing], + [Just (Crate 'A'), Just (Crate 'B'), Just (Crate 'C')] + ] + ) + +tests = + TestList $ + [ tParseCrate, + tParseCrateOrNothing1, + tParseCrateOrNothing2, + tCrateRow, + tNumberRow, + tCommand1, + tCommand2, + tStackBuild1, + tStackBuild2 + ] + +main :: IO () +main = do + runTestTT tests + return ()