diff --git a/.aoc-cache/14.txt b/.aoc-cache/14.txt
new file mode 100644
index 0000000..d10b058
--- /dev/null
+++ b/.aoc-cache/14.txt
@@ -0,0 +1,151 @@
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+520,82 -> 524,82
+496,164 -> 500,164
+505,162 -> 509,162
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+526,94 -> 530,94
+513,116 -> 517,116
+493,162 -> 497,162
+505,123 -> 505,125 -> 501,125 -> 501,130 -> 511,130 -> 511,125 -> 508,125 -> 508,123
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+507,149 -> 507,151 -> 502,151 -> 502,155 -> 516,155 -> 516,151 -> 511,151 -> 511,149
+539,66 -> 544,66
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+517,85 -> 521,85
+523,85 -> 527,85
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+499,158 -> 503,158
+502,160 -> 506,160
+508,164 -> 512,164
+526,88 -> 530,88
+505,123 -> 505,125 -> 501,125 -> 501,130 -> 511,130 -> 511,125 -> 508,125 -> 508,123
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+507,149 -> 507,151 -> 502,151 -> 502,155 -> 516,155 -> 516,151 -> 511,151 -> 511,149
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+514,42 -> 514,46 -> 508,46 -> 508,51 -> 525,51 -> 525,46 -> 517,46 -> 517,42
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+504,107 -> 504,99 -> 504,107 -> 506,107 -> 506,97 -> 506,107 -> 508,107 -> 508,103 -> 508,107
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+518,66 -> 523,66
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+504,107 -> 504,99 -> 504,107 -> 506,107 -> 506,97 -> 506,107 -> 508,107 -> 508,103 -> 508,107
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+502,164 -> 506,164
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+524,60 -> 529,60
+507,149 -> 507,151 -> 502,151 -> 502,155 -> 516,155 -> 516,151 -> 511,151 -> 511,149
+510,113 -> 514,113
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+514,94 -> 518,94
+511,91 -> 515,91
+504,107 -> 504,99 -> 504,107 -> 506,107 -> 506,97 -> 506,107 -> 508,107 -> 508,103 -> 508,107
+490,164 -> 494,164
+514,42 -> 514,46 -> 508,46 -> 508,51 -> 525,51 -> 525,46 -> 517,46 -> 517,42
+523,91 -> 527,91
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+520,57 -> 525,57
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+511,145 -> 511,146 -> 517,146 -> 517,145
+521,63 -> 526,63
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+503,39 -> 514,39
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+517,60 -> 522,60
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+504,107 -> 504,99 -> 504,107 -> 506,107 -> 506,97 -> 506,107 -> 508,107 -> 508,103 -> 508,107
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+505,123 -> 505,125 -> 501,125 -> 501,130 -> 511,130 -> 511,125 -> 508,125 -> 508,123
+528,63 -> 533,63
+507,149 -> 507,151 -> 502,151 -> 502,155 -> 516,155 -> 516,151 -> 511,151 -> 511,149
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+507,149 -> 507,151 -> 502,151 -> 502,155 -> 516,155 -> 516,151 -> 511,151 -> 511,149
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+514,42 -> 514,46 -> 508,46 -> 508,51 -> 525,51 -> 525,46 -> 517,46 -> 517,42
+507,149 -> 507,151 -> 502,151 -> 502,155 -> 516,155 -> 516,151 -> 511,151 -> 511,149
+491,136 -> 491,138 -> 483,138 -> 483,141 -> 499,141 -> 499,138 -> 496,138 -> 496,136
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+494,133 -> 503,133 -> 503,132
+531,60 -> 536,60
+505,123 -> 505,125 -> 501,125 -> 501,130 -> 511,130 -> 511,125 -> 508,125 -> 508,123
+523,54 -> 528,54
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+517,91 -> 521,91
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+504,107 -> 504,99 -> 504,107 -> 506,107 -> 506,97 -> 506,107 -> 508,107 -> 508,103 -> 508,107
+514,63 -> 519,63
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+514,42 -> 514,46 -> 508,46 -> 508,51 -> 525,51 -> 525,46 -> 517,46 -> 517,42
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+511,79 -> 511,77 -> 511,79 -> 513,79 -> 513,70 -> 513,79 -> 515,79 -> 515,73 -> 515,79 -> 517,79 -> 517,77 -> 517,79 -> 519,79 -> 519,77 -> 519,79 -> 521,79 -> 521,76 -> 521,79
+504,113 -> 508,113
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+491,136 -> 491,138 -> 483,138 -> 483,141 -> 499,141 -> 499,138 -> 496,138 -> 496,136
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+501,116 -> 505,116
+511,145 -> 511,146 -> 517,146 -> 517,145
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+532,94 -> 536,94
+491,136 -> 491,138 -> 483,138 -> 483,141 -> 499,141 -> 499,138 -> 496,138 -> 496,136
+499,162 -> 503,162
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+520,94 -> 524,94
+491,119 -> 491,120 -> 503,120 -> 503,119
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+491,119 -> 491,120 -> 503,120 -> 503,119
+504,107 -> 504,99 -> 504,107 -> 506,107 -> 506,97 -> 506,107 -> 508,107 -> 508,103 -> 508,107
+529,91 -> 533,91
+507,110 -> 511,110
+494,133 -> 503,133 -> 503,132
+491,136 -> 491,138 -> 483,138 -> 483,141 -> 499,141 -> 499,138 -> 496,138 -> 496,136
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+511,145 -> 511,146 -> 517,146 -> 517,145
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+514,42 -> 514,46 -> 508,46 -> 508,51 -> 525,51 -> 525,46 -> 517,46 -> 517,42
+491,119 -> 491,120 -> 503,120 -> 503,119
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+491,136 -> 491,138 -> 483,138 -> 483,141 -> 499,141 -> 499,138 -> 496,138 -> 496,136
+496,160 -> 500,160
+505,123 -> 505,125 -> 501,125 -> 501,130 -> 511,130 -> 511,125 -> 508,125 -> 508,123
+527,57 -> 532,57
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+508,94 -> 512,94
+532,66 -> 537,66
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+494,23 -> 494,17 -> 494,23 -> 496,23 -> 496,20 -> 496,23 -> 498,23 -> 498,16 -> 498,23 -> 500,23 -> 500,18 -> 500,23 -> 502,23 -> 502,19 -> 502,23 -> 504,23 -> 504,18 -> 504,23
+520,88 -> 524,88
+504,107 -> 504,99 -> 504,107 -> 506,107 -> 506,97 -> 506,107 -> 508,107 -> 508,103 -> 508,107
+514,88 -> 518,88
+514,42 -> 514,46 -> 508,46 -> 508,51 -> 525,51 -> 525,46 -> 517,46 -> 517,42
+504,107 -> 504,99 -> 504,107 -> 506,107 -> 506,97 -> 506,107 -> 508,107 -> 508,103 -> 508,107
+525,66 -> 530,66
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+491,136 -> 491,138 -> 483,138 -> 483,141 -> 499,141 -> 499,138 -> 496,138 -> 496,136
+535,63 -> 540,63
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+505,123 -> 505,125 -> 501,125 -> 501,130 -> 511,130 -> 511,125 -> 508,125 -> 508,123
+511,66 -> 516,66
+491,136 -> 491,138 -> 483,138 -> 483,141 -> 499,141 -> 499,138 -> 496,138 -> 496,136
+505,123 -> 505,125 -> 501,125 -> 501,130 -> 511,130 -> 511,125 -> 508,125 -> 508,123
+514,42 -> 514,46 -> 508,46 -> 508,51 -> 525,51 -> 525,46 -> 517,46 -> 517,42
+507,116 -> 511,116
+496,36 -> 496,34 -> 496,36 -> 498,36 -> 498,30 -> 498,36 -> 500,36 -> 500,31 -> 500,36 -> 502,36 -> 502,27 -> 502,36 -> 504,36 -> 504,29 -> 504,36 -> 506,36 -> 506,34 -> 506,36 -> 508,36 -> 508,34 -> 508,36 -> 510,36 -> 510,30 -> 510,36 -> 512,36 -> 512,30 -> 512,36
+507,149 -> 507,151 -> 502,151 -> 502,155 -> 516,155 -> 516,151 -> 511,151 -> 511,149
diff --git a/src/bin/day_14.rs b/src/bin/day_14.rs
new file mode 100644
index 0000000..c4654a5
--- /dev/null
+++ b/src/bin/day_14.rs
@@ -0,0 +1,162 @@
+use std::collections::HashMap;
+
+use aoc_2022::prelude::*;
+
+#[derive(Clone, Copy, Debug)]
+enum SolidNode {
+ Rock,
+ Sand,
+}
+
+type Input = (HashMap<(usize, usize), SolidNode>, usize);
+
+fn parse_coord(s: &str) -> Result<(usize, usize)> {
+ let (a, b) = s.split_once(",").unwrap();
+ Ok((a.parse()?, b.parse()?))
+}
+
+fn coords_between(a: (usize, usize), b: (usize, usize)) -> Vec<(usize, usize)> {
+ let mut coords = vec![];
+ if a.0 == b.0 {
+ let y_min = a.1.min(b.1);
+ let y_max = a.1.max(b.1);
+ for y in y_min..=y_max {
+ coords.push((a.0, y));
+ }
+ } else if a.1 == b.1 {
+ let x_min = a.0.min(b.0);
+ let x_max = a.0.max(b.0);
+ for x in x_min..=x_max {
+ coords.push((x, a.1));
+ }
+ } else {
+ unreachable!()
+ }
+ coords
+}
+
+fn parse(s: &str) -> Result {
+ let mut map = HashMap::new();
+ let mut max_y = 0;
+ for line in s.lines() {
+ let solids = line.split(" -> ").collect::>();
+ let solids = solids.windows(2);
+ for solid in solids {
+ let a = parse_coord(&solid[0])?;
+ let b = parse_coord(&solid[1])?;
+ for coord in coords_between(a, b) {
+ map.insert(coord, SolidNode::Rock);
+ if coord.1 > max_y {
+ max_y = coord.1;
+ }
+ }
+ }
+ }
+ Ok((map, max_y))
+}
+
+#[aoc(day = 14, parse = parse, test_cases = ["day_14.txt"])]
+fn day_14((map, max_y): Input) -> Result<()> {
+ // Part 1
+ {
+ let mut map = map.clone();
+ println!("{max_y}");
+ let mut fallen = 0;
+ 'outer: loop {
+ let mut sand_pos = (500, 0);
+ 'sand: loop {
+ if sand_pos.1 > max_y {
+ break 'outer;
+ }
+
+ // first, try down
+ {
+ let new_sand_pos = (sand_pos.0, sand_pos.1 + 1);
+ if !map.contains_key(&new_sand_pos) {
+ sand_pos = new_sand_pos;
+ continue 'sand;
+ }
+ }
+ // next, left
+ {
+ let new_sand_pos = (sand_pos.0 - 1, sand_pos.1 + 1);
+ if !map.contains_key(&new_sand_pos) {
+ sand_pos = new_sand_pos;
+ continue 'sand;
+ }
+ }
+
+ // finally, right
+ {
+ let new_sand_pos = (sand_pos.0 + 1, sand_pos.1 + 1);
+ if !map.contains_key(&new_sand_pos) {
+ sand_pos = new_sand_pos;
+ continue 'sand;
+ }
+ }
+
+ // can't move anymore, we've reached the bottom
+ break 'sand;
+ }
+ fallen += 1;
+ map.insert(sand_pos, SolidNode::Sand);
+ }
+
+ println!("Part one: {fallen}");
+ }
+
+ // Part 2
+ {
+ let mut map = map.clone();
+ println!("{max_y}");
+ let mut fallen = 0;
+ loop {
+ let mut sand_pos = (500, 0);
+
+ 'sand: loop {
+ if sand_pos.1 == max_y + 1 {
+ break 'sand;
+ }
+
+ // first, try down
+ {
+ let new_sand_pos = (sand_pos.0, sand_pos.1 + 1);
+ if !map.contains_key(&new_sand_pos) {
+ sand_pos = new_sand_pos;
+ continue 'sand;
+ }
+ }
+ // next, left
+ {
+ let new_sand_pos = (sand_pos.0 - 1, sand_pos.1 + 1);
+ if !map.contains_key(&new_sand_pos) {
+ sand_pos = new_sand_pos;
+ continue 'sand;
+ }
+ }
+
+ // finally, right
+ {
+ let new_sand_pos = (sand_pos.0 + 1, sand_pos.1 + 1);
+ if !map.contains_key(&new_sand_pos) {
+ sand_pos = new_sand_pos;
+ continue 'sand;
+ }
+ }
+
+ // can't move anymore, we've reached the bottom
+ break 'sand;
+ }
+ fallen += 1;
+ map.insert(sand_pos, SolidNode::Sand);
+
+ if map.get(&(500, 0)).is_some() {
+ break;
+ }
+ }
+
+ println!("Part two: {fallen}");
+ }
+
+ Ok(())
+}
diff --git a/test_cases/day_14.txt b/test_cases/day_14.txt
new file mode 100644
index 0000000..1926028
--- /dev/null
+++ b/test_cases/day_14.txt
@@ -0,0 +1,2 @@
+498,4 -> 498,6 -> 496,6
+503,4 -> 502,4 -> 502,9 -> 494,9
\ No newline at end of file