summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShivesh Mandalia <mail@shivesh.org>2022-12-23 18:04:02 +0000
committerShivesh Mandalia <mail@shivesh.org>2022-12-23 18:04:02 +0000
commite9b61b1519a9b1dc34944f269b6fc9b34715b278 (patch)
tree9f6ed5f112354976864e9ba0c09d87274813580e
parent9da51d9db5dd1b3b34d92bc68419eaa28322c844 (diff)
downloadadvent_of_code_2022-e9b61b1519a9b1dc34944f269b6fc9b34715b278.tar.gz
advent_of_code_2022-e9b61b1519a9b1dc34944f269b6fc9b34715b278.zip
complete day 9
-rw-r--r--Cargo.lock18
-rw-r--r--Cargo.toml4
-rw-r--r--day09a/Cargo.toml11
-rw-r--r--day09a/examples/input.txt2000
-rw-r--r--day09a/examples/test.txt8
-rw-r--r--day09a/src/main.rs417
-rw-r--r--day09b/Cargo.toml11
-rw-r--r--day09b/examples/input.txt2000
-rw-r--r--day09b/examples/test.txt8
-rw-r--r--day09b/src/main.rs605
10 files changed, 5080 insertions, 2 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 92e44ed..8985bdc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -199,6 +199,24 @@ dependencies = [
]
[[package]]
+name = "day09a"
+version = "0.1.0"
+dependencies = [
+ "clap",
+ "itertools",
+ "nom",
+]
+
+[[package]]
+name = "day09b"
+version = "0.1.0"
+dependencies = [
+ "clap",
+ "itertools",
+ "nom",
+]
+
+[[package]]
name = "either"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 9a039ec..e7e378d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,8 +17,8 @@ members = [
"day07b",
"day08a",
"day08b",
- # "day09a",
- # "day09b",
+ "day09a",
+ "day09b",
# "day10a",
# "day10b",
# "day11a",
diff --git a/day09a/Cargo.toml b/day09a/Cargo.toml
new file mode 100644
index 0000000..1b0c457
--- /dev/null
+++ b/day09a/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "day09a"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+clap = { version = "3.2.20", features = ["derive"] }
+nom = "7.1.1"
+itertools = "0.10.5"
diff --git a/day09a/examples/input.txt b/day09a/examples/input.txt
new file mode 100644
index 0000000..be008e2
--- /dev/null
+++ b/day09a/examples/input.txt
@@ -0,0 +1,2000 @@
+L 2
+D 2
+L 2
+R 2
+L 1
+U 2
+D 1
+U 2
+L 2
+D 2
+L 2
+R 1
+D 2
+L 2
+R 2
+U 1
+R 1
+U 2
+D 2
+R 1
+U 1
+L 2
+D 1
+U 2
+L 2
+R 2
+U 2
+D 2
+L 1
+D 2
+R 2
+L 2
+U 1
+R 2
+D 2
+R 2
+U 2
+D 1
+R 2
+U 2
+L 1
+D 2
+R 1
+U 2
+R 2
+U 1
+L 2
+R 1
+D 1
+L 2
+U 2
+R 1
+L 1
+R 2
+U 1
+D 1
+L 2
+R 1
+D 1
+R 1
+L 2
+U 2
+D 2
+R 2
+L 1
+U 2
+R 1
+L 2
+D 1
+R 2
+L 1
+U 2
+D 1
+R 1
+U 2
+D 2
+L 1
+D 2
+U 2
+D 2
+R 2
+D 1
+U 1
+R 2
+D 2
+U 2
+R 2
+L 2
+R 2
+L 1
+U 2
+L 2
+U 2
+R 2
+D 2
+U 1
+R 2
+U 1
+D 1
+L 1
+R 2
+U 2
+R 1
+D 1
+L 2
+U 2
+L 1
+D 1
+R 2
+L 2
+U 1
+L 2
+D 1
+U 2
+R 1
+D 1
+L 1
+R 3
+L 2
+D 1
+R 2
+D 1
+R 2
+D 2
+L 3
+R 2
+U 3
+D 2
+U 3
+R 2
+D 2
+R 1
+D 3
+R 3
+L 1
+R 2
+D 3
+L 1
+R 1
+L 1
+U 2
+L 1
+D 3
+L 1
+D 1
+R 1
+L 3
+U 3
+L 3
+U 3
+L 2
+U 1
+D 1
+U 1
+L 1
+R 2
+D 3
+L 1
+R 1
+L 2
+U 1
+R 1
+L 2
+D 2
+L 3
+U 3
+R 2
+D 3
+R 1
+L 3
+U 1
+D 1
+L 3
+D 1
+L 3
+R 1
+D 1
+U 1
+D 2
+R 1
+L 3
+D 2
+L 2
+R 1
+U 1
+R 3
+U 3
+L 3
+R 2
+L 1
+D 1
+R 2
+D 1
+U 1
+R 1
+U 3
+R 1
+L 2
+D 3
+R 3
+D 2
+U 1
+D 1
+U 1
+R 3
+D 3
+R 2
+U 1
+L 3
+R 2
+L 2
+D 2
+L 3
+D 1
+U 2
+D 3
+L 1
+U 3
+D 3
+L 3
+R 3
+L 3
+U 4
+D 4
+U 3
+D 4
+R 4
+L 2
+D 2
+R 4
+L 2
+U 4
+D 2
+U 4
+R 4
+L 4
+D 1
+U 4
+D 1
+L 2
+U 1
+R 2
+D 3
+L 4
+R 4
+L 4
+R 4
+U 4
+L 3
+D 3
+L 3
+U 1
+R 4
+D 2
+L 4
+R 3
+L 4
+U 4
+D 1
+R 1
+L 1
+D 1
+R 2
+U 4
+R 4
+D 4
+R 3
+D 1
+L 1
+D 4
+U 3
+D 4
+R 4
+L 4
+R 3
+L 3
+R 2
+D 4
+U 2
+R 2
+D 3
+R 3
+L 4
+D 1
+L 2
+D 2
+R 4
+D 3
+R 1
+L 2
+R 1
+U 2
+L 3
+D 3
+U 4
+R 4
+L 1
+U 4
+L 3
+D 4
+L 2
+D 3
+R 2
+L 1
+U 3
+R 2
+D 4
+L 1
+D 2
+U 4
+L 3
+R 2
+D 3
+U 1
+D 4
+L 4
+R 4
+D 2
+L 4
+R 2
+U 1
+L 2
+U 4
+R 3
+D 2
+R 3
+D 3
+R 1
+L 1
+R 4
+D 3
+R 1
+L 3
+R 1
+L 2
+R 1
+L 3
+D 3
+U 4
+L 4
+U 1
+D 5
+L 5
+U 3
+L 1
+U 5
+D 1
+U 3
+L 5
+R 1
+L 3
+D 5
+U 4
+R 4
+L 2
+R 3
+L 2
+D 4
+L 1
+U 2
+D 4
+L 3
+U 4
+L 3
+U 5
+L 3
+D 1
+R 3
+U 4
+D 3
+L 2
+D 1
+L 2
+D 5
+U 1
+R 1
+D 1
+U 5
+L 4
+U 5
+L 2
+R 1
+D 3
+U 4
+R 2
+U 5
+D 2
+U 5
+D 4
+L 4
+D 5
+U 3
+R 3
+U 2
+D 1
+U 4
+R 2
+D 2
+R 5
+L 3
+U 2
+L 2
+R 3
+U 3
+L 4
+R 4
+L 1
+R 5
+L 4
+D 2
+U 2
+D 3
+U 1
+L 5
+U 1
+L 1
+D 1
+L 5
+R 2
+D 2
+U 4
+L 2
+R 3
+D 5
+R 5
+U 3
+R 2
+L 5
+D 2
+R 3
+D 5
+L 2
+R 1
+L 2
+D 3
+L 2
+U 5
+D 4
+L 5
+R 5
+L 2
+D 2
+L 3
+R 4
+D 2
+L 4
+D 5
+L 4
+D 3
+R 2
+L 1
+R 3
+D 3
+U 3
+L 1
+U 2
+D 2
+R 6
+U 2
+D 3
+U 6
+R 4
+U 1
+R 5
+D 5
+L 1
+U 1
+L 4
+U 5
+R 4
+D 5
+U 6
+R 3
+L 5
+R 5
+U 6
+L 3
+D 5
+R 2
+U 6
+L 5
+R 4
+L 5
+U 3
+L 3
+R 1
+U 6
+D 5
+R 1
+D 1
+L 5
+R 1
+D 5
+L 6
+U 1
+R 6
+L 2
+R 4
+L 6
+R 2
+D 5
+L 4
+D 4
+R 5
+D 3
+R 4
+U 1
+L 6
+D 2
+L 3
+R 6
+L 6
+U 6
+L 3
+R 2
+U 5
+R 6
+D 1
+L 1
+R 6
+L 4
+D 1
+U 4
+L 6
+R 6
+L 3
+R 4
+L 5
+R 2
+U 3
+L 5
+R 5
+L 3
+D 6
+U 5
+R 3
+L 1
+R 2
+D 2
+L 6
+R 1
+U 1
+R 1
+U 5
+L 6
+D 1
+R 1
+L 4
+U 6
+L 1
+U 3
+L 5
+U 5
+L 6
+D 5
+L 7
+U 4
+R 3
+U 4
+R 4
+U 3
+L 3
+R 1
+U 4
+L 4
+U 7
+R 1
+U 2
+D 1
+R 6
+L 1
+U 6
+L 2
+R 2
+U 4
+L 3
+U 6
+L 6
+D 6
+R 7
+D 5
+R 1
+L 3
+U 4
+R 7
+L 7
+R 4
+L 4
+D 7
+L 4
+U 6
+R 5
+L 5
+D 6
+L 3
+U 3
+D 3
+U 7
+D 5
+L 6
+R 1
+U 7
+L 6
+D 3
+U 5
+D 2
+L 5
+R 1
+L 6
+U 3
+L 3
+R 5
+D 3
+U 4
+L 2
+R 4
+U 2
+L 5
+U 6
+R 7
+U 4
+D 6
+R 7
+L 7
+D 7
+R 1
+U 4
+R 1
+U 7
+L 3
+R 2
+L 5
+D 6
+R 6
+L 6
+U 4
+D 4
+R 3
+U 2
+R 5
+D 6
+R 1
+D 7
+L 6
+R 1
+L 7
+D 3
+R 7
+U 7
+L 4
+D 1
+R 3
+L 3
+D 7
+L 3
+D 4
+L 7
+U 6
+R 1
+D 5
+U 5
+L 6
+U 1
+L 7
+R 3
+U 1
+R 7
+D 8
+L 3
+U 5
+L 3
+U 4
+D 5
+U 1
+D 4
+U 5
+L 2
+R 5
+D 2
+L 7
+R 3
+U 7
+D 2
+U 8
+D 7
+L 3
+R 1
+U 1
+R 5
+L 1
+R 5
+D 7
+U 8
+R 7
+U 1
+R 7
+D 2
+R 5
+L 1
+R 4
+D 4
+L 3
+D 3
+U 6
+D 2
+R 2
+U 3
+L 6
+R 6
+D 7
+U 6
+R 1
+D 2
+U 6
+D 8
+U 7
+D 1
+R 5
+D 1
+U 8
+R 4
+D 7
+L 8
+R 5
+L 8
+D 2
+U 7
+R 3
+D 5
+R 7
+D 6
+L 8
+U 1
+L 1
+D 6
+L 1
+R 2
+L 6
+D 2
+L 5
+D 4
+R 2
+U 2
+R 1
+L 8
+R 1
+D 3
+U 3
+L 4
+D 8
+R 3
+L 4
+R 2
+U 1
+L 4
+R 6
+U 5
+D 5
+L 8
+D 5
+L 5
+U 1
+L 7
+R 4
+D 6
+L 5
+U 3
+R 5
+D 8
+U 8
+L 5
+U 2
+D 6
+L 3
+D 5
+U 6
+D 3
+L 3
+R 2
+D 6
+U 9
+L 7
+D 6
+L 8
+U 8
+L 8
+R 4
+L 8
+D 8
+R 2
+L 2
+D 6
+L 4
+D 4
+L 6
+R 2
+L 7
+R 3
+L 6
+U 2
+R 9
+D 5
+R 1
+L 7
+R 3
+D 3
+L 4
+R 1
+U 8
+L 7
+R 3
+U 9
+D 5
+U 3
+R 8
+L 1
+R 9
+L 1
+U 1
+R 1
+U 6
+L 4
+U 7
+L 3
+D 7
+U 6
+L 5
+U 7
+D 4
+L 7
+U 8
+D 6
+U 7
+D 7
+R 8
+U 5
+D 8
+U 1
+D 1
+L 9
+U 8
+D 8
+U 2
+L 1
+R 5
+D 8
+L 4
+D 4
+L 1
+R 4
+U 3
+D 8
+U 9
+L 4
+U 4
+L 1
+D 8
+U 8
+R 1
+U 1
+R 6
+U 4
+R 1
+L 9
+U 8
+D 3
+U 3
+D 6
+U 8
+L 6
+D 3
+U 3
+D 1
+U 4
+R 9
+D 4
+L 7
+D 1
+R 2
+U 2
+L 3
+D 5
+L 5
+R 7
+D 9
+U 8
+R 2
+U 6
+D 10
+L 2
+D 6
+R 8
+U 8
+R 5
+L 4
+R 8
+D 5
+R 4
+L 4
+D 2
+R 3
+U 6
+L 3
+D 4
+R 4
+U 10
+L 6
+R 4
+L 9
+U 2
+D 2
+L 10
+U 1
+L 2
+R 3
+D 6
+R 2
+U 3
+R 6
+L 3
+R 3
+D 1
+L 5
+U 8
+R 6
+L 5
+D 3
+R 9
+L 7
+D 5
+U 10
+R 5
+D 8
+U 6
+D 10
+R 6
+U 9
+L 7
+R 4
+U 8
+R 1
+D 3
+U 9
+L 7
+D 5
+U 2
+L 9
+U 5
+L 5
+R 5
+U 8
+L 7
+D 7
+U 10
+L 2
+D 6
+U 9
+D 10
+U 4
+D 7
+L 6
+U 10
+L 4
+U 1
+D 9
+R 6
+U 6
+R 3
+L 10
+D 5
+U 9
+R 10
+U 8
+R 10
+U 1
+D 1
+U 3
+D 6
+R 9
+U 5
+R 6
+U 6
+R 5
+D 7
+L 1
+U 9
+R 10
+D 2
+L 5
+D 8
+L 9
+D 9
+L 2
+U 8
+R 4
+D 7
+U 3
+D 3
+U 8
+L 10
+D 7
+R 7
+D 8
+R 11
+D 10
+R 9
+U 2
+D 8
+U 5
+D 6
+U 2
+R 9
+D 5
+U 2
+R 5
+U 1
+L 1
+R 6
+D 6
+R 7
+U 7
+L 2
+R 6
+L 1
+D 3
+U 6
+L 1
+U 9
+D 5
+R 4
+D 3
+R 5
+U 11
+R 3
+D 2
+U 2
+L 11
+U 6
+R 11
+U 4
+D 6
+R 3
+U 9
+L 2
+D 10
+R 2
+U 5
+L 9
+D 1
+R 8
+L 2
+R 2
+D 1
+U 2
+D 11
+L 7
+D 8
+R 4
+L 2
+R 5
+U 7
+D 2
+L 2
+U 5
+L 2
+D 8
+R 1
+U 5
+D 11
+L 9
+R 5
+U 5
+D 7
+R 4
+U 2
+R 11
+D 9
+R 6
+D 6
+L 4
+U 5
+L 8
+U 5
+D 7
+L 9
+U 9
+D 8
+L 4
+R 5
+D 7
+U 3
+R 4
+L 5
+U 11
+D 3
+R 8
+L 6
+U 7
+L 10
+D 9
+L 4
+R 10
+U 9
+R 11
+U 5
+D 2
+L 7
+D 1
+U 4
+D 5
+L 7
+R 1
+D 5
+R 6
+D 7
+R 1
+U 10
+D 6
+L 8
+D 3
+L 9
+R 9
+U 8
+R 6
+U 10
+D 11
+R 9
+U 3
+L 10
+U 10
+D 10
+U 1
+D 4
+R 7
+L 4
+U 3
+L 12
+D 10
+R 4
+L 10
+D 12
+R 8
+U 6
+L 6
+R 5
+L 9
+U 6
+L 5
+D 12
+U 4
+R 9
+U 9
+D 11
+U 10
+R 11
+U 12
+D 12
+U 9
+R 9
+L 7
+D 2
+U 1
+D 1
+U 6
+R 7
+U 4
+D 2
+U 2
+D 7
+R 12
+L 10
+R 4
+U 6
+D 12
+R 9
+D 12
+R 5
+U 1
+R 2
+U 6
+D 2
+U 5
+R 3
+D 11
+L 3
+U 8
+D 11
+R 2
+D 10
+R 8
+L 7
+R 9
+U 11
+L 1
+D 4
+R 4
+U 11
+D 4
+R 1
+U 3
+R 5
+U 5
+D 11
+L 1
+R 2
+L 8
+U 7
+L 8
+D 7
+U 2
+R 4
+U 4
+D 2
+U 12
+R 9
+U 5
+L 2
+D 3
+U 8
+L 1
+R 2
+U 4
+L 12
+U 3
+L 8
+U 1
+D 2
+L 11
+R 13
+L 8
+R 10
+U 9
+D 3
+R 7
+L 3
+R 1
+U 1
+L 7
+R 7
+U 1
+L 10
+R 8
+U 11
+R 9
+L 12
+D 9
+L 8
+D 12
+L 10
+D 13
+R 8
+L 5
+R 6
+L 10
+U 13
+D 12
+L 4
+D 3
+U 7
+D 11
+L 12
+R 7
+D 9
+L 9
+D 4
+L 9
+D 9
+U 9
+R 7
+L 4
+R 8
+L 13
+U 2
+D 3
+R 3
+U 4
+D 8
+L 4
+R 6
+U 10
+L 1
+U 11
+L 13
+U 13
+D 10
+L 13
+R 3
+L 1
+D 4
+R 3
+L 7
+U 10
+L 4
+R 7
+U 10
+D 8
+L 9
+D 4
+U 5
+R 12
+U 1
+R 9
+D 6
+L 2
+D 6
+R 12
+U 11
+L 11
+U 2
+D 11
+L 11
+R 9
+L 13
+R 6
+U 5
+R 13
+L 7
+U 5
+R 1
+L 6
+R 1
+L 5
+U 10
+D 10
+R 11
+L 13
+R 5
+L 13
+R 3
+D 2
+L 3
+D 10
+U 4
+D 7
+L 7
+D 14
+R 4
+U 3
+R 14
+L 3
+R 3
+U 12
+R 10
+U 9
+D 14
+R 2
+U 5
+D 12
+U 3
+R 5
+L 8
+R 8
+L 2
+U 5
+R 13
+U 13
+R 7
+D 3
+L 8
+U 2
+L 3
+U 13
+L 8
+D 10
+L 6
+U 13
+L 6
+U 11
+R 10
+L 7
+D 2
+U 4
+L 13
+R 5
+U 10
+D 14
+L 3
+D 13
+L 13
+D 11
+L 7
+U 6
+R 5
+D 9
+L 3
+R 10
+L 3
+R 8
+L 10
+D 11
+R 3
+U 3
+D 6
+L 7
+U 13
+R 8
+D 6
+R 3
+D 11
+R 11
+D 7
+U 2
+R 9
+L 7
+D 7
+R 13
+L 1
+R 5
+D 14
+U 10
+R 13
+U 12
+L 7
+D 14
+U 8
+R 5
+U 4
+D 5
+U 14
+L 3
+U 3
+D 13
+U 2
+R 9
+U 7
+D 2
+L 10
+U 3
+R 12
+L 9
+R 8
+L 3
+D 13
+U 10
+R 12
+D 7
+U 10
+L 12
+D 8
+L 13
+D 14
+L 4
+D 4
+L 5
+U 11
+D 4
+L 2
+U 9
+D 3
+L 3
+D 12
+L 14
+R 15
+L 10
+U 2
+D 10
+U 14
+R 5
+L 12
+R 8
+D 1
+L 4
+R 13
+D 10
+R 12
+L 5
+U 8
+D 12
+U 5
+R 2
+L 4
+U 1
+D 13
+U 6
+R 14
+D 14
+R 10
+D 8
+U 12
+L 7
+U 2
+L 13
+R 11
+L 13
+D 11
+R 1
+U 13
+R 6
+D 8
+L 4
+R 3
+D 7
+U 1
+L 8
+U 15
+D 3
+L 9
+R 10
+U 4
+D 8
+R 2
+D 13
+L 13
+U 4
+D 10
+L 12
+R 14
+U 9
+L 4
+U 1
+D 7
+R 2
+U 8
+L 6
+R 9
+U 4
+L 9
+U 8
+L 9
+U 9
+R 6
+L 12
+U 12
+L 1
+R 15
+U 4
+R 7
+L 5
+D 9
+R 1
+L 15
+D 1
+R 10
+D 4
+R 5
+D 6
+R 15
+U 15
+L 9
+D 3
+L 9
+U 11
+L 8
+U 9
+L 15
+U 14
+L 10
+R 8
+D 3
+R 8
+U 8
+R 4
+D 9
+L 1
+U 11
+L 14
+R 1
+D 12
+L 10
+D 3
+L 1
+R 1
+U 16
+D 7
+R 13
+D 11
+L 7
+U 7
+D 16
+L 16
+D 3
+L 12
+D 14
+R 11
+D 15
+R 2
+U 10
+R 10
+D 1
+R 9
+U 11
+D 7
+U 15
+D 7
+R 15
+L 11
+D 1
+L 9
+D 2
+R 4
+L 1
+R 7
+L 6
+U 6
+L 16
+R 12
+D 7
+L 1
+U 3
+D 16
+R 1
+D 8
+R 15
+L 4
+U 10
+R 14
+U 4
+R 15
+L 14
+R 7
+D 7
+L 8
+R 7
+L 10
+R 1
+D 4
+U 12
+L 15
+R 16
+U 10
+D 13
+U 12
+R 2
+D 3
+U 2
+L 1
+R 13
+U 7
+L 9
+D 12
+L 16
+D 4
+L 4
+D 1
+R 9
+L 10
+R 1
+D 6
+L 12
+R 12
+U 8
+D 4
+L 3
+R 6
+L 12
+U 12
+D 3
+R 6
+U 11
+R 11
+U 12
+L 11
+R 2
+U 4
+D 2
+U 16
+R 9
+D 16
+L 4
+U 5
+L 16
+U 1
+L 7
+R 13
+L 2
+D 16
+L 10
+D 14
+R 9
+U 14
+L 15
+D 12
+L 12
+D 5
+L 14
+R 17
+L 13
+R 7
+L 7
+U 14
+R 17
+L 12
+U 9
+D 16
+R 1
+D 5
+R 4
+D 12
+R 13
+L 15
+D 5
+R 7
+U 5
+L 10
+R 1
+U 4
+R 5
+L 16
+D 11
+U 13
+D 12
+L 1
+U 1
+L 10
+U 1
+L 1
+R 3
+D 13
+U 10
+L 17
+D 11
+L 10
+U 10
+L 12
+D 10
+L 11
+D 7
+R 17
+L 2
+R 15
+D 17
+R 8
+U 16
+L 17
+D 8
+L 7
+D 3
+R 5
+L 12
+R 9
+D 14
+U 3
+D 7
+L 1
+U 1
+D 5
+L 12
+U 12
+R 9
+L 15
+D 6
+L 5
+U 5
+D 17
+L 7
+R 14
+U 14
+R 10
+L 5
+U 5
+D 12
+U 5
+R 14
+L 11
+D 1
+R 3
+L 16
+R 6
+U 14
+D 1
+L 9
+R 17
+D 3
+U 3
+R 16
+L 12
+R 6
+U 1
+D 11
+U 10
+L 7
+D 4
+R 10
+D 14
+R 11
+L 4
+D 11
+R 7
+L 10
+D 8
+U 4
+L 11
+R 8
+U 10
+L 17
+D 2
+R 4
+L 13
+U 7
+L 13
+U 3
+D 16
+R 17
+D 8
+L 1
+R 4
+U 16
+R 1
+U 13
+L 4
+R 18
+U 7
+L 5
+D 14
+U 17
+L 2
+D 8
+R 9
+U 16
+D 4
+U 18
+L 1
+U 2
+L 13
+R 16
+D 10
+R 6
+D 11
+L 5
+U 17
+L 8
+R 15
+U 8
+L 4
+R 1
+D 10
+L 1
+U 18
+R 6
+U 5
+R 8
+U 1
+D 15
+L 5
+D 13
+U 14
+R 5
+U 1
+L 4
+D 6
+R 8
+U 17
+D 14
+U 6
+R 9
+D 1
+L 11
+D 6
+L 11
+U 17
+L 1
+D 17
+L 4
+D 2
+U 9
+R 9
+D 17
+U 4
+L 6
+U 2
+D 2
+R 6
+D 12
+R 10
+D 11
+L 7
+D 3
+U 14
+R 1
+L 18
+D 15
+L 3
+R 5
+L 15
+U 5
+R 11
+D 10
+L 14
+D 2
+R 5
+U 12
+R 8
+D 10
+R 14
+D 18
+U 4
+R 18
+D 11
+R 11
+U 2
+L 7
+R 1
+U 18
+L 3
+U 13
+R 16
+D 8
+U 7
+R 1
+U 2
+R 15
+U 3
+R 13
+D 14
+L 15
+U 10
+L 12
+U 6
+R 14
+D 14
+U 1
+D 8
+R 13
+D 14
+L 10
+R 4
+D 1
+L 3
+U 13
+R 17
+D 12
+L 4
+U 15
+R 3
+U 19
+D 15
+U 2
+D 7
+U 8
+L 19
+D 17
+U 16
+D 13
+L 3
+R 16
+D 4
+R 17
+L 10
+R 5
+U 10
+L 18
+U 15
+R 11
+D 1
+R 14
+D 7
+R 4
+U 19
+R 14
+U 19
+D 16
+L 14
+R 17
+L 9
+R 16
+L 14
+D 10
+R 1
+U 2
+L 3
+R 12
+D 4
+U 12
+R 16
+L 4
+R 3
+U 9
+R 19
+U 2
+L 13
+D 11
+L 7
+D 11
+U 3
+R 1
+L 8
+R 7
+L 15
+D 9
+U 12
+D 10
+R 9
+U 16
+R 11
+L 11
+R 6
+U 11
+D 9
+L 8
+R 7
+L 9
+R 13
+D 14
+U 11
+R 14
+L 17
+U 9
+L 17
+R 9
+L 10
diff --git a/day09a/examples/test.txt b/day09a/examples/test.txt
new file mode 100644
index 0000000..9874df2
--- /dev/null
+++ b/day09a/examples/test.txt
@@ -0,0 +1,8 @@
+R 4
+U 4
+L 3
+D 1
+R 4
+D 1
+L 5
+R 2
diff --git a/day09a/src/main.rs b/day09a/src/main.rs
new file mode 100644
index 0000000..efe843c
--- /dev/null
+++ b/day09a/src/main.rs
@@ -0,0 +1,417 @@
+/// --- Day 9: Rope Bridge ---
+///
+/// This rope bridge creaks as you walk along it. You aren't sure how old it is, or whether it can
+/// even support your weight.
+///
+/// It seems to support the Elves just fine, though. The bridge spans a gorge which was carved out
+/// by the massive river far below you.
+///
+/// You step carefully; as you do, the ropes stretch and twist. You decide to distract yourself by
+/// modeling rope physics; maybe you can even figure out where not to step.
+///
+/// Consider a rope with a knot at each end; these knots mark the head and the tail of the rope. If
+/// the head moves far enough away from the tail, the tail is pulled toward the head.
+///
+/// Due to nebulous reasoning involving Planck lengths, you should be able to model the positions
+/// of the knots on a two-dimensional grid. Then, by following a hypothetical series of motions
+/// (your puzzle input) for the head, you can determine how the tail will move.
+///
+/// Due to the aforementioned Planck lengths, the rope must be quite short; in fact, the head (H)
+/// and tail (T) must always be touching (diagonally adjacent and even overlapping both count as
+/// touching):
+///
+/// ```
+/// ....
+/// .TH.
+/// ....
+///
+/// ....
+/// .H..
+/// ..T.
+/// ....
+///
+/// ...
+/// .H. (H covers T)
+/// ...
+/// ```
+///
+/// If the head is ever two steps directly up, down, left, or right from the tail, the tail must
+/// also move one step in that direction so it remains close enough:
+///
+/// ```
+/// ..... ..... .....
+/// .TH.. -> .T.H. -> ..TH.
+/// ..... ..... .....
+///
+/// ... ... ...
+/// .T. .T. ...
+/// .H. -> ... -> .T.
+/// ... .H. .H.
+/// ... ... ...
+/// ```
+///
+/// Otherwise, if the head and tail aren't touching and aren't in the same row or column, the tail
+/// always moves one step diagonally to keep up:
+///
+/// ```
+/// ..... ..... .....
+/// ..... ..H.. ..H..
+/// ..H.. -> ..... -> ..T..
+/// .T... .T... .....
+/// ..... ..... .....
+///
+/// ..... ..... .....
+/// ..... ..... .....
+/// ..H.. -> ...H. -> ..TH.
+/// .T... .T... .....
+/// ..... ..... .....
+/// ```
+///
+/// You just need to work out where the tail goes as the head follows a series of motions. Assume
+/// the head and the tail both start at the same position, overlapping.
+///
+/// For example:
+///
+/// ```
+/// R 4
+/// U 4
+/// L 3
+/// D 1
+/// R 4
+/// D 1
+/// L 5
+/// R 2
+/// ```
+///
+/// This series of motions moves the head right four steps, then up four steps, then left three
+/// steps, then down one step, and so on. After each step, you'll need to update the position of
+/// the tail if the step means the head is no longer adjacent to the tail. Visually, these motions
+/// occur as follows (s marks the starting position as a reference point):
+///
+/// ```
+/// == Initial State ==
+///
+/// ......
+/// ......
+/// ......
+/// ......
+/// H..... (H covers T, s)
+///
+/// == R 4 ==
+///
+/// ......
+/// ......
+/// ......
+/// ......
+/// TH.... (T covers s)
+///
+/// ......
+/// ......
+/// ......
+/// ......
+/// sTH...
+///
+/// ......
+/// ......
+/// ......
+/// ......
+/// s.TH..
+///
+/// ......
+/// ......
+/// ......
+/// ......
+/// s..TH.
+///
+/// == U 4 ==
+///
+/// ......
+/// ......
+/// ......
+/// ....H.
+/// s..T..
+///
+/// ......
+/// ......
+/// ....H.
+/// ....T.
+/// s.....
+///
+/// ......
+/// ....H.
+/// ....T.
+/// ......
+/// s.....
+///
+/// ....H.
+/// ....T.
+/// ......
+/// ......
+/// s.....
+///
+/// == L 3 ==
+///
+/// ...H..
+/// ....T.
+/// ......
+/// ......
+/// s.....
+///
+/// ..HT..
+/// ......
+/// ......
+/// ......
+/// s.....
+///
+/// .HT...
+/// ......
+/// ......
+/// ......
+/// s.....
+///
+/// == D 1 ==
+///
+/// ..T...
+/// .H....
+/// ......
+/// ......
+/// s.....
+///
+/// == R 4 ==
+///
+/// ..T...
+/// ..H...
+/// ......
+/// ......
+/// s.....
+///
+/// ..T...
+/// ...H..
+/// ......
+/// ......
+/// s.....
+///
+/// ......
+/// ...TH.
+/// ......
+/// ......
+/// s.....
+///
+/// ......
+/// ....TH
+/// ......
+/// ......
+/// s.....
+///
+/// == D 1 ==
+///
+/// ......
+/// ....T.
+/// .....H
+/// ......
+/// s.....
+///
+/// == L 5 ==
+///
+/// ......
+/// ....T.
+/// ....H.
+/// ......
+/// s.....
+///
+/// ......
+/// ....T.
+/// ...H..
+/// ......
+/// s.....
+///
+/// ......
+/// ......
+/// ..HT..
+/// ......
+/// s.....
+///
+/// ......
+/// ......
+/// .HT...
+/// ......
+/// s.....
+///
+/// ......
+/// ......
+/// HT....
+/// ......
+/// s.....
+///
+/// == R 2 ==
+///
+/// ......
+/// ......
+/// .H.... (H covers T)
+/// ......
+/// s.....
+///
+/// ......
+/// ......
+/// .TH...
+/// ......
+/// s.....
+/// ```
+///
+/// After simulating the rope, you can count up all of the positions the tail visited at least
+/// once. In this diagram, s again marks the starting position (which the tail also visited) and #
+/// marks other positions the tail visited:
+///
+/// ```
+/// ..##..
+/// ...##.
+/// .####.
+/// ....#.
+/// s###..
+/// ```
+///
+/// So, there are 13 positions the tail visited at least once.
+///
+/// Simulate your complete hypothetical series of motions. How many positions does the tail of the
+/// rope visit at least once?
+use clap::Parser;
+use itertools::Itertools;
+
+use std::collections::HashSet;
+use std::fs::File;
+use std::io::prelude::*;
+use std::io::BufReader;
+use std::path::PathBuf;
+
+const FILEPATH: &'static str = "examples/input.txt";
+
+#[derive(Parser, Debug)]
+#[clap(author, version, about, long_about = None)]
+struct Cli {
+ #[clap(short, long, default_value = FILEPATH)]
+ file: PathBuf,
+}
+
+#[derive(Copy, Clone, Debug)]
+enum Direction {
+ Up,
+ Down,
+ Left,
+ Right,
+}
+
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
+struct Coord {
+ x: i32,
+ y: i32,
+}
+
+#[derive(Clone, Debug)]
+struct Command {
+ dir: Direction,
+ amount: u32,
+}
+
+#[derive(Clone, Debug)]
+struct State {
+ head: Coord,
+ tail: Coord,
+ tail_visited: HashSet<Coord>,
+}
+
+impl Coord {
+ fn new() -> Self {
+ Self { x: 0, y: 0 }
+ }
+}
+
+impl Command {
+ fn parse(dir: &str, amount: &str) -> Self {
+ use Direction::*;
+ let d = match dir {
+ "U" => Up,
+ "D" => Down,
+ "L" => Left,
+ "R" => Right,
+ _ => panic!("unknown direction {}", dir),
+ };
+ Self {
+ dir: d,
+ amount: amount.parse::<u32>().unwrap(),
+ }
+ }
+}
+
+impl State {
+ fn new() -> Self {
+ let mut hs = HashSet::new();
+ hs.insert(Coord::new());
+ State {
+ head: Coord::new(),
+ tail: Coord::new(),
+ tail_visited: hs,
+ }
+ }
+
+ fn update_tail(&mut self) {
+ match (self.head.x - self.tail.x, self.head.y - self.tail.y) {
+ (0, 0)
+ | (1, 0)
+ | (-1, 0)
+ | (0, 1)
+ | (0, -1)
+ | (1, 1)
+ | (-1, -1)
+ | (1, -1)
+ | (-1, 1) => return,
+ (xdiff, ydiff) => {
+ self.tail.x += i32::signum(xdiff);
+ self.tail.y += i32::signum(ydiff);
+ self.tail_visited.insert(self.tail);
+ },
+ }
+ }
+
+ fn shift(&mut self, dir: Direction) {
+ use Direction::*;
+ match dir {
+ Up => self.head.y += 1,
+ Down => self.head.y -= 1,
+ Right => self.head.x += 1,
+ Left => self.head.x -= 1,
+ }
+ self.update_tail();
+ }
+
+ fn process(&mut self, cmd: &Command) {
+ for _ in 0..cmd.amount {
+ self.shift(cmd.dir);
+ }
+ }
+}
+
+fn main() {
+ let args = Cli::parse();
+
+ let file = File::open(&args.file).unwrap();
+ let reader = BufReader::new(file);
+ let mut state = State::new();
+ let _ = reader
+ .lines()
+ .map(|l| {
+ l.unwrap()
+ .split_whitespace()
+ .map(|s| s.to_owned())
+ .collect_tuple::<(String, String)>()
+ .unwrap()
+ })
+ .map(|(dir, amount)| Command::parse(dir.as_str(), amount.as_str()))
+ .scan(&mut state, |state, cmd| {
+ state.process(&cmd);
+ Some(())
+ })
+ .last();
+
+ let res = state.tail_visited.len();
+ println!("{res:?}");
+}
diff --git a/day09b/Cargo.toml b/day09b/Cargo.toml
new file mode 100644
index 0000000..46a19e5
--- /dev/null
+++ b/day09b/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "day09b"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+clap = { version = "3.2.20", features = ["derive"] }
+nom = "7.1.1"
+itertools = "0.10.5"
diff --git a/day09b/examples/input.txt b/day09b/examples/input.txt
new file mode 100644
index 0000000..be008e2
--- /dev/null
+++ b/day09b/examples/input.txt
@@ -0,0 +1,2000 @@
+L 2
+D 2
+L 2
+R 2
+L 1
+U 2
+D 1
+U 2
+L 2
+D 2
+L 2
+R 1
+D 2
+L 2
+R 2
+U 1
+R 1
+U 2
+D 2
+R 1
+U 1
+L 2
+D 1
+U 2
+L 2
+R 2
+U 2
+D 2
+L 1
+D 2
+R 2
+L 2
+U 1
+R 2
+D 2
+R 2
+U 2
+D 1
+R 2
+U 2
+L 1
+D 2
+R 1
+U 2
+R 2
+U 1
+L 2
+R 1
+D 1
+L 2
+U 2
+R 1
+L 1
+R 2
+U 1
+D 1
+L 2
+R 1
+D 1
+R 1
+L 2
+U 2
+D 2
+R 2
+L 1
+U 2
+R 1
+L 2
+D 1
+R 2
+L 1
+U 2
+D 1
+R 1
+U 2
+D 2
+L 1
+D 2
+U 2
+D 2
+R 2
+D 1
+U 1
+R 2
+D 2
+U 2
+R 2
+L 2
+R 2
+L 1
+U 2
+L 2
+U 2
+R 2
+D 2
+U 1
+R 2
+U 1
+D 1
+L 1
+R 2
+U 2
+R 1
+D 1
+L 2
+U 2
+L 1
+D 1
+R 2
+L 2
+U 1
+L 2
+D 1
+U 2
+R 1
+D 1
+L 1
+R 3
+L 2
+D 1
+R 2
+D 1
+R 2
+D 2
+L 3
+R 2
+U 3
+D 2
+U 3
+R 2
+D 2
+R 1
+D 3
+R 3
+L 1
+R 2
+D 3
+L 1
+R 1
+L 1
+U 2
+L 1
+D 3
+L 1
+D 1
+R 1
+L 3
+U 3
+L 3
+U 3
+L 2
+U 1
+D 1
+U 1
+L 1
+R 2
+D 3
+L 1
+R 1
+L 2
+U 1
+R 1
+L 2
+D 2
+L 3
+U 3
+R 2
+D 3
+R 1
+L 3
+U 1
+D 1
+L 3
+D 1
+L 3
+R 1
+D 1
+U 1
+D 2
+R 1
+L 3
+D 2
+L 2
+R 1
+U 1
+R 3
+U 3
+L 3
+R 2
+L 1
+D 1
+R 2
+D 1
+U 1
+R 1
+U 3
+R 1
+L 2
+D 3
+R 3
+D 2
+U 1
+D 1
+U 1
+R 3
+D 3
+R 2
+U 1
+L 3
+R 2
+L 2
+D 2
+L 3
+D 1
+U 2
+D 3
+L 1
+U 3
+D 3
+L 3
+R 3
+L 3
+U 4
+D 4
+U 3
+D 4
+R 4
+L 2
+D 2
+R 4
+L 2
+U 4
+D 2
+U 4
+R 4
+L 4
+D 1
+U 4
+D 1
+L 2
+U 1
+R 2
+D 3
+L 4
+R 4
+L 4
+R 4
+U 4
+L 3
+D 3
+L 3
+U 1
+R 4
+D 2
+L 4
+R 3
+L 4
+U 4
+D 1
+R 1
+L 1
+D 1
+R 2
+U 4
+R 4
+D 4
+R 3
+D 1
+L 1
+D 4
+U 3
+D 4
+R 4
+L 4
+R 3
+L 3
+R 2
+D 4
+U 2
+R 2
+D 3
+R 3
+L 4
+D 1
+L 2
+D 2
+R 4
+D 3
+R 1
+L 2
+R 1
+U 2
+L 3
+D 3
+U 4
+R 4
+L 1
+U 4
+L 3
+D 4
+L 2
+D 3
+R 2
+L 1
+U 3
+R 2
+D 4
+L 1
+D 2
+U 4
+L 3
+R 2
+D 3
+U 1
+D 4
+L 4
+R 4
+D 2
+L 4
+R 2
+U 1
+L 2
+U 4
+R 3
+D 2
+R 3
+D 3
+R 1
+L 1
+R 4
+D 3
+R 1
+L 3
+R 1
+L 2
+R 1
+L 3
+D 3
+U 4
+L 4
+U 1
+D 5
+L 5
+U 3
+L 1
+U 5
+D 1
+U 3
+L 5
+R 1
+L 3
+D 5
+U 4
+R 4
+L 2
+R 3
+L 2
+D 4
+L 1
+U 2
+D 4
+L 3
+U 4
+L 3
+U 5
+L 3
+D 1
+R 3
+U 4
+D 3
+L 2
+D 1
+L 2
+D 5
+U 1
+R 1
+D 1
+U 5
+L 4
+U 5
+L 2
+R 1
+D 3
+U 4
+R 2
+U 5
+D 2
+U 5
+D 4
+L 4
+D 5
+U 3
+R 3
+U 2
+D 1
+U 4
+R 2
+D 2
+R 5
+L 3
+U 2
+L 2
+R 3
+U 3
+L 4
+R 4
+L 1
+R 5
+L 4
+D 2
+U 2
+D 3
+U 1
+L 5
+U 1
+L 1
+D 1
+L 5
+R 2
+D 2
+U 4
+L 2
+R 3
+D 5
+R 5
+U 3
+R 2
+L 5
+D 2
+R 3
+D 5
+L 2
+R 1
+L 2
+D 3
+L 2
+U 5
+D 4
+L 5
+R 5
+L 2
+D 2
+L 3
+R 4
+D 2
+L 4
+D 5
+L 4
+D 3
+R 2
+L 1
+R 3
+D 3
+U 3
+L 1
+U 2
+D 2
+R 6
+U 2
+D 3
+U 6
+R 4
+U 1
+R 5
+D 5
+L 1
+U 1
+L 4
+U 5
+R 4
+D 5
+U 6
+R 3
+L 5
+R 5
+U 6
+L 3
+D 5
+R 2
+U 6
+L 5
+R 4
+L 5
+U 3
+L 3
+R 1
+U 6
+D 5
+R 1
+D 1
+L 5
+R 1
+D 5
+L 6
+U 1
+R 6
+L 2
+R 4
+L 6
+R 2
+D 5
+L 4
+D 4
+R 5
+D 3
+R 4
+U 1
+L 6
+D 2
+L 3
+R 6
+L 6
+U 6
+L 3
+R 2
+U 5
+R 6
+D 1
+L 1
+R 6
+L 4
+D 1
+U 4
+L 6
+R 6
+L 3
+R 4
+L 5
+R 2
+U 3
+L 5
+R 5
+L 3
+D 6
+U 5
+R 3
+L 1
+R 2
+D 2
+L 6
+R 1
+U 1
+R 1
+U 5
+L 6
+D 1
+R 1
+L 4
+U 6
+L 1
+U 3
+L 5
+U 5
+L 6
+D 5
+L 7
+U 4
+R 3
+U 4
+R 4
+U 3
+L 3
+R 1
+U 4
+L 4
+U 7
+R 1
+U 2
+D 1
+R 6
+L 1
+U 6
+L 2
+R 2
+U 4
+L 3
+U 6
+L 6
+D 6
+R 7
+D 5
+R 1
+L 3
+U 4
+R 7
+L 7
+R 4
+L 4
+D 7
+L 4
+U 6
+R 5
+L 5
+D 6
+L 3
+U 3
+D 3
+U 7
+D 5
+L 6
+R 1
+U 7
+L 6
+D 3
+U 5
+D 2
+L 5
+R 1
+L 6
+U 3
+L 3
+R 5
+D 3
+U 4
+L 2
+R 4
+U 2
+L 5
+U 6
+R 7
+U 4
+D 6
+R 7
+L 7
+D 7
+R 1
+U 4
+R 1
+U 7
+L 3
+R 2
+L 5
+D 6
+R 6
+L 6
+U 4
+D 4
+R 3
+U 2
+R 5
+D 6
+R 1
+D 7
+L 6
+R 1
+L 7
+D 3
+R 7
+U 7
+L 4
+D 1
+R 3
+L 3
+D 7
+L 3
+D 4
+L 7
+U 6
+R 1
+D 5
+U 5
+L 6
+U 1
+L 7
+R 3
+U 1
+R 7
+D 8
+L 3
+U 5
+L 3
+U 4
+D 5
+U 1
+D 4
+U 5
+L 2
+R 5
+D 2
+L 7
+R 3
+U 7
+D 2
+U 8
+D 7
+L 3
+R 1
+U 1
+R 5
+L 1
+R 5
+D 7
+U 8
+R 7
+U 1
+R 7
+D 2
+R 5
+L 1
+R 4
+D 4
+L 3
+D 3
+U 6
+D 2
+R 2
+U 3
+L 6
+R 6
+D 7
+U 6
+R 1
+D 2
+U 6
+D 8
+U 7
+D 1
+R 5
+D 1
+U 8
+R 4
+D 7
+L 8
+R 5
+L 8
+D 2
+U 7
+R 3
+D 5
+R 7
+D 6
+L 8
+U 1
+L 1
+D 6
+L 1
+R 2
+L 6
+D 2
+L 5
+D 4
+R 2
+U 2
+R 1
+L 8
+R 1
+D 3
+U 3
+L 4
+D 8
+R 3
+L 4
+R 2
+U 1
+L 4
+R 6
+U 5
+D 5
+L 8
+D 5
+L 5
+U 1
+L 7
+R 4
+D 6
+L 5
+U 3
+R 5
+D 8
+U 8
+L 5
+U 2
+D 6
+L 3
+D 5
+U 6
+D 3
+L 3
+R 2
+D 6
+U 9
+L 7
+D 6
+L 8
+U 8
+L 8
+R 4
+L 8
+D 8
+R 2
+L 2
+D 6
+L 4
+D 4
+L 6
+R 2
+L 7
+R 3
+L 6
+U 2
+R 9
+D 5
+R 1
+L 7
+R 3
+D 3
+L 4
+R 1
+U 8
+L 7
+R 3
+U 9
+D 5
+U 3
+R 8
+L 1
+R 9
+L 1
+U 1
+R 1
+U 6
+L 4
+U 7
+L 3
+D 7
+U 6
+L 5
+U 7
+D 4
+L 7
+U 8
+D 6
+U 7
+D 7
+R 8
+U 5
+D 8
+U 1
+D 1
+L 9
+U 8
+D 8
+U 2
+L 1
+R 5
+D 8
+L 4
+D 4
+L 1
+R 4
+U 3
+D 8
+U 9
+L 4
+U 4
+L 1
+D 8
+U 8
+R 1
+U 1
+R 6
+U 4
+R 1
+L 9
+U 8
+D 3
+U 3
+D 6
+U 8
+L 6
+D 3
+U 3
+D 1
+U 4
+R 9
+D 4
+L 7
+D 1
+R 2
+U 2
+L 3
+D 5
+L 5
+R 7
+D 9
+U 8
+R 2
+U 6
+D 10
+L 2
+D 6
+R 8
+U 8
+R 5
+L 4
+R 8
+D 5
+R 4
+L 4
+D 2
+R 3
+U 6
+L 3
+D 4
+R 4
+U 10
+L 6
+R 4
+L 9
+U 2
+D 2
+L 10
+U 1
+L 2
+R 3
+D 6
+R 2
+U 3
+R 6
+L 3
+R 3
+D 1
+L 5
+U 8
+R 6
+L 5
+D 3
+R 9
+L 7
+D 5
+U 10
+R 5
+D 8
+U 6
+D 10
+R 6
+U 9
+L 7
+R 4
+U 8
+R 1
+D 3
+U 9
+L 7
+D 5
+U 2
+L 9
+U 5
+L 5
+R 5
+U 8
+L 7
+D 7
+U 10
+L 2
+D 6
+U 9
+D 10
+U 4
+D 7
+L 6
+U 10
+L 4
+U 1
+D 9
+R 6
+U 6
+R 3
+L 10
+D 5
+U 9
+R 10
+U 8
+R 10
+U 1
+D 1
+U 3
+D 6
+R 9
+U 5
+R 6
+U 6
+R 5
+D 7
+L 1
+U 9
+R 10
+D 2
+L 5
+D 8
+L 9
+D 9
+L 2
+U 8
+R 4
+D 7
+U 3
+D 3
+U 8
+L 10
+D 7
+R 7
+D 8
+R 11
+D 10
+R 9
+U 2
+D 8
+U 5
+D 6
+U 2
+R 9
+D 5
+U 2
+R 5
+U 1
+L 1
+R 6
+D 6
+R 7
+U 7
+L 2
+R 6
+L 1
+D 3
+U 6
+L 1
+U 9
+D 5
+R 4
+D 3
+R 5
+U 11
+R 3
+D 2
+U 2
+L 11
+U 6
+R 11
+U 4
+D 6
+R 3
+U 9
+L 2
+D 10
+R 2
+U 5
+L 9
+D 1
+R 8
+L 2
+R 2
+D 1
+U 2
+D 11
+L 7
+D 8
+R 4
+L 2
+R 5
+U 7
+D 2
+L 2
+U 5
+L 2
+D 8
+R 1
+U 5
+D 11
+L 9
+R 5
+U 5
+D 7
+R 4
+U 2
+R 11
+D 9
+R 6
+D 6
+L 4
+U 5
+L 8
+U 5
+D 7
+L 9
+U 9
+D 8
+L 4
+R 5
+D 7
+U 3
+R 4
+L 5
+U 11
+D 3
+R 8
+L 6
+U 7
+L 10
+D 9
+L 4
+R 10
+U 9
+R 11
+U 5
+D 2
+L 7
+D 1
+U 4
+D 5
+L 7
+R 1
+D 5
+R 6
+D 7
+R 1
+U 10
+D 6
+L 8
+D 3
+L 9
+R 9
+U 8
+R 6
+U 10
+D 11
+R 9
+U 3
+L 10
+U 10
+D 10
+U 1
+D 4
+R 7
+L 4
+U 3
+L 12
+D 10
+R 4
+L 10
+D 12
+R 8
+U 6
+L 6
+R 5
+L 9
+U 6
+L 5
+D 12
+U 4
+R 9
+U 9
+D 11
+U 10
+R 11
+U 12
+D 12
+U 9
+R 9
+L 7
+D 2
+U 1
+D 1
+U 6
+R 7
+U 4
+D 2
+U 2
+D 7
+R 12
+L 10
+R 4
+U 6
+D 12
+R 9
+D 12
+R 5
+U 1
+R 2
+U 6
+D 2
+U 5
+R 3
+D 11
+L 3
+U 8
+D 11
+R 2
+D 10
+R 8
+L 7
+R 9
+U 11
+L 1
+D 4
+R 4
+U 11
+D 4
+R 1
+U 3
+R 5
+U 5
+D 11
+L 1
+R 2
+L 8
+U 7
+L 8
+D 7
+U 2
+R 4
+U 4
+D 2
+U 12
+R 9
+U 5
+L 2
+D 3
+U 8
+L 1
+R 2
+U 4
+L 12
+U 3
+L 8
+U 1
+D 2
+L 11
+R 13
+L 8
+R 10
+U 9
+D 3
+R 7
+L 3
+R 1
+U 1
+L 7
+R 7
+U 1
+L 10
+R 8
+U 11
+R 9
+L 12
+D 9
+L 8
+D 12
+L 10
+D 13
+R 8
+L 5
+R 6
+L 10
+U 13
+D 12
+L 4
+D 3
+U 7
+D 11
+L 12
+R 7
+D 9
+L 9
+D 4
+L 9
+D 9
+U 9
+R 7
+L 4
+R 8
+L 13
+U 2
+D 3
+R 3
+U 4
+D 8
+L 4
+R 6
+U 10
+L 1
+U 11
+L 13
+U 13
+D 10
+L 13
+R 3
+L 1
+D 4
+R 3
+L 7
+U 10
+L 4
+R 7
+U 10
+D 8
+L 9
+D 4
+U 5
+R 12
+U 1
+R 9
+D 6
+L 2
+D 6
+R 12
+U 11
+L 11
+U 2
+D 11
+L 11
+R 9
+L 13
+R 6
+U 5
+R 13
+L 7
+U 5
+R 1
+L 6
+R 1
+L 5
+U 10
+D 10
+R 11
+L 13
+R 5
+L 13
+R 3
+D 2
+L 3
+D 10
+U 4
+D 7
+L 7
+D 14
+R 4
+U 3
+R 14
+L 3
+R 3
+U 12
+R 10
+U 9
+D 14
+R 2
+U 5
+D 12
+U 3
+R 5
+L 8
+R 8
+L 2
+U 5
+R 13
+U 13
+R 7
+D 3
+L 8
+U 2
+L 3
+U 13
+L 8
+D 10
+L 6
+U 13
+L 6
+U 11
+R 10
+L 7
+D 2
+U 4
+L 13
+R 5
+U 10
+D 14
+L 3
+D 13
+L 13
+D 11
+L 7
+U 6
+R 5
+D 9
+L 3
+R 10
+L 3
+R 8
+L 10
+D 11
+R 3
+U 3
+D 6
+L 7
+U 13
+R 8
+D 6
+R 3
+D 11
+R 11
+D 7
+U 2
+R 9
+L 7
+D 7
+R 13
+L 1
+R 5
+D 14
+U 10
+R 13
+U 12
+L 7
+D 14
+U 8
+R 5
+U 4
+D 5
+U 14
+L 3
+U 3
+D 13
+U 2
+R 9
+U 7
+D 2
+L 10
+U 3
+R 12
+L 9
+R 8
+L 3
+D 13
+U 10
+R 12
+D 7
+U 10
+L 12
+D 8
+L 13
+D 14
+L 4
+D 4
+L 5
+U 11
+D 4
+L 2
+U 9
+D 3
+L 3
+D 12
+L 14
+R 15
+L 10
+U 2
+D 10
+U 14
+R 5
+L 12
+R 8
+D 1
+L 4
+R 13
+D 10
+R 12
+L 5
+U 8
+D 12
+U 5
+R 2
+L 4
+U 1
+D 13
+U 6
+R 14
+D 14
+R 10
+D 8
+U 12
+L 7
+U 2
+L 13
+R 11
+L 13
+D 11
+R 1
+U 13
+R 6
+D 8
+L 4
+R 3
+D 7
+U 1
+L 8
+U 15
+D 3
+L 9
+R 10
+U 4
+D 8
+R 2
+D 13
+L 13
+U 4
+D 10
+L 12
+R 14
+U 9
+L 4
+U 1
+D 7
+R 2
+U 8
+L 6
+R 9
+U 4
+L 9
+U 8
+L 9
+U 9
+R 6
+L 12
+U 12
+L 1
+R 15
+U 4
+R 7
+L 5
+D 9
+R 1
+L 15
+D 1
+R 10
+D 4
+R 5
+D 6
+R 15
+U 15
+L 9
+D 3
+L 9
+U 11
+L 8
+U 9
+L 15
+U 14
+L 10
+R 8
+D 3
+R 8
+U 8
+R 4
+D 9
+L 1
+U 11
+L 14
+R 1
+D 12
+L 10
+D 3
+L 1
+R 1
+U 16
+D 7
+R 13
+D 11
+L 7
+U 7
+D 16
+L 16
+D 3
+L 12
+D 14
+R 11
+D 15
+R 2
+U 10
+R 10
+D 1
+R 9
+U 11
+D 7
+U 15
+D 7
+R 15
+L 11
+D 1
+L 9
+D 2
+R 4
+L 1
+R 7
+L 6
+U 6
+L 16
+R 12
+D 7
+L 1
+U 3
+D 16
+R 1
+D 8
+R 15
+L 4
+U 10
+R 14
+U 4
+R 15
+L 14
+R 7
+D 7
+L 8
+R 7
+L 10
+R 1
+D 4
+U 12
+L 15
+R 16
+U 10
+D 13
+U 12
+R 2
+D 3
+U 2
+L 1
+R 13
+U 7
+L 9
+D 12
+L 16
+D 4
+L 4
+D 1
+R 9
+L 10
+R 1
+D 6
+L 12
+R 12
+U 8
+D 4
+L 3
+R 6
+L 12
+U 12
+D 3
+R 6
+U 11
+R 11
+U 12
+L 11
+R 2
+U 4
+D 2
+U 16
+R 9
+D 16
+L 4
+U 5
+L 16
+U 1
+L 7
+R 13
+L 2
+D 16
+L 10
+D 14
+R 9
+U 14
+L 15
+D 12
+L 12
+D 5
+L 14
+R 17
+L 13
+R 7
+L 7
+U 14
+R 17
+L 12
+U 9
+D 16
+R 1
+D 5
+R 4
+D 12
+R 13
+L 15
+D 5
+R 7
+U 5
+L 10
+R 1
+U 4
+R 5
+L 16
+D 11
+U 13
+D 12
+L 1
+U 1
+L 10
+U 1
+L 1
+R 3
+D 13
+U 10
+L 17
+D 11
+L 10
+U 10
+L 12
+D 10
+L 11
+D 7
+R 17
+L 2
+R 15
+D 17
+R 8
+U 16
+L 17
+D 8
+L 7
+D 3
+R 5
+L 12
+R 9
+D 14
+U 3
+D 7
+L 1
+U 1
+D 5
+L 12
+U 12
+R 9
+L 15
+D 6
+L 5
+U 5
+D 17
+L 7
+R 14
+U 14
+R 10
+L 5
+U 5
+D 12
+U 5
+R 14
+L 11
+D 1
+R 3
+L 16
+R 6
+U 14
+D 1
+L 9
+R 17
+D 3
+U 3
+R 16
+L 12
+R 6
+U 1
+D 11
+U 10
+L 7
+D 4
+R 10
+D 14
+R 11
+L 4
+D 11
+R 7
+L 10
+D 8
+U 4
+L 11
+R 8
+U 10
+L 17
+D 2
+R 4
+L 13
+U 7
+L 13
+U 3
+D 16
+R 17
+D 8
+L 1
+R 4
+U 16
+R 1
+U 13
+L 4
+R 18
+U 7
+L 5
+D 14
+U 17
+L 2
+D 8
+R 9
+U 16
+D 4
+U 18
+L 1
+U 2
+L 13
+R 16
+D 10
+R 6
+D 11
+L 5
+U 17
+L 8
+R 15
+U 8
+L 4
+R 1
+D 10
+L 1
+U 18
+R 6
+U 5
+R 8
+U 1
+D 15
+L 5
+D 13
+U 14
+R 5
+U 1
+L 4
+D 6
+R 8
+U 17
+D 14
+U 6
+R 9
+D 1
+L 11
+D 6
+L 11
+U 17
+L 1
+D 17
+L 4
+D 2
+U 9
+R 9
+D 17
+U 4
+L 6
+U 2
+D 2
+R 6
+D 12
+R 10
+D 11
+L 7
+D 3
+U 14
+R 1
+L 18
+D 15
+L 3
+R 5
+L 15
+U 5
+R 11
+D 10
+L 14
+D 2
+R 5
+U 12
+R 8
+D 10
+R 14
+D 18
+U 4
+R 18
+D 11
+R 11
+U 2
+L 7
+R 1
+U 18
+L 3
+U 13
+R 16
+D 8
+U 7
+R 1
+U 2
+R 15
+U 3
+R 13
+D 14
+L 15
+U 10
+L 12
+U 6
+R 14
+D 14
+U 1
+D 8
+R 13
+D 14
+L 10
+R 4
+D 1
+L 3
+U 13
+R 17
+D 12
+L 4
+U 15
+R 3
+U 19
+D 15
+U 2
+D 7
+U 8
+L 19
+D 17
+U 16
+D 13
+L 3
+R 16
+D 4
+R 17
+L 10
+R 5
+U 10
+L 18
+U 15
+R 11
+D 1
+R 14
+D 7
+R 4
+U 19
+R 14
+U 19
+D 16
+L 14
+R 17
+L 9
+R 16
+L 14
+D 10
+R 1
+U 2
+L 3
+R 12
+D 4
+U 12
+R 16
+L 4
+R 3
+U 9
+R 19
+U 2
+L 13
+D 11
+L 7
+D 11
+U 3
+R 1
+L 8
+R 7
+L 15
+D 9
+U 12
+D 10
+R 9
+U 16
+R 11
+L 11
+R 6
+U 11
+D 9
+L 8
+R 7
+L 9
+R 13
+D 14
+U 11
+R 14
+L 17
+U 9
+L 17
+R 9
+L 10
diff --git a/day09b/examples/test.txt b/day09b/examples/test.txt
new file mode 100644
index 0000000..60bd43b
--- /dev/null
+++ b/day09b/examples/test.txt
@@ -0,0 +1,8 @@
+R 5
+U 8
+L 8
+D 3
+R 17
+D 10
+L 25
+U 20
diff --git a/day09b/src/main.rs b/day09b/src/main.rs
new file mode 100644
index 0000000..7cee4ad
--- /dev/null
+++ b/day09b/src/main.rs
@@ -0,0 +1,605 @@
+/// --- Part Two ---
+///
+/// A rope snaps! Suddenly, the river is getting a lot closer than you remember. The bridge is
+/// still there, but some of the ropes that broke are now whipping toward you as you fall through
+/// the air!
+///
+/// The ropes are moving too quickly to grab; you only have a few seconds to choose how to arch
+/// your body to avoid being hit. Fortunately, your simulation can be extended to support longer
+/// ropes.
+///
+/// Rather than two knots, you now must simulate a rope consisting of ten knots. One knot is still
+/// the head of the rope and moves according to the series of motions. Each knot further down the
+/// rope follows the knot in front of it using the same rules as before.
+///
+/// Using the same series of motions as the above example, but with the knots marked H, 1, 2, ...,
+/// 9, the motions now occur as follows:
+///
+/// ```
+/// == Initial State ==
+///
+/// ......
+/// ......
+/// ......
+/// ......
+/// H..... (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s)
+///
+/// == R 4 ==
+///
+/// ......
+/// ......
+/// ......
+/// ......
+/// 1H.... (1 covers 2, 3, 4, 5, 6, 7, 8, 9, s)
+///
+/// ......
+/// ......
+/// ......
+/// ......
+/// 21H... (2 covers 3, 4, 5, 6, 7, 8, 9, s)
+///
+/// ......
+/// ......
+/// ......
+/// ......
+/// 321H.. (3 covers 4, 5, 6, 7, 8, 9, s)
+///
+/// ......
+/// ......
+/// ......
+/// ......
+/// 4321H. (4 covers 5, 6, 7, 8, 9, s)
+///
+/// == U 4 ==
+///
+/// ......
+/// ......
+/// ......
+/// ....H.
+/// 4321.. (4 covers 5, 6, 7, 8, 9, s)
+///
+/// ......
+/// ......
+/// ....H.
+/// .4321.
+/// 5..... (5 covers 6, 7, 8, 9, s)
+///
+/// ......
+/// ....H.
+/// ....1.
+/// .432..
+/// 5..... (5 covers 6, 7, 8, 9, s)
+///
+/// ....H.
+/// ....1.
+/// ..432.
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// == L 3 ==
+///
+/// ...H..
+/// ....1.
+/// ..432.
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// ..H1..
+/// ...2..
+/// ..43..
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// .H1...
+/// ...2..
+/// ..43..
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// == D 1 ==
+///
+/// ..1...
+/// .H.2..
+/// ..43..
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// == R 4 ==
+///
+/// ..1...
+/// ..H2..
+/// ..43..
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// ..1...
+/// ...H.. (H covers 2)
+/// ..43..
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// ......
+/// ...1H. (1 covers 2)
+/// ..43..
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// ......
+/// ...21H
+/// ..43..
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// == D 1 ==
+///
+/// ......
+/// ...21.
+/// ..43.H
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// == L 5 ==
+///
+/// ......
+/// ...21.
+/// ..43H.
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// ......
+/// ...21.
+/// ..4H.. (H covers 3)
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// ......
+/// ...2..
+/// ..H1.. (H covers 4; 1 covers 3)
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// ......
+/// ...2..
+/// .H13.. (1 covers 4)
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// ......
+/// ......
+/// H123.. (2 covers 4)
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// == R 2 ==
+///
+/// ......
+/// ......
+/// .H23.. (H covers 1; 2 covers 4)
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+///
+/// ......
+/// ......
+/// .1H3.. (H covers 2, 4)
+/// .5....
+/// 6..... (6 covers 7, 8, 9, s)
+/// ```
+///
+/// Now, you need to keep track of the positions the new tail, 9, visits. In this example, the
+/// tail never moves, and so it only visits 1 position. However, be careful: more types of motion
+/// are possible than before, so you might want to visually compare your simulated rope to the one
+/// above.
+///
+/// Here's a larger example:
+///
+/// ```
+/// R 5
+/// U 8
+/// L 8
+/// D 3
+/// R 17
+/// D 10
+/// L 25
+/// U 20
+/// ```
+///
+/// These motions occur as follows (individual steps are not shown):
+///
+/// ```
+/// == Initial State ==
+///
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ...........H.............. (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s)
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+///
+/// == R 5 ==
+///
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ...........54321H......... (5 covers 6, 7, 8, 9, s)
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+///
+/// == U 8 ==
+///
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ................H.........
+/// ................1.........
+/// ................2.........
+/// ................3.........
+/// ...............54.........
+/// ..............6...........
+/// .............7............
+/// ............8.............
+/// ...........9.............. (9 covers s)
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+///
+/// == L 8 ==
+///
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ........H1234.............
+/// ............5.............
+/// ............6.............
+/// ............7.............
+/// ............8.............
+/// ............9.............
+/// ..........................
+/// ..........................
+/// ...........s..............
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+///
+/// == D 3 ==
+///
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// .........2345.............
+/// ........1...6.............
+/// ........H...7.............
+/// ............8.............
+/// ............9.............
+/// ..........................
+/// ..........................
+/// ...........s..............
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+///
+/// == R 17 ==
+///
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ................987654321H
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ...........s..............
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+///
+/// == D 10 ==
+///
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ...........s.........98765
+/// .........................4
+/// .........................3
+/// .........................2
+/// .........................1
+/// .........................H
+///
+/// == L 25 ==
+///
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ...........s..............
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// H123456789................
+///
+/// == U 20 ==
+///
+/// H.........................
+/// 1.........................
+/// 2.........................
+/// 3.........................
+/// 4.........................
+/// 5.........................
+/// 6.........................
+/// 7.........................
+/// 8.........................
+/// 9.........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ...........s..............
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+///
+/// Now, the tail (9) visits 36 positions (including s) at least once:
+///
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// ..........................
+/// #.........................
+/// #.............###.........
+/// #............#...#........
+/// .#..........#.....#.......
+/// ..#..........#.....#......
+/// ...#........#.......#.....
+/// ....#......s.........#....
+/// .....#..............#.....
+/// ......#............#......
+/// .......#..........#.......
+/// ........#........#........
+/// .........########.........
+/// ```
+///
+/// Simulate your complete series of motions on a larger rope with ten knots. How many positions
+/// does the tail of the rope visit at least once?
+use clap::Parser;
+use itertools::Itertools;
+
+use std::collections::HashSet;
+use std::fs::File;
+use std::io::prelude::*;
+use std::io::BufReader;
+use std::path::PathBuf;
+
+const FILEPATH: &'static str = "examples/input.txt";
+const KNOTS: usize = 10;
+
+#[derive(Parser, Debug)]
+#[clap(author, version, about, long_about = None)]
+struct Cli {
+ #[clap(short, long, default_value = FILEPATH)]
+ file: PathBuf,
+}
+
+#[derive(Copy, Clone, Debug)]
+enum Direction {
+ Up,
+ Down,
+ Left,
+ Right,
+}
+
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
+struct Coord {
+ x: i32,
+ y: i32,
+}
+
+#[derive(Clone, Debug)]
+struct Command {
+ dir: Direction,
+ amount: u32,
+}
+
+#[derive(Clone, Debug)]
+struct State {
+ head: Coord,
+ knots: [Coord; KNOTS - 1],
+ tail_visited: HashSet<Coord>,
+}
+
+impl Coord {
+ fn new() -> Self {
+ Self { x: 0, y: 0 }
+ }
+}
+
+impl Command {
+ fn parse(dir: &str, amount: &str) -> Self {
+ use Direction::*;
+ let d = match dir {
+ "U" => Up,
+ "D" => Down,
+ "L" => Left,
+ "R" => Right,
+ _ => panic!("unknown direction {}", dir),
+ };
+ Self {
+ dir: d,
+ amount: amount.parse::<u32>().unwrap(),
+ }
+ }
+}
+
+impl State {
+ fn new() -> Self {
+ let mut hs = HashSet::new();
+ hs.insert(Coord::new());
+ State {
+ head: Coord::new(),
+ knots: [Coord::new(); KNOTS - 1],
+ tail_visited: hs,
+ }
+ }
+
+ fn update_knot(&mut self, idx: usize, h_idx: Option<usize>) {
+ let head = match h_idx {
+ None => &self.head,
+ Some(h_idx) => &self.knots[h_idx],
+ };
+ match (head.x - self.knots[idx].x, head.y - self.knots[idx].y) {
+ (0, 0)
+ | (1, 0)
+ | (-1, 0)
+ | (0, 1)
+ | (0, -1)
+ | (1, 1)
+ | (-1, -1)
+ | (1, -1)
+ | (-1, 1) => return,
+ (xdiff, ydiff) => {
+ self.knots[idx].x += i32::signum(xdiff);
+ self.knots[idx].y += i32::signum(ydiff);
+ if idx == KNOTS - 2 {
+ self.tail_visited.insert(self.knots[idx]);
+ }
+ }
+ }
+ }
+
+ fn shift(&mut self, dir: Direction) {
+ use Direction::*;
+ match dir {
+ Up => self.head.y += 1,
+ Down => self.head.y -= 1,
+ Right => self.head.x += 1,
+ Left => self.head.x -= 1,
+ }
+ for idx in 0..(KNOTS - 1) {
+ let h_idx = match idx {
+ 0 => None,
+ _ => Some(idx - 1),
+ };
+ self.update_knot(idx, h_idx);
+ }
+ }
+
+ fn process(&mut self, cmd: &Command) {
+ for _ in 0..cmd.amount {
+ self.shift(cmd.dir);
+ }
+ }
+}
+
+fn main() {
+ let args = Cli::parse();
+
+ let file = File::open(&args.file).unwrap();
+ let reader = BufReader::new(file);
+ let mut state = State::new();
+ let _ = reader
+ .lines()
+ .map(|l| {
+ l.unwrap()
+ .split_whitespace()
+ .map(|s| s.to_owned())
+ .collect_tuple::<(String, String)>()
+ .unwrap()
+ })
+ .map(|(dir, amount)| Command::parse(dir.as_str(), amount.as_str()))
+ .scan(&mut state, |state, cmd| {
+ state.process(&cmd);
+ Some(())
+ })
+ .last();
+
+ let res = state.tail_visited.len();
+ println!("{res:?}");
+}