From 9bd3d62eec6fa8019ceb990ad461a38cd1addb60 Mon Sep 17 00:00:00 2001 From: Jens Kadenbach Date: Fri, 9 Dec 2022 15:23:38 +0100 Subject: [PATCH] Day 9 - Part 1 --- aoc2022.cabal | 5 + package.yaml | 1 + ressources/day09-input | 2000 ++++++++++++++++++++++++++++++++++++++++ src/Day9.hs | 110 +++ src/Lib.hs | 21 +- test/Day9Spec.hs | 79 ++ 6 files changed, 2206 insertions(+), 10 deletions(-) create mode 100644 ressources/day09-input create mode 100644 src/Day9.hs create mode 100644 test/Day9Spec.hs diff --git a/aoc2022.cabal b/aoc2022.cabal index 0b0dc3f..207b6e7 100644 --- a/aoc2022.cabal +++ b/aoc2022.cabal @@ -48,6 +48,7 @@ library Day7.Interpreter Day7.Parser Day8 + Day9 Lib Shared other-modules: @@ -67,6 +68,7 @@ library , parsec , split , text + , transformers , vector default-language: Haskell2010 @@ -90,6 +92,7 @@ executable aoc2022-exe , parsec , split , text + , transformers , vector default-language: Haskell2010 @@ -105,6 +108,7 @@ test-suite aoc2022-test Day6Spec Day7Spec Day8Spec + Day9Spec Paths_aoc2022 hs-source-dirs: test @@ -122,5 +126,6 @@ test-suite aoc2022-test , parsec , split , text + , transformers , vector default-language: Haskell2010 diff --git a/package.yaml b/package.yaml index ac76f5c..2fcedee 100644 --- a/package.yaml +++ b/package.yaml @@ -33,6 +33,7 @@ dependencies: - matrix - vector - megaparsec +- transformers ghc-options: - -Wall diff --git a/ressources/day09-input b/ressources/day09-input new file mode 100644 index 0000000..448850e --- /dev/null +++ b/ressources/day09-input @@ -0,0 +1,2000 @@ +D 2 +R 1 +U 1 +L 1 +D 2 +L 2 +R 1 +U 1 +D 2 +U 1 +R 1 +U 1 +D 2 +R 2 +L 2 +U 2 +D 1 +L 2 +R 2 +D 2 +U 2 +R 2 +U 1 +D 1 +L 2 +D 2 +L 2 +U 1 +R 2 +L 2 +D 2 +L 1 +D 2 +L 1 +R 2 +L 2 +U 1 +D 2 +L 1 +U 2 +R 1 +D 2 +L 2 +D 1 +L 2 +U 1 +L 1 +R 2 +U 2 +L 2 +D 1 +L 1 +D 1 +L 2 +R 1 +D 2 +U 2 +D 2 +R 1 +L 2 +R 2 +U 1 +R 1 +L 2 +U 2 +D 1 +U 2 +L 1 +R 2 +D 2 +L 2 +U 1 +L 1 +D 2 +R 2 +U 1 +R 2 +U 2 +D 2 +L 1 +U 1 +D 1 +R 1 +U 1 +D 2 +L 1 +D 2 +U 2 +D 1 +U 2 +L 2 +D 2 +R 2 +D 1 +R 2 +L 2 +U 1 +R 1 +L 1 +U 2 +D 2 +U 2 +L 2 +U 2 +R 2 +L 1 +U 1 +D 1 +L 2 +D 2 +R 2 +U 3 +R 3 +U 2 +L 1 +U 1 +L 1 +U 2 +R 2 +U 2 +D 1 +R 3 +D 1 +L 3 +R 2 +D 3 +U 1 +D 2 +L 2 +D 2 +L 1 +R 3 +D 1 +R 1 +L 3 +R 1 +U 2 +D 2 +L 3 +R 1 +U 2 +L 2 +R 3 +D 1 +U 2 +D 2 +L 3 +D 1 +R 3 +U 3 +R 2 +U 3 +D 1 +U 2 +R 2 +U 3 +R 1 +U 2 +L 3 +D 3 +U 1 +D 2 +U 2 +L 2 +R 1 +L 3 +R 1 +L 3 +U 2 +R 1 +U 1 +L 1 +R 2 +U 2 +D 1 +R 3 +D 3 +L 2 +D 2 +R 2 +L 3 +R 1 +L 1 +R 3 +L 3 +D 2 +U 1 +L 2 +U 3 +R 1 +L 1 +R 1 +L 1 +D 1 +R 2 +D 2 +U 1 +L 1 +D 3 +R 2 +D 1 +L 3 +R 3 +U 3 +D 2 +U 1 +D 2 +R 1 +U 1 +R 2 +D 2 +U 1 +D 3 +R 2 +U 3 +D 3 +R 1 +D 1 +U 2 +D 1 +U 2 +D 3 +U 3 +D 2 +R 4 +D 2 +R 1 +L 4 +U 2 +D 1 +U 2 +R 2 +U 1 +R 1 +U 4 +L 4 +U 3 +L 2 +U 3 +D 3 +R 2 +L 2 +U 3 +D 1 +L 3 +U 1 +L 1 +U 2 +L 4 +R 3 +U 3 +D 1 +L 3 +R 4 +D 4 +L 3 +R 4 +D 1 +R 4 +D 1 +L 3 +D 1 +L 1 +U 2 +D 1 +U 4 +R 1 +D 2 +U 2 +D 4 +U 3 +D 2 +L 4 +R 3 +U 3 +R 2 +D 3 +U 4 +R 4 +L 3 +U 2 +D 2 +U 2 +L 1 +R 3 +D 4 +U 1 +D 2 +U 1 +R 2 +L 2 +R 3 +U 4 +D 1 +L 1 +R 1 +D 4 +L 4 +D 4 +L 2 +R 3 +L 1 +U 2 +L 1 +D 3 +U 2 +R 2 +D 1 +R 1 +U 1 +L 2 +D 2 +U 3 +L 3 +U 1 +L 1 +D 1 +L 3 +R 4 +L 2 +R 1 +U 2 +D 4 +U 2 +L 4 +U 4 +R 1 +D 3 +U 2 +L 2 +D 4 +L 2 +U 1 +D 5 +L 5 +R 1 +D 1 +L 4 +D 5 +R 4 +U 2 +R 2 +L 2 +D 3 +U 4 +L 1 +U 1 +R 2 +L 4 +R 3 +U 1 +D 5 +U 4 +D 2 +R 3 +L 1 +D 4 +L 5 +D 1 +L 2 +U 1 +R 2 +L 2 +R 1 +L 2 +U 4 +D 1 +U 5 +L 2 +R 1 +D 5 +L 2 +D 5 +U 5 +R 3 +L 4 +D 2 +L 2 +D 2 +U 5 +R 3 +U 1 +D 3 +R 4 +U 3 +R 2 +U 3 +D 5 +U 4 +L 3 +R 3 +D 3 +R 1 +L 1 +D 4 +R 3 +D 2 +L 2 +R 4 +L 3 +R 2 +D 4 +L 3 +U 1 +D 2 +L 3 +U 4 +D 5 +U 2 +L 2 +R 1 +D 1 +L 3 +U 2 +R 4 +D 4 +L 4 +U 2 +D 1 +R 5 +L 3 +U 3 +L 5 +R 2 +D 1 +L 2 +D 2 +L 2 +R 4 +L 3 +D 3 +R 5 +L 5 +D 3 +R 5 +L 2 +R 1 +D 4 +L 2 +D 1 +U 2 +D 4 +U 5 +L 4 +D 2 +U 2 +D 4 +U 6 +L 3 +U 1 +D 2 +R 1 +U 5 +D 2 +L 4 +R 6 +U 2 +L 2 +D 1 +R 5 +U 2 +D 5 +R 5 +U 4 +D 6 +U 1 +D 2 +U 5 +D 5 +L 6 +U 5 +D 6 +L 4 +U 6 +R 5 +L 6 +D 5 +L 5 +D 6 +U 5 +L 6 +U 5 +L 3 +R 2 +D 1 +R 1 +L 6 +U 5 +D 1 +R 2 +D 2 +L 2 +D 6 +U 6 +L 1 +R 6 +L 3 +D 6 +R 3 +D 2 +U 5 +D 4 +L 2 +R 3 +D 5 +U 1 +D 3 +R 6 +U 4 +L 4 +U 4 +D 1 +R 4 +U 2 +R 6 +L 1 +D 3 +R 3 +U 1 +L 6 +R 4 +D 2 +U 2 +D 6 +L 4 +R 6 +U 3 +R 3 +D 3 +L 1 +R 5 +U 4 +R 6 +L 2 +R 1 +U 1 +L 6 +D 6 +L 3 +R 2 +D 6 +R 6 +L 3 +U 3 +D 1 +L 3 +D 1 +R 4 +D 3 +U 3 +D 2 +U 6 +D 4 +L 4 +R 5 +D 1 +L 7 +R 3 +L 5 +R 3 +U 6 +L 5 +U 3 +D 1 +L 5 +R 4 +L 1 +U 6 +L 1 +R 4 +D 3 +R 7 +D 7 +R 4 +L 4 +D 4 +L 2 +R 1 +U 7 +L 1 +D 7 +L 1 +D 1 +R 5 +D 5 +U 2 +L 6 +R 2 +U 5 +L 7 +D 7 +L 7 +U 1 +L 6 +D 2 +L 6 +U 2 +R 4 +U 7 +D 2 +L 6 +U 7 +R 5 +U 7 +L 7 +D 2 +R 4 +U 6 +R 1 +D 3 +R 2 +L 5 +R 5 +U 3 +L 5 +U 4 +D 4 +L 5 +R 1 +L 4 +D 5 +U 1 +L 4 +D 7 +R 6 +D 7 +U 7 +D 4 +R 1 +D 2 +L 5 +R 4 +D 3 +U 2 +D 4 +R 3 +L 4 +R 4 +U 3 +D 7 +R 2 +L 1 +D 5 +R 3 +D 2 +L 7 +R 3 +D 5 +R 1 +D 2 +R 6 +L 5 +R 7 +L 5 +U 2 +R 3 +D 6 +L 1 +D 4 +R 2 +U 1 +D 1 +R 6 +D 5 +L 3 +R 7 +L 3 +U 5 +R 5 +U 3 +D 8 +L 2 +U 6 +L 8 +U 4 +D 5 +R 7 +U 7 +L 4 +R 3 +L 3 +D 1 +L 6 +R 5 +L 6 +R 6 +L 8 +D 3 +U 2 +L 7 +R 2 +U 8 +D 3 +L 4 +R 3 +U 8 +R 3 +U 6 +D 8 +R 2 +L 8 +U 2 +R 5 +D 1 +U 1 +D 8 +R 4 +L 7 +D 2 +U 3 +D 1 +R 2 +U 1 +L 5 +U 4 +R 5 +D 6 +L 3 +U 1 +D 6 +U 6 +D 6 +U 2 +L 6 +U 6 +D 5 +L 1 +D 7 +U 2 +D 4 +L 5 +R 4 +D 2 +L 6 +U 2 +R 1 +U 4 +L 3 +D 3 +R 6 +D 4 +R 3 +L 2 +U 8 +R 5 +L 2 +U 3 +R 7 +U 7 +R 4 +U 5 +D 1 +L 8 +R 8 +U 3 +L 1 +U 7 +L 7 +D 2 +L 8 +D 7 +R 7 +L 3 +R 4 +L 3 +R 4 +U 6 +L 5 +R 4 +U 7 +L 3 +D 3 +R 2 +L 6 +U 3 +L 1 +R 8 +L 6 +D 7 +L 8 +R 7 +L 6 +D 2 +U 2 +R 3 +L 9 +R 7 +D 1 +R 9 +L 2 +D 5 +U 7 +D 5 +U 4 +L 4 +D 5 +L 6 +R 3 +U 2 +R 6 +D 3 +U 2 +R 1 +D 5 +U 6 +L 8 +D 8 +U 9 +L 2 +U 5 +L 2 +U 3 +L 4 +U 6 +L 3 +D 2 +R 5 +L 3 +R 8 +D 8 +U 8 +R 4 +U 2 +D 3 +L 9 +U 2 +L 4 +U 5 +R 5 +L 7 +U 9 +L 7 +U 5 +L 6 +U 6 +R 5 +L 9 +U 9 +R 3 +D 8 +U 8 +R 9 +D 4 +U 9 +D 9 +L 3 +R 2 +D 3 +U 1 +R 7 +D 5 +U 9 +D 7 +U 3 +D 8 +L 9 +U 1 +R 6 +L 8 +R 2 +L 7 +D 3 +U 4 +D 9 +L 1 +R 4 +D 9 +U 1 +D 1 +L 8 +U 2 +D 8 +U 1 +L 1 +U 2 +D 7 +L 1 +D 2 +L 6 +U 2 +D 8 +R 7 +L 4 +U 5 +R 2 +U 8 +D 6 +R 3 +D 8 +R 4 +L 5 +U 4 +L 1 +U 6 +L 10 +D 7 +R 5 +D 9 +U 6 +D 5 +L 9 +U 2 +R 3 +U 7 +R 7 +D 1 +R 4 +U 10 +D 4 +R 7 +L 7 +D 3 +R 5 +U 5 +D 6 +U 2 +D 2 +U 6 +D 5 +L 6 +U 10 +D 7 +R 6 +L 9 +R 7 +L 7 +U 6 +D 6 +R 8 +D 8 +R 4 +D 4 +L 1 +R 3 +U 5 +R 2 +L 9 +R 8 +L 3 +U 3 +R 6 +U 2 +L 6 +U 4 +D 5 +R 6 +U 5 +R 8 +U 10 +L 5 +U 2 +R 1 +D 9 +U 8 +D 2 +U 9 +L 7 +R 2 +D 10 +L 7 +D 3 +R 4 +L 2 +U 2 +R 7 +U 6 +D 9 +U 8 +L 7 +D 4 +U 4 +R 6 +U 3 +D 9 +L 1 +U 9 +R 9 +D 4 +L 9 +R 6 +L 6 +U 9 +L 10 +R 1 +L 5 +R 1 +L 2 +D 8 +U 2 +L 1 +R 4 +U 9 +L 3 +D 9 +L 6 +R 8 +U 6 +R 8 +L 5 +D 2 +R 5 +U 8 +R 2 +L 9 +R 3 +U 3 +R 8 +U 5 +D 5 +U 8 +D 10 +R 4 +L 5 +U 2 +L 4 +D 2 +L 1 +D 3 +U 8 +D 3 +U 4 +L 6 +D 6 +U 9 +L 5 +D 5 +U 10 +R 9 +D 2 +U 11 +D 4 +L 8 +D 8 +L 4 +U 6 +D 3 +R 9 +U 11 +L 7 +U 7 +D 9 +U 10 +D 9 +U 2 +R 2 +U 7 +R 2 +U 10 +R 7 +L 7 +U 6 +D 10 +L 5 +U 4 +D 4 +L 3 +D 3 +L 2 +R 5 +D 5 +U 10 +R 3 +U 8 +L 10 +U 5 +R 3 +L 9 +R 5 +D 1 +L 8 +R 8 +D 10 +L 6 +D 5 +L 6 +R 7 +D 10 +U 3 +D 9 +L 8 +D 5 +U 10 +L 5 +U 4 +D 7 +U 11 +L 6 +U 6 +L 9 +R 6 +U 8 +R 8 +L 6 +U 8 +L 8 +U 9 +D 4 +L 10 +D 6 +R 5 +D 8 +L 7 +D 6 +R 4 +D 11 +U 5 +D 4 +R 7 +U 11 +L 5 +U 7 +D 7 +L 11 +R 9 +U 1 +D 11 +R 8 +L 4 +R 2 +D 6 +L 4 +R 8 +D 9 +R 11 +U 2 +L 9 +U 6 +R 10 +L 11 +R 9 +D 10 +U 11 +L 6 +U 3 +L 2 +R 11 +L 2 +D 2 +L 5 +D 6 +U 11 +D 10 +U 8 +L 3 +R 9 +D 5 +R 9 +D 6 +R 2 +U 2 +D 11 +R 6 +U 9 +R 12 +U 6 +L 1 +D 2 +L 5 +D 9 +L 5 +D 4 +U 10 +L 12 +U 6 +R 6 +U 4 +L 4 +U 1 +L 4 +R 12 +L 11 +R 3 +U 10 +L 4 +R 11 +D 9 +L 9 +U 11 +D 1 +L 1 +R 3 +D 7 +U 6 +R 4 +D 3 +L 8 +U 5 +R 6 +L 9 +U 4 +L 6 +D 6 +U 6 +L 5 +R 7 +D 10 +R 5 +U 8 +L 5 +R 6 +U 10 +R 2 +U 2 +R 10 +U 12 +D 12 +L 7 +U 3 +R 1 +L 6 +D 6 +L 5 +D 8 +U 8 +D 11 +L 2 +D 10 +L 6 +R 10 +L 9 +D 5 +R 1 +D 7 +R 6 +U 10 +D 8 +R 9 +D 11 +R 8 +U 7 +R 10 +L 1 +U 3 +R 11 +D 11 +L 8 +D 13 +U 6 +D 12 +U 2 +L 2 +U 11 +D 1 +R 3 +U 8 +R 4 +L 3 +U 7 +D 4 +L 3 +R 2 +L 3 +R 6 +D 13 +L 1 +R 8 +L 5 +R 11 +D 7 +L 8 +D 12 +U 12 +D 3 +L 6 +U 1 +R 7 +U 2 +D 9 +L 3 +U 11 +R 2 +U 6 +D 11 +L 10 +D 4 +U 13 +D 1 +R 11 +L 3 +U 2 +D 7 +R 8 +D 10 +R 12 +D 4 +R 1 +U 5 +R 5 +U 2 +R 12 +D 3 +L 8 +D 11 +U 3 +R 1 +U 2 +R 3 +D 5 +U 8 +D 4 +R 6 +L 2 +R 4 +U 6 +D 12 +L 7 +U 2 +L 8 +U 8 +R 13 +U 10 +L 11 +R 1 +D 4 +R 1 +U 5 +L 9 +D 9 +U 11 +D 13 +U 9 +R 2 +D 9 +U 6 +R 1 +D 12 +R 3 +U 1 +R 13 +U 11 +L 6 +R 3 +D 11 +U 13 +R 2 +U 8 +L 11 +R 12 +D 7 +L 11 +U 10 +D 2 +L 9 +R 1 +L 9 +R 10 +D 5 +U 7 +R 6 +D 11 +U 11 +L 7 +R 6 +L 12 +D 12 +L 5 +R 3 +L 12 +R 4 +L 7 +D 4 +U 11 +R 2 +L 9 +R 11 +D 14 +L 7 +R 10 +U 1 +D 2 +L 7 +D 2 +U 12 +R 2 +D 6 +R 12 +L 7 +D 4 +U 13 +L 11 +D 13 +R 11 +D 5 +U 14 +R 1 +L 8 +U 10 +R 3 +D 3 +L 13 +R 6 +U 5 +D 4 +L 12 +D 2 +R 9 +D 1 +R 7 +D 10 +U 14 +L 12 +R 11 +U 6 +D 11 +L 8 +D 2 +U 4 +L 1 +R 14 +D 8 +U 11 +L 13 +U 1 +D 2 +R 14 +D 10 +R 4 +L 1 +R 10 +U 9 +D 8 +L 10 +R 10 +U 6 +D 14 +L 10 +U 13 +R 8 +L 3 +D 6 +L 13 +D 11 +U 14 +R 13 +U 12 +L 2 +D 6 +U 13 +L 13 +U 12 +D 1 +U 10 +L 5 +U 3 +R 4 +D 10 +L 14 +U 8 +R 7 +U 6 +R 13 +D 14 +L 5 +U 6 +L 1 +D 7 +R 2 +D 14 +U 13 +R 3 +U 5 +R 13 +L 2 +D 12 +U 1 +R 11 +L 7 +U 2 +D 11 +L 2 +R 7 +D 7 +L 1 +U 10 +L 12 +R 6 +L 7 +R 4 +D 3 +R 3 +U 15 +D 13 +U 6 +D 6 +U 3 +R 14 +U 10 +L 1 +R 8 +D 7 +R 13 +D 10 +R 9 +U 11 +D 11 +U 4 +D 11 +U 10 +D 3 +R 12 +U 5 +D 1 +L 4 +R 10 +D 11 +U 2 +D 9 +U 12 +D 9 +R 3 +D 6 +U 4 +L 14 +R 15 +U 4 +D 11 +R 13 +L 3 +U 12 +R 5 +U 11 +L 11 +D 6 +U 15 +R 5 +U 5 +R 1 +D 8 +U 4 +L 12 +D 2 +U 9 +L 15 +D 6 +R 12 +L 10 +D 14 +R 14 +D 8 +L 2 +D 11 +U 13 +L 1 +R 8 +D 8 +L 5 +D 14 +R 10 +U 13 +R 10 +L 4 +R 5 +L 6 +U 7 +R 7 +L 5 +D 3 +L 15 +U 10 +D 6 +L 1 +R 15 +D 11 +U 13 +R 12 +U 4 +D 8 +L 4 +D 11 +R 12 +L 5 +D 2 +U 8 +D 8 +L 10 +U 16 +L 15 +D 9 +U 10 +R 16 +L 7 +R 7 +U 9 +D 12 +L 16 +U 12 +R 13 +U 5 +R 5 +U 8 +D 8 +U 15 +L 4 +R 2 +L 2 +U 10 +D 2 +U 6 +L 15 +R 11 +D 2 +L 5 +R 16 +L 13 +R 14 +U 5 +R 2 +L 11 +U 9 +D 4 +L 14 +U 6 +D 6 +U 7 +D 2 +U 5 +D 6 +U 10 +D 5 +L 11 +R 13 +L 9 +U 5 +R 7 +D 13 +U 12 +L 6 +U 14 +R 15 +L 3 +U 4 +D 4 +U 8 +R 1 +U 12 +L 7 +U 2 +L 11 +R 10 +D 6 +R 9 +L 6 +R 2 +L 16 +U 8 +D 16 +R 8 +U 7 +D 7 +U 12 +D 13 +L 14 +R 3 +U 7 +L 14 +R 14 +U 4 +D 15 +R 13 +D 2 +R 9 +D 14 +U 15 +D 8 +L 8 +R 10 +U 4 +D 5 +L 16 +D 17 +R 14 +U 10 +D 15 +L 15 +R 13 +L 17 +U 12 +R 1 +D 8 +U 2 +R 11 +U 8 +D 9 +R 6 +U 10 +D 3 +L 7 +R 4 +L 15 +U 14 +L 9 +R 15 +U 9 +D 5 +U 4 +D 10 +R 13 +U 9 +D 5 +R 12 +D 6 +U 7 +D 8 +L 7 +U 13 +D 5 +R 4 +L 10 +D 16 +L 11 +R 16 +L 16 +U 15 +D 1 +R 3 +L 13 +D 7 +U 1 +R 15 +U 15 +D 2 +U 3 +L 7 +U 4 +D 14 +L 10 +D 8 +U 8 +D 6 +R 16 +U 6 +D 7 +L 13 +U 3 +L 9 +R 10 +D 5 +R 2 +D 16 +U 14 +R 11 +D 10 +R 13 +U 12 +L 4 +U 7 +L 2 +R 5 +D 13 +U 3 +R 3 +U 16 +L 5 +R 13 +L 16 +D 7 +L 4 +R 14 +U 8 +L 9 +U 2 +L 10 +D 9 +R 17 +U 14 +R 2 +D 7 +U 14 +R 3 +U 3 +L 14 +D 16 +U 6 +L 5 +U 2 +R 7 +L 4 +U 3 +D 12 +L 7 +D 15 +U 6 +L 1 +D 5 +U 11 +L 9 +D 15 +L 12 +R 18 +L 4 +D 9 +U 17 +R 1 +D 5 +L 13 +U 16 +R 17 +U 10 +D 5 +L 16 +D 2 +R 10 +L 1 +U 14 +L 16 +U 3 +D 2 +R 5 +U 3 +R 17 +D 17 +L 15 +U 11 +L 16 +R 4 +L 3 +R 7 +L 5 +R 8 +U 15 +R 9 +U 9 +R 18 +L 17 +R 9 +U 18 +L 11 +U 14 +R 7 +L 16 +R 15 +L 1 +U 9 +L 10 +U 9 +L 14 +U 5 +D 1 +R 16 +D 6 +R 1 +D 14 +R 11 +U 10 +D 17 +L 12 +D 5 +U 4 +L 12 +U 1 +L 7 +R 13 +D 2 +U 14 +D 3 +U 6 +R 1 +U 2 +R 11 +U 9 +D 14 +R 9 +U 14 +R 9 +D 14 +R 2 +D 9 +U 8 +D 10 +U 3 +R 8 +D 11 +R 5 +U 4 +D 1 +U 16 +L 17 +U 1 +R 14 +U 10 +R 5 +U 12 +D 4 +R 10 +D 10 +L 5 +R 2 +L 18 +D 3 +L 17 +D 10 +U 4 +L 15 +U 4 +L 9 +U 14 +R 9 +U 16 +L 1 +R 7 +U 10 +D 1 +U 13 +D 15 +R 6 +U 2 +L 17 +U 11 +L 14 +U 12 +R 11 +U 4 +D 11 +R 7 +D 13 +U 16 +L 5 +U 7 +R 4 +L 17 +D 2 +U 18 +R 8 +U 16 +L 15 +R 8 +L 19 +U 17 +D 2 +U 8 +D 9 +U 3 +L 12 +U 16 +L 3 +R 14 +D 16 +U 11 +D 2 +L 16 +U 4 +L 18 +R 15 +U 9 +L 18 +U 11 +R 18 +L 13 +D 8 +U 12 +D 14 +L 12 +U 2 +D 13 +L 12 +U 16 +R 17 +L 14 +U 10 +R 15 +U 19 +L 17 +R 8 +L 17 +R 8 +U 4 +R 8 +U 11 +L 17 +R 8 +D 13 +U 6 +D 7 +R 9 +L 2 +R 4 +D 16 +L 2 +D 10 +U 4 +L 10 +D 14 +U 5 +D 7 +U 4 +D 16 +U 14 +L 4 +U 14 +L 3 +D 16 +L 14 +U 11 +D 3 +L 10 +U 8 +D 6 +L 9 +D 17 +R 16 diff --git a/src/Day9.hs b/src/Day9.hs new file mode 100644 index 0000000..89ed3e1 --- /dev/null +++ b/src/Day9.hs @@ -0,0 +1,110 @@ +module Day9 + ( parseMovements, + Move (..), + Grid (..), + startGrid, + up, + down, + left, + right, + diag, + still, + step, + recordPositions, + normalizeMovement, + Step (..), + follow, + day9 + ) +where + +import Control.Arrow ((>>>)) +import Data.List (nub) + +newtype Move = Move (Int, Int) + deriving (Show, Eq) + +newtype Step = Step (Int, Int) + deriving (Show, Eq) + +up :: Int -> Move +up y = Move (0, y) + +down :: Int -> Move +down y = Move (0, y * (-1)) + +left :: Int -> Move +left x = Move (x * (-1), 0) + +right :: Int -> Move +right x = Move (x, 0) + +diag :: Int -> Move +diag x = Move (x, x) + +still :: Move +still = Move (0, 0) + +type Pos = (Int, Int) + +data Grid = Grid {h :: Pos, t :: Pos} deriving (Show, Eq) + +recordPositions :: [Step] -> [Pos] +recordPositions steps = nub (lastTailPos:positions) + where + (positions, _, Grid { t = lastTailPos}) = recordPositions' [] steps startGrid + recordPositions' :: [Pos] -> [Step] -> Grid -> ([Pos], [Step], Grid) + recordPositions' pos [] grid = (pos, [], grid) + recordPositions' pos (m : ms) Grid {h = headPos, t = tailPos} = + let newHead = headPos `step` m + followStep = follow newHead tailPos + newTail = tailPos `step` followStep + in recordPositions' (tailPos : pos) ms Grid {h = newHead, t = newTail} + +startGrid :: Grid +startGrid = Grid {h = p, t = p} + where + p = (0, 0) + +parseMovements :: String -> [Move] +parseMovements = lines >>> map toMove + where + toMove ('U' : ' ' : xs) = up $ read xs + toMove ('D' : ' ' : xs) = down $ read xs + toMove ('L' : ' ' : xs) = left $ read xs + toMove ('R' : ' ' : xs) = right $ read xs + toMove _ = error "cannot parse movement" + +normalizeMovement :: Move -> [Step] +normalizeMovement (Move (dx, 0)) = replicate (abs dx) (Step (signum dx, 0)) +normalizeMovement (Move (0, dy)) = replicate (abs dy) (Step (0, signum dy)) +normalizeMovement m = error $ "cannot normalize movement: " ++ show m + +step :: Pos -> Step -> Pos +step (x, y) (Step (dx, dy)) = (x + dx, y + dy) + +distance :: Pos -> Pos -> Int +distance (x, y) (x2, y2) = floor (dx ** 2 + dy ** 2) + where + dx :: Double + dx = fromIntegral $ x - x2 + dy :: Double + dy = fromIntegral $ y - y2 + +follow :: Pos -> Pos -> Step +follow p1@(x1, y1) p2@(x2, y2) + | distance p1 p2 > 2 = Step (signum dx, signum dy) + | abs dx == 2 = Step (signum dx, 0) + | abs dy == 2 = Step (0, signum dy) + | otherwise = Step (0, 0) + where + dx = x1 - x2 + dy = y1 - y2 + +day9 :: IO () +day9 = do + input <- readFile "ressources/day09-input" + putStrLn "Day9" + let movements = parseMovements input + let positions = concatMap normalizeMovement >>> recordPositions >>> length $ movements + putStrLn ("Number of distinct positions " ++ show positions) diff --git a/src/Lib.hs b/src/Lib.hs index 730a00d..7fb2a7b 100644 --- a/src/Lib.hs +++ b/src/Lib.hs @@ -2,21 +2,22 @@ module Lib ( someFunc ) where -import Day1 -import Day2 -import Day3 -import Day4 -import Day5 -import Day6 -import Day7 -import Day8 +import Day1 (day1) +import Day2 (day2) +import Day3 (day3) +import Day4 (day4) +import Day5 (day5) +import Day6 (day6) +import Day7 (day7) +import Day8 (day8) +import Day9 (day9) days :: [IO ()] -days = [day1, day2, day3, day4, day5, day6, day7, day8] +days = [day1, day2, day3, day4, day5, day6, day7, day8, day9] sep :: IO () sep = putStrLn "---------" someFunc :: IO () someFunc = mapM_ (>> sep) days - + diff --git a/test/Day9Spec.hs b/test/Day9Spec.hs new file mode 100644 index 0000000..4f4679e --- /dev/null +++ b/test/Day9Spec.hs @@ -0,0 +1,79 @@ +{-# LANGUAGE QuasiQuotes #-} + +module Day9Spec (spec) where + +import Control.Arrow ((>>>)) +import Day9 +import Test.Hspec +import Text.Heredoc +import Data.List (sort) + +testInput :: String +testInput = + [str|R 4 + |U 4 + |L 3 + |D 1 + |R 4 + |D 1 + |L 5 + |R 2 + |] + +expectedPositions :: [(Int, Int)] +expectedPositions = sort [ + (2,4),(3,4), + (3,3),(4,3), + (1,2),(2,2),(3,2),(4,2), + (4,1), + (0,0),(1,0),(2,0),(3,0) + ] + +spec :: Spec +spec = + describe "Day9" $ do + describe "Part1" $ do + it "parses the instructions" $ do + parseMovements testInput + `shouldBe` [ right 4, + up 4, + left 3, + down 1, + right 4, + down 1, + left 5, + right 2 + ] + it "moves a step" $ do + step (0, 0) (Step (1, 1)) `shouldBe` (1, 1) + step (0, 0) (Step (1, 0)) `shouldBe` (1, 0) + step (1, 0) (Step (-1, 0)) `shouldBe` (0, 0) + step (0, 1) (Step (0, -1)) `shouldBe` (0, 0) + it "normalizes movement" $ do + normalizeMovement still `shouldBe` [] + normalizeMovement (left 1) `shouldBe` [Step (-1, 0)] + normalizeMovement (right 1) `shouldBe` [Step (1, 0)] + normalizeMovement (up 1) `shouldBe` [Step (0, 1)] + normalizeMovement (down 2) `shouldBe` [Step (0, -1), Step (0, -1)] + it "follows the head" $ do + follow (1, 0) (0, 0) `shouldBe` Step (0, 0) + follow (0, 1) (0, 0) `shouldBe` Step (0, 0) + follow (1, 1) (0, 0) `shouldBe` Step (0, 0) + follow (2, 1) (0, 0) `shouldBe` Step (1, 1) + follow (1, 2) (0, 0) `shouldBe` Step (1, 1) + follow (2, 2) (0, 0) `shouldBe` Step (1, 1) + follow (4, 2) (3, 0) `shouldBe` Step (1, 1) + it "moves around and records tail position" $ do + let positions = parseMovements + >>> concatMap normalizeMovement + >>> recordPositions + >>> sort + $ testInput + length positions `shouldBe` 13 + positions `shouldBe` expectedPositions + it "solves the riddle" $ do + input <- readFile "ressources/day09-input" + putStrLn "Day9" + let movements = parseMovements input + let positions = concatMap normalizeMovement >>> recordPositions >>> length $ movements + positions `shouldBe` 5878