summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock18
-rw-r--r--Cargo.toml4
-rw-r--r--day14a/Cargo.toml11
-rw-r--r--day14a/examples/input.txt151
-rw-r--r--day14a/examples/test.txt2
-rw-r--r--day14a/src/main.rs438
-rw-r--r--day14b/Cargo.toml11
-rw-r--r--day14b/examples/input.txt151
-rw-r--r--day14b/examples/test.txt2
-rw-r--r--day14b/src/main.rs345
10 files changed, 1131 insertions, 2 deletions
diff --git a/Cargo.lock b/Cargo.lock
index aff08f7..e9eb9a7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -286,6 +286,24 @@ dependencies = [
]
[[package]]
+name = "day14a"
+version = "0.1.0"
+dependencies = [
+ "clap",
+ "itertools",
+ "nom",
+]
+
+[[package]]
+name = "day14b"
+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 c315226..25f033a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,8 +27,8 @@ members = [
"day12b",
"day13a",
"day13b",
- # "day14a",
- # "day14b",
+ "day14a",
+ "day14b",
# "day15a",
# "day15b",
# "day16a",
diff --git a/day14a/Cargo.toml b/day14a/Cargo.toml
new file mode 100644
index 0000000..8dbd6fe
--- /dev/null
+++ b/day14a/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "day14a"
+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/day14a/examples/input.txt b/day14a/examples/input.txt
new file mode 100644
index 0000000..c91a439
--- /dev/null
+++ b/day14a/examples/input.txt
@@ -0,0 +1,151 @@
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+495,155 -> 499,155
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+500,138 -> 505,138
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
+483,160 -> 487,160
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+491,131 -> 502,131 -> 502,130
+475,88 -> 475,89 -> 483,89 -> 483,88
+483,164 -> 487,164
+498,147 -> 503,147
+505,147 -> 510,147
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+516,150 -> 521,150
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+496,13 -> 501,13
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+512,147 -> 517,147
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+497,141 -> 502,141
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+480,162 -> 484,162
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+489,155 -> 493,155
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+498,157 -> 502,157
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+491,147 -> 496,147
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+475,88 -> 475,89 -> 483,89 -> 483,88
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+486,162 -> 490,162
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+508,144 -> 513,144
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
+477,164 -> 481,164
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+504,141 -> 509,141
+489,164 -> 493,164
+480,42 -> 485,42
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+486,157 -> 490,157
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+501,144 -> 506,144
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,166 -> 496,166
+509,150 -> 514,150
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+480,134 -> 480,135 -> 500,135 -> 500,134
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+486,166 -> 490,166
+494,144 -> 499,144
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+480,134 -> 480,135 -> 500,135 -> 500,134
+481,46 -> 486,46
+477,44 -> 482,44
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
+491,131 -> 502,131 -> 502,130
+492,157 -> 496,157
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+488,150 -> 493,150
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+474,46 -> 479,46
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+488,46 -> 493,46
+495,150 -> 500,150
+474,166 -> 478,166
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+484,44 -> 489,44
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+492,153 -> 496,153
+502,150 -> 507,150
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
+475,88 -> 475,89 -> 483,89 -> 483,88
+480,134 -> 480,135 -> 500,135 -> 500,134
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+480,166 -> 484,166
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
diff --git a/day14a/examples/test.txt b/day14a/examples/test.txt
new file mode 100644
index 0000000..4e87bb5
--- /dev/null
+++ b/day14a/examples/test.txt
@@ -0,0 +1,2 @@
+498,4 -> 498,6 -> 496,6
+503,4 -> 502,4 -> 502,9 -> 494,9
diff --git a/day14a/src/main.rs b/day14a/src/main.rs
new file mode 100644
index 0000000..a27e51c
--- /dev/null
+++ b/day14a/src/main.rs
@@ -0,0 +1,438 @@
+/// --- Day 14: Regolith Reservoir ---
+///
+/// The distress signal leads you to a giant waterfall! Actually, hang on - the signal seems like
+/// it's coming from the waterfall itself, and that doesn't make any sense. However, you do notice
+/// a little path that leads behind the waterfall.
+///
+/// Correction: the distress signal leads you behind a giant waterfall! There seems to be a large
+/// cave system here, and the signal definitely leads further inside.
+///
+/// As you begin to make your way deeper underground, you feel the ground rumble for a moment.
+/// Sand begins pouring into the cave! If you don't quickly figure out where the sand is going,
+/// you could quickly become trapped!
+///
+/// Fortunately, your familiarity with analyzing the path of falling material will come in handy
+/// here. You scan a two-dimensional vertical slice of the cave above you (your puzzle input) and
+/// discover that it is mostly air with structures made of rock.
+///
+/// Your scan traces the path of each solid rock structure and reports the x,y coordinates that
+/// form the shape of the path, where x represents distance to the right and y represents distance
+/// down. Each path appears as a single line of text in your scan. After the first point of each
+/// path, each point indicates the end of a straight horizontal or vertical line to be drawn from
+/// the previous point. For example:
+///
+/// ```
+/// 498,4 -> 498,6 -> 496,6
+/// 503,4 -> 502,4 -> 502,9 -> 494,9
+/// ```
+///
+/// This scan means that there are two paths of rock; the first path consists of two straight
+/// lines, and the second path consists of three straight lines. (Specifically, the first path
+/// consists of a line of rock from 498,4 through 498,6 and another line of rock from 498,6 through
+/// 496,6.)
+///
+/// The sand is pouring into the cave from point 500,0.
+///
+/// Drawing rock as #, air as ., and the source of the sand as +, this becomes:
+///
+///
+/// ```
+/// 4 5 5
+/// 9 0 0
+/// 4 0 3
+/// 0 ......+...
+/// 1 ..........
+/// 2 ..........
+/// 3 ..........
+/// 4 ....#...##
+/// 5 ....#...#.
+/// 6 ..###...#.
+/// 7 ........#.
+/// 8 ........#.
+/// 9 #########.
+/// ```
+///
+/// Sand is produced one unit at a time, and the next unit of sand is not produced until the
+/// previous unit of sand comes to rest. A unit of sand is large enough to fill one tile of air in
+/// your scan.
+///
+/// A unit of sand always falls down one step if possible. If the tile immediately below is
+/// blocked (by rock or sand), the unit of sand attempts to instead move diagonally one step down
+/// and to the left. If that tile is blocked, the unit of sand attempts to instead move diagonally
+/// one step down and to the right. Sand keeps moving as long as it is able to do so, at each step
+/// trying to move down, then down-left, then down-right. If all three possible destinations are
+/// blocked, the unit of sand comes to rest and no longer moves, at which point the next unit of
+/// sand is created back at the source.
+///
+/// So, drawing sand that has come to rest as o, the first unit of sand simply falls straight down
+/// and then stops:
+///
+/// ```
+/// ......+...
+/// ..........
+/// ..........
+/// ..........
+/// ....#...##
+/// ....#...#.
+/// ..###...#.
+/// ........#.
+/// ......o.#.
+/// #########.
+/// ```
+///
+/// The second unit of sand then falls straight down, lands on the first one, and then comes to
+/// rest to its left:
+///
+/// ```
+/// ......+...
+/// ..........
+/// ..........
+/// ..........
+/// ....#...##
+/// ....#...#.
+/// ..###...#.
+/// ........#.
+/// .....oo.#.
+/// #########.
+/// ```
+///
+/// After a total of five units of sand have come to rest, they form this pattern:
+///
+/// ```
+/// ......+...
+/// ..........
+/// ..........
+/// ..........
+/// ....#...##
+/// ....#...#.
+/// ..###...#.
+/// ......o.#.
+/// ....oooo#.
+/// #########.
+/// ```
+///
+/// After a total of 22 units of sand:
+///
+/// ```
+/// ......+...
+/// ..........
+/// ......o...
+/// .....ooo..
+/// ....#ooo##
+/// ....#ooo#.
+/// ..###ooo#.
+/// ....oooo#.
+/// ...ooooo#.
+/// #########.
+/// ```
+///
+/// Finally, only two more units of sand can possibly come to rest:
+///
+/// ```
+/// ......+...
+/// ..........
+/// ......o...
+/// .....ooo..
+/// ....#ooo##
+/// ...o#ooo#.
+/// ..###ooo#.
+/// ....oooo#.
+/// .o.ooooo#.
+/// #########.
+/// ```
+///
+/// Once all 24 units of sand shown above have come to rest, all further sand flows out the bottom,
+/// falling into the endless void. Just for fun, the path any new sand takes before falling
+/// forever is shown here with ~:
+///
+/// ```
+/// .......+...
+/// .......~...
+/// ......~o...
+/// .....~ooo..
+/// ....~#ooo##
+/// ...~o#ooo#.
+/// ..~###ooo#.
+/// ..~..oooo#.
+/// .~o.ooooo#.
+/// ~#########.
+/// ~..........
+/// ~..........
+/// ~..........
+/// ```
+///
+/// Using your scan, simulate the falling sand. How many units of sand come to rest before sand
+/// starts flowing into the abyss below?
+use clap::Parser;
+use itertools::Itertools;
+use nom::bytes::complete::tag;
+use nom::character::complete::i32;
+use nom::combinator::{map, opt};
+use nom::error::{ContextError, ErrorKind as NomErrorKind, ParseError};
+use nom::multi::many1;
+use nom::sequence::{terminated, tuple};
+use nom::IResult;
+
+use std::fs::File;
+use std::io::prelude::*;
+use std::io::BufReader;
+use std::path::PathBuf;
+
+const FILEPATH: &'static str = "examples/input.txt";
+const SAND_SOURCE: Coords = Coords { x: 500, y: 0 };
+
+pub type Input<'a> = &'a str;
+pub type Result<'a, T> = IResult<Input<'a>, T, Error<Input<'a>>>;
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub enum ErrorKind {
+ Nom(NomErrorKind),
+ Context(&'static str),
+ Custom(String),
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+enum Terrain {
+ Air,
+ Rock,
+ Sand,
+ SandSource,
+}
+
+#[derive(Parser, Debug)]
+#[clap(author, version, about, long_about = None)]
+struct Cli {
+ #[clap(short, long, default_value = FILEPATH)]
+ file: PathBuf,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Error<I> {
+ pub errors: Vec<(I, ErrorKind)>,
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+struct Coords {
+ x: i32,
+ y: i32,
+}
+
+impl Coords {
+ fn path_between(&self, other: &Coords) -> Vec<Coords> {
+ if self == other {
+ panic!()
+ }
+ if self.x == other.x {
+ let yrange = {
+ if self.y > other.y {
+ other.y..=self.y
+ } else if other.y > self.y {
+ self.y..=other.y
+ } else {
+ panic!()
+ }
+ };
+ yrange.map(|y| Coords { x: self.x, y }).collect_vec()
+ } else {
+ let xrange = {
+ if self.x > other.x {
+ other.x..=self.x
+ } else if other.x > self.x {
+ self.x..=other.x
+ } else {
+ panic!()
+ }
+ };
+ xrange.map(|x| Coords { x, y: self.y }).collect_vec()
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+struct Grid {
+ data: Vec<Vec<Terrain>>,
+ bounds: GridBoundaries,
+}
+
+impl Grid {
+ fn new(bounds: GridBoundaries) -> Self {
+ let xlen = (bounds.maxx - bounds.minx) as usize + 1;
+ let ylen = (bounds.maxy - bounds.miny) as usize + 1;
+ let data = vec![vec![Terrain::Air; ylen]; xlen];
+ Self { data, bounds }
+ }
+
+ fn get(&self, coord: &Coords) -> &Terrain {
+ &self.data[(coord.x - self.bounds.minx) as usize][(coord.y - self.bounds.miny) as usize]
+ }
+
+ fn set(&mut self, coord: &Coords, terrain: Terrain) {
+ self.data[(coord.x - self.bounds.minx) as usize][(coord.y - self.bounds.miny) as usize] =
+ terrain;
+ }
+
+ fn populate(&mut self, geography: Vec<RockStructure>) {
+ geography
+ .into_iter()
+ .map(|rstruct| {
+ rstruct
+ .0
+ .as_slice()
+ .windows(2)
+ .map(|window| window[0].path_between(&window[1]))
+ .flatten()
+ .collect_vec()
+ })
+ .flatten()
+ .scan(self, |state, coords| {
+ state.data[(coords.x - state.bounds.minx) as usize]
+ [(coords.y - state.bounds.miny) as usize] = Terrain::Rock;
+ Some(())
+ })
+ .last()
+ .unwrap()
+ }
+
+ fn run(&mut self) -> usize {
+ let mut count = 0;
+ let mut pos = SAND_SOURCE;
+ let mut history = vec![SAND_SOURCE];
+ 'block: loop {
+ for (dx, dy) in [(0, 1), (-1, 1), (1, 1)] {
+ let next_pos = Coords {
+ x: &pos.x + dx,
+ y: &pos.y + dy,
+ };
+
+ if (next_pos.x < self.bounds.minx)
+ || (next_pos.x > self.bounds.maxx)
+ || (next_pos.y > self.bounds.maxy)
+ {
+ break 'block;
+ }
+
+ if self.get(&next_pos) == &Terrain::Air {
+ history.push(next_pos);
+ pos = next_pos;
+ continue 'block;
+ }
+ }
+
+ self.set(&pos, Terrain::Sand);
+ pos = {
+ loop {
+ let prev_pos = history[history.len() - 1];
+ match self.get(&prev_pos) {
+ Terrain::Air | Terrain::SandSource => break prev_pos,
+ _ => {
+ let _ = history.pop();
+ continue;
+ }
+ };
+ }
+ };
+ count += 1;
+ }
+ count
+ }
+}
+
+#[derive(Clone, Debug)]
+struct GridBoundaries {
+ minx: i32,
+ maxx: i32,
+ miny: i32,
+ maxy: i32,
+}
+
+impl GridBoundaries {
+ fn new() -> Self {
+ GridBoundaries {
+ minx: i32::max_value(),
+ maxx: i32::min_value(),
+ miny: 0,
+ maxy: i32::min_value(),
+ }
+ }
+
+ fn combine(&mut self, other: &GridBoundaries) {
+ self.minx = i32::min(self.minx, other.minx);
+ self.maxx = i32::max(self.maxx, other.maxx);
+ self.miny = i32::min(self.miny, other.miny);
+ self.maxy = i32::max(self.maxy, other.maxy);
+ }
+
+ fn fold(&self, other: &Coords) -> Self {
+ let mut res = GridBoundaries::new();
+ res.minx = i32::min(self.minx, other.x);
+ res.maxx = i32::max(self.maxx, other.x);
+ res.miny = i32::min(self.miny, other.y);
+ res.maxy = i32::max(self.maxy, other.y);
+ res
+ }
+}
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+struct RockStructure(Vec<Coords>);
+
+impl<I> ParseError<I> for Error<I> {
+ fn from_error_kind(input: I, kind: NomErrorKind) -> Self {
+ let errors = vec![(input, ErrorKind::Nom(kind))];
+ Self { errors }
+ }
+
+ fn append(input: I, kind: NomErrorKind, mut other: Self) -> Self {
+ other.errors.push((input, ErrorKind::Nom(kind)));
+ other
+ }
+}
+
+impl<I> ContextError<I> for Error<I> {
+ fn add_context(input: I, ctx: &'static str, mut other: Self) -> Self {
+ other.errors.push((input, ErrorKind::Context(ctx)));
+ other
+ }
+}
+
+fn parse_coord(input: &str) -> Result<Coords> {
+ map(tuple((terminated(i32, tag(",")), i32)), |(x, y)| Coords {
+ x,
+ y,
+ })(input)
+}
+
+fn parse_line(input: &str) -> Result<RockStructure> {
+ map(many1(terminated(parse_coord, opt(tag(" -> ")))), |v| {
+ RockStructure(v)
+ })(input)
+}
+
+fn main() {
+ let args = Cli::parse();
+
+ let file = File::open(&args.file).unwrap();
+ let reader = BufReader::new(file);
+
+ let mut bounds = GridBoundaries::new();
+ let geography = reader
+ .lines()
+ .map(|l| parse_line(l.unwrap().as_str()).unwrap().1)
+ .scan(&mut bounds, |state, rstruct| {
+ state.combine(
+ &rstruct
+ .0
+ .iter()
+ .fold(GridBoundaries::new(), |acc, x| acc.fold(x)),
+ );
+ Some(rstruct)
+ })
+ .collect_vec();
+
+ let mut grid = Grid::new(bounds);
+ grid.set(&SAND_SOURCE, Terrain::SandSource);
+ grid.populate(geography);
+ assert_eq!(grid.get(&SAND_SOURCE), &Terrain::SandSource);
+
+ let res = grid.run();
+ println!("{res:?}");
+}
diff --git a/day14b/Cargo.toml b/day14b/Cargo.toml
new file mode 100644
index 0000000..7331590
--- /dev/null
+++ b/day14b/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "day14b"
+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/day14b/examples/input.txt b/day14b/examples/input.txt
new file mode 100644
index 0000000..c91a439
--- /dev/null
+++ b/day14b/examples/input.txt
@@ -0,0 +1,151 @@
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+495,155 -> 499,155
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+500,138 -> 505,138
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
+483,160 -> 487,160
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+491,131 -> 502,131 -> 502,130
+475,88 -> 475,89 -> 483,89 -> 483,88
+483,164 -> 487,164
+498,147 -> 503,147
+505,147 -> 510,147
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+516,150 -> 521,150
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+496,13 -> 501,13
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+512,147 -> 517,147
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+497,141 -> 502,141
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+480,162 -> 484,162
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+489,155 -> 493,155
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+498,157 -> 502,157
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+491,147 -> 496,147
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+475,88 -> 475,89 -> 483,89 -> 483,88
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+486,162 -> 490,162
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+508,144 -> 513,144
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
+477,164 -> 481,164
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+504,141 -> 509,141
+489,164 -> 493,164
+480,42 -> 485,42
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+486,157 -> 490,157
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+501,144 -> 506,144
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+492,166 -> 496,166
+509,150 -> 514,150
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+480,134 -> 480,135 -> 500,135 -> 500,134
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+486,166 -> 490,166
+494,144 -> 499,144
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+480,134 -> 480,135 -> 500,135 -> 500,134
+481,46 -> 486,46
+477,44 -> 482,44
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
+491,131 -> 502,131 -> 502,130
+492,157 -> 496,157
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+488,150 -> 493,150
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+474,46 -> 479,46
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+488,46 -> 493,46
+495,150 -> 500,150
+474,166 -> 478,166
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+484,44 -> 489,44
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115
+492,153 -> 496,153
+502,150 -> 507,150
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
+475,88 -> 475,89 -> 483,89 -> 483,88
+480,134 -> 480,135 -> 500,135 -> 500,134
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26
+480,166 -> 484,166
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
+470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76
+485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112
+470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49
diff --git a/day14b/examples/test.txt b/day14b/examples/test.txt
new file mode 100644
index 0000000..4e87bb5
--- /dev/null
+++ b/day14b/examples/test.txt
@@ -0,0 +1,2 @@
+498,4 -> 498,6 -> 496,6
+503,4 -> 502,4 -> 502,9 -> 494,9
diff --git a/day14b/src/main.rs b/day14b/src/main.rs
new file mode 100644
index 0000000..f1c3846
--- /dev/null
+++ b/day14b/src/main.rs
@@ -0,0 +1,345 @@
+/// --- Part Two ---
+///
+/// You realize you misread the scan. There isn't an endless void at the bottom of the scan -
+/// there's floor, and you're standing on it!
+///
+/// You don't have time to scan the floor, so assume the floor is an infinite horizontal line with
+/// a y coordinate equal to two plus the highest y coordinate of any point in your scan.
+///
+/// In the example above, the highest y coordinate of any point is 9, and so the floor is at y=11.
+/// (This is as if your scan contained one extra rock path like -infinity,11 -> infinity,11.) With
+/// the added floor, the example above now looks like this:
+///
+/// ```
+/// ...........+........
+/// ....................
+/// ....................
+/// ....................
+/// .........#...##.....
+/// .........#...#......
+/// .......###...#......
+/// .............#......
+/// .............#......
+/// .....#########......
+/// ....................
+/// <-- etc #################### etc -->
+/// ```
+///
+/// To find somewhere safe to stand, you'll need to simulate falling sand until a unit of sand
+/// comes to rest at 500,0, blocking the source entirely and stopping the flow of sand into the
+/// cave. In the example above, the situation finally looks like this after 93 units of sand come
+/// to rest:
+///
+/// ```
+/// ............o............
+/// ...........ooo...........
+/// ..........ooooo..........
+/// .........ooooooo.........
+/// ........oo#ooo##o........
+/// .......ooo#ooo#ooo.......
+/// ......oo###ooo#oooo......
+/// .....oooo.oooo#ooooo.....
+/// ....oooooooooo#oooooo....
+/// ...ooo#########ooooooo...
+/// ..ooooo.......ooooooooo..
+/// #########################
+/// ```
+///
+/// Using your scan, simulate the falling sand until the source of the sand becomes blocked. How
+/// many units of sand come to rest?
+use clap::Parser;
+use itertools::Itertools;
+use nom::bytes::complete::tag;
+use nom::character::complete::i32;
+use nom::combinator::{map, opt};
+use nom::error::{ContextError, ErrorKind as NomErrorKind, ParseError};
+use nom::multi::many1;
+use nom::sequence::{terminated, tuple};
+use nom::IResult;
+
+use std::fs::File;
+use std::io::prelude::*;
+use std::io::BufReader;
+use std::path::PathBuf;
+
+const FILEPATH: &'static str = "examples/input.txt";
+const SAND_SOURCE: Coords = Coords { x: 500, y: 0 };
+const FLOOR_OFFSET: usize = 2;
+
+pub type Input<'a> = &'a str;
+pub type Result<'a, T> = IResult<Input<'a>, T, Error<Input<'a>>>;
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub enum ErrorKind {
+ Nom(NomErrorKind),
+ Context(&'static str),
+ Custom(String),
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+enum Terrain {
+ Air,
+ Rock,
+ Sand,
+ SandSource,
+}
+
+#[derive(Parser, Debug)]
+#[clap(author, version, about, long_about = None)]
+struct Cli {
+ #[clap(short, long, default_value = FILEPATH)]
+ file: PathBuf,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Error<I> {
+ pub errors: Vec<(I, ErrorKind)>,
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+struct Coords {
+ x: i32,
+ y: i32,
+}
+
+impl Coords {
+ fn path_between(&self, other: &Coords) -> Vec<Coords> {
+ if self == other {
+ panic!()
+ }
+ if self.x == other.x {
+ let yrange = {
+ if self.y > other.y {
+ other.y..=self.y
+ } else if other.y > self.y {
+ self.y..=other.y
+ } else {
+ panic!()
+ }
+ };
+ yrange.map(|y| Coords { x: self.x, y }).collect_vec()
+ } else {
+ let xrange = {
+ if self.x > other.x {
+ other.x..=self.x
+ } else if other.x > self.x {
+ self.x..=other.x
+ } else {
+ panic!()
+ }
+ };
+ xrange.map(|x| Coords { x, y: self.y }).collect_vec()
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+struct Grid {
+ data: Vec<Vec<Terrain>>,
+ bounds: GridBoundaries,
+}
+
+impl Grid {
+ fn new(bounds: GridBoundaries) -> Self {
+ let xlen = (bounds.maxx - bounds.minx) as usize + 1;
+ let ylen = (bounds.maxy - bounds.miny) as usize + 1;
+ let data = vec![vec![Terrain::Air; ylen]; xlen];
+ Self { data, bounds }
+ }
+
+ fn get(&self, coord: &Coords) -> &Terrain {
+ &self.data[(coord.x - self.bounds.minx) as usize][(coord.y - self.bounds.miny) as usize]
+ }
+
+ fn set(&mut self, coord: &Coords, terrain: Terrain) {
+ self.data[(coord.x - self.bounds.minx) as usize][(coord.y - self.bounds.miny) as usize] =
+ terrain;
+ }
+
+ fn populate(&mut self, geography: Vec<RockStructure>) {
+ geography
+ .into_iter()
+ .map(|rstruct| {
+ rstruct
+ .0
+ .as_slice()
+ .windows(2)
+ .map(|window| window[0].path_between(&window[1]))
+ .flatten()
+ .collect_vec()
+ })
+ .flatten()
+ .scan(self, |state, coords| {
+ state.data[(coords.x - state.bounds.minx) as usize]
+ [(coords.y - state.bounds.miny) as usize] = Terrain::Rock;
+ Some(())
+ })
+ .last()
+ .unwrap()
+ }
+
+ fn run(&mut self) -> usize {
+ let mut count = 0;
+ let mut pos = SAND_SOURCE;
+ let mut history = vec![SAND_SOURCE];
+ 'block: loop {
+ for (dx, dy) in [(0, 1), (-1, 1), (1, 1)] {
+ let next_pos = Coords {
+ x: &pos.x + dx,
+ y: &pos.y + dy,
+ };
+
+ if (next_pos.x < self.bounds.minx)
+ || (next_pos.x > self.bounds.maxx)
+ {
+ continue;
+ }
+
+ if self.get(&next_pos) == &Terrain::Air {
+ history.push(next_pos);
+ pos = next_pos;
+ continue 'block;
+ }
+ }
+
+ count += 1;
+ if pos == SAND_SOURCE {
+ break 'block;
+ }
+ self.set(&pos, Terrain::Sand);
+ pos = {
+ loop {
+ let prev_pos = history[history.len() - 1];
+ match self.get(&prev_pos) {
+ Terrain::Air | Terrain::SandSource => break prev_pos,
+ _ => {
+ let _ = history.pop();
+ continue;
+ }
+ };
+ }
+ };
+ }
+ count
+ }
+}
+
+#[derive(Clone, Debug)]
+struct GridBoundaries {
+ minx: i32,
+ maxx: i32,
+ miny: i32,
+ maxy: i32,
+}
+
+impl GridBoundaries {
+ fn new() -> Self {
+ GridBoundaries {
+ minx: i32::max_value(),
+ maxx: i32::min_value(),
+ miny: 0,
+ maxy: i32::min_value(),
+ }
+ }
+
+ fn combine(&mut self, other: &GridBoundaries) {
+ self.minx = i32::min(self.minx, other.minx);
+ self.maxx = i32::max(self.maxx, other.maxx);
+ self.miny = i32::min(self.miny, other.miny);
+ self.maxy = i32::max(self.maxy, other.maxy);
+ }
+
+ fn fold(&self, other: &Coords) -> Self {
+ let mut res = GridBoundaries::new();
+ res.minx = i32::min(self.minx, other.x);
+ res.maxx = i32::max(self.maxx, other.x);
+ res.miny = i32::min(self.miny, other.y);
+ res.maxy = i32::max(self.maxy, other.y);
+ res
+ }
+}
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+struct RockStructure(Vec<Coords>);
+
+impl<I> ParseError<I> for Error<I> {
+ fn from_error_kind(input: I, kind: NomErrorKind) -> Self {
+ let errors = vec![(input, ErrorKind::Nom(kind))];
+ Self { errors }
+ }
+
+ fn append(input: I, kind: NomErrorKind, mut other: Self) -> Self {
+ other.errors.push((input, ErrorKind::Nom(kind)));
+ other
+ }
+}
+
+impl<I> ContextError<I> for Error<I> {
+ fn add_context(input: I, ctx: &'static str, mut other: Self) -> Self {
+ other.errors.push((input, ErrorKind::Context(ctx)));
+ other
+ }
+}
+
+fn parse_coord(input: &str) -> Result<Coords> {
+ map(tuple((terminated(i32, tag(",")), i32)), |(x, y)| Coords {
+ x,
+ y,
+ })(input)
+}
+
+fn parse_line(input: &str) -> Result<RockStructure> {
+ map(many1(terminated(parse_coord, opt(tag(" -> ")))), |v| {
+ RockStructure(v)
+ })(input)
+}
+
+fn main() {
+ let args = Cli::parse();
+
+ let file = File::open(&args.file).unwrap();
+ let reader = BufReader::new(file);
+
+ let mut bounds = GridBoundaries::new();
+ let mut geography = reader
+ .lines()
+ .map(|l| parse_line(l.unwrap().as_str()).unwrap().1)
+ .scan(&mut bounds, |state, rstruct| {
+ state.combine(
+ &rstruct
+ .0
+ .iter()
+ .fold(GridBoundaries::new(), |acc, x| acc.fold(x)),
+ );
+ Some(rstruct)
+ })
+ .collect_vec();
+
+ bounds.maxy = bounds.maxy + FLOOR_OFFSET as i32;
+ let max_x_len = 2 * bounds.maxy - 1;
+ let minx = SAND_SOURCE.x - (max_x_len - 1) / 2;
+ let maxx = SAND_SOURCE.x + (max_x_len - 1) / 2;
+ assert!(minx < bounds.minx);
+ assert!(maxx > bounds.maxx);
+ bounds.minx = minx;
+ bounds.maxx = maxx;
+
+ geography.push(RockStructure(vec![
+ Coords {
+ x: minx,
+ y: bounds.maxy,
+ },
+ Coords {
+ x: maxx,
+ y: bounds.maxy,
+ },
+ ]));
+
+ let mut grid = Grid::new(bounds);
+ grid.set(&SAND_SOURCE, Terrain::SandSource);
+ grid.populate(geography);
+ assert_eq!(grid.get(&SAND_SOURCE), &Terrain::SandSource);
+
+ let res = grid.run();
+ println!("{res:?}");
+}