diff --git a/22/Cargo.lock b/22/Cargo.lock new file mode 100644 index 0000000..385c3c7 --- /dev/null +++ b/22/Cargo.lock @@ -0,0 +1,89 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "day22" +version = "0.1.0" +dependencies = [ + "itertools", + "ndarray", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + +[[package]] +name = "matrixmultiply" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +dependencies = [ + "autocfg", + "rawpointer", +] + +[[package]] +name = "ndarray" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "rawpointer", +] + +[[package]] +name = "num-complex" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" diff --git a/22/Cargo.toml b/22/Cargo.toml new file mode 100644 index 0000000..6ac632a --- /dev/null +++ b/22/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day22" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +itertools = "0.12.0" +ndarray = "0.15.6" diff --git a/22/input b/22/input new file mode 100644 index 0000000..92d2852 --- /dev/null +++ b/22/input @@ -0,0 +1,1300 @@ +2,1,68~2,3,68 +6,9,174~6,9,174 +7,5,106~7,7,106 +0,4,227~0,5,227 +7,0,225~9,0,225 +1,4,66~1,4,67 +9,5,189~9,6,189 +5,0,48~8,0,48 +2,3,92~2,4,92 +2,0,290~4,0,290 +6,6,117~6,8,117 +4,0,288~4,3,288 +3,3,210~3,3,212 +1,0,7~4,0,7 +3,1,111~4,1,111 +0,8,261~3,8,261 +8,1,65~9,1,65 +4,1,174~7,1,174 +0,4,103~0,6,103 +2,0,222~3,0,222 +7,5,130~7,7,130 +7,6,135~7,7,135 +5,1,57~6,1,57 +2,1,204~2,4,204 +5,1,235~5,3,235 +2,4,185~3,4,185 +3,8,36~3,9,36 +6,6,121~6,6,121 +7,3,49~7,5,49 +5,5,80~9,5,80 +5,3,83~5,6,83 +1,1,172~3,1,172 +6,2,277~7,2,277 +7,2,111~7,4,111 +5,6,191~5,9,191 +2,4,157~2,5,157 +1,6,127~3,6,127 +2,2,287~2,4,287 +7,3,279~7,3,282 +4,1,298~4,3,298 +6,1,97~8,1,97 +1,8,112~1,9,112 +5,1,207~7,1,207 +9,4,45~9,6,45 +7,0,289~7,2,289 +9,1,130~9,2,130 +5,2,142~8,2,142 +7,8,88~7,9,88 +6,4,95~6,8,95 +4,6,267~7,6,267 +6,5,243~6,7,243 +4,7,198~4,9,198 +8,6,205~8,8,205 +5,1,185~5,3,185 +6,4,149~6,6,149 +2,7,236~4,7,236 +3,0,180~3,3,180 +0,2,129~2,2,129 +5,5,123~5,5,124 +2,1,135~2,1,137 +3,3,92~5,3,92 +3,3,83~3,5,83 +4,7,17~4,9,17 +5,5,201~5,5,201 +6,5,233~6,5,235 +6,0,81~6,1,81 +8,2,36~8,3,36 +3,4,160~3,6,160 +8,4,233~8,6,233 +0,6,55~0,9,55 +6,8,108~6,8,108 +9,5,280~9,9,280 +8,1,61~8,2,61 +5,9,32~7,9,32 +6,0,82~9,0,82 +0,2,84~0,3,84 +8,6,242~8,9,242 +1,4,64~3,4,64 +7,0,47~7,2,47 +8,0,85~8,2,85 +1,2,197~1,5,197 +6,5,92~6,6,92 +5,0,162~5,3,162 +8,1,245~8,1,247 +1,8,102~4,8,102 +1,7,263~3,7,263 +8,3,35~8,6,35 +0,2,225~0,5,225 +2,0,140~5,0,140 +4,9,192~7,9,192 +2,4,94~2,7,94 +1,7,26~1,7,27 +4,2,75~4,4,75 +0,9,109~2,9,109 +7,5,234~8,5,234 +7,5,79~7,8,79 +5,1,240~7,1,240 +0,1,167~0,4,167 +2,3,183~4,3,183 +9,4,64~9,7,64 +3,8,90~4,8,90 +7,2,268~7,4,268 +6,4,50~7,4,50 +4,6,268~4,9,268 +8,2,136~8,2,136 +2,4,51~4,4,51 +0,0,182~0,1,182 +1,2,215~4,2,215 +3,2,204~3,4,204 +6,4,42~6,6,42 +1,7,271~1,9,271 +3,1,93~3,3,93 +7,8,229~9,8,229 +4,5,51~4,7,51 +8,1,62~8,3,62 +9,4,259~9,7,259 +9,1,117~9,3,117 +4,9,272~6,9,272 +7,7,61~9,7,61 +7,7,277~9,7,277 +0,8,274~3,8,274 +8,2,141~8,3,141 +5,6,175~5,8,175 +0,7,148~1,7,148 +8,1,269~8,3,269 +8,0,88~8,2,88 +6,0,135~8,0,135 +9,3,245~9,6,245 +5,4,159~5,7,159 +0,5,26~2,5,26 +0,8,166~1,8,166 +1,7,249~5,7,249 +0,4,229~2,4,229 +9,7,12~9,9,12 +6,4,273~6,6,273 +5,1,151~5,1,155 +3,6,94~4,6,94 +4,7,245~4,7,245 +8,5,38~8,7,38 +9,4,91~9,6,91 +3,2,159~3,3,159 +5,1,94~6,1,94 +5,3,182~5,4,182 +2,7,125~4,7,125 +5,4,85~5,4,87 +5,2,109~5,5,109 +4,0,1~5,0,1 +5,6,33~7,6,33 +8,5,119~9,5,119 +0,4,241~0,6,241 +6,0,204~6,3,204 +9,1,223~9,2,223 +1,4,215~3,4,215 +2,1,178~4,1,178 +6,5,28~6,8,28 +2,0,154~4,0,154 +0,5,5~0,7,5 +6,9,176~8,9,176 +8,2,114~8,4,114 +3,6,53~4,6,53 +9,6,216~9,6,216 +3,0,12~4,0,12 +1,3,154~1,3,156 +3,2,4~5,2,4 +5,5,105~5,7,105 +9,2,32~9,4,32 +6,2,175~6,3,175 +7,3,100~9,3,100 +2,9,244~4,9,244 +7,1,217~9,1,217 +1,2,121~1,6,121 +5,9,217~7,9,217 +7,4,183~9,4,183 +7,7,117~7,9,117 +3,2,63~4,2,63 +8,4,139~8,6,139 +4,7,11~4,7,11 +2,4,202~4,4,202 +3,7,241~4,7,241 +5,5,120~5,7,120 +0,1,237~1,1,237 +1,0,127~5,0,127 +7,4,292~9,4,292 +1,7,37~1,7,40 +7,0,177~7,2,177 +6,7,171~8,7,171 +1,3,218~1,6,218 +0,7,102~0,9,102 +3,6,249~4,6,249 +8,5,136~8,8,136 +4,2,45~7,2,45 +3,5,165~5,5,165 +7,7,241~8,7,241 +0,4,104~0,6,104 +7,5,51~7,7,51 +2,2,67~4,2,67 +6,1,191~6,3,191 +5,3,228~5,5,228 +4,5,209~4,7,209 +1,6,219~4,6,219 +2,0,171~2,2,171 +6,5,116~8,5,116 +6,1,288~6,3,288 +2,1,218~6,1,218 +7,8,169~9,8,169 +7,8,106~8,8,106 +2,0,250~2,2,250 +2,7,107~2,9,107 +9,8,181~9,9,181 +2,7,151~2,9,151 +3,3,86~5,3,86 +3,4,115~4,4,115 +0,7,146~2,7,146 +9,2,84~9,2,86 +9,3,5~9,4,5 +0,3,194~1,3,194 +1,2,274~1,3,274 +1,5,132~4,5,132 +6,5,294~6,5,297 +6,2,25~8,2,25 +3,7,52~3,9,52 +3,8,35~5,8,35 +1,9,3~1,9,4 +6,6,219~9,6,219 +1,3,118~3,3,118 +7,7,207~7,9,207 +9,7,262~9,8,262 +5,2,79~5,4,79 +2,0,220~2,1,220 +9,1,259~9,2,259 +2,1,128~4,1,128 +7,8,213~7,9,213 +2,6,128~2,6,129 +4,4,106~8,4,106 +0,5,78~3,5,78 +4,4,201~7,4,201 +4,7,62~4,9,62 +5,8,82~5,9,82 +0,5,83~2,5,83 +3,2,225~3,4,225 +7,7,140~8,7,140 +5,2,15~5,4,15 +5,7,161~7,7,161 +8,7,133~8,8,133 +1,1,230~4,1,230 +7,1,8~9,1,8 +1,4,156~3,4,156 +2,1,174~2,1,176 +8,7,257~8,7,259 +0,9,247~2,9,247 +1,3,147~1,3,149 +6,0,206~8,0,206 +6,1,151~8,1,151 +8,6,293~8,7,293 +5,1,211~5,3,211 +1,4,222~4,4,222 +1,5,23~1,7,23 +3,4,47~3,5,47 +1,6,85~1,8,85 +0,0,80~0,2,80 +7,3,215~7,3,218 +0,3,135~0,6,135 +5,7,177~6,7,177 +3,2,221~3,4,221 +9,7,63~9,8,63 +6,7,197~8,7,197 +0,2,277~2,2,277 +2,8,211~4,8,211 +1,7,132~4,7,132 +9,6,178~9,8,178 +5,0,222~5,3,222 +0,1,14~0,3,14 +6,4,256~6,5,256 +2,7,65~5,7,65 +3,3,170~3,4,170 +0,2,233~0,5,233 +4,4,12~7,4,12 +6,5,59~6,5,61 +5,1,237~5,2,237 +4,6,48~4,8,48 +1,5,135~1,5,136 +6,0,47~6,1,47 +1,6,84~3,6,84 +1,5,179~1,7,179 +4,7,138~4,9,138 +2,1,28~5,1,28 +4,1,155~4,2,155 +1,1,64~1,1,66 +4,4,32~6,4,32 +0,5,146~1,5,146 +4,6,71~4,8,71 +9,2,244~9,4,244 +5,2,212~5,3,212 +6,3,156~7,3,156 +9,6,10~9,8,10 +0,5,153~1,5,153 +1,7,102~1,7,104 +8,1,272~9,1,272 +4,7,123~7,7,123 +2,9,29~4,9,29 +0,5,133~3,5,133 +4,1,172~4,4,172 +7,7,90~7,8,90 +6,9,123~8,9,123 +6,2,233~6,2,234 +3,1,30~3,1,31 +1,4,280~1,6,280 +5,0,51~7,0,51 +7,8,83~7,8,85 +9,4,83~9,6,83 +5,5,104~7,5,104 +0,3,17~2,3,17 +3,6,47~3,6,48 +7,0,121~7,2,121 +6,5,11~8,5,11 +1,2,279~1,2,282 +2,6,162~3,6,162 +5,3,254~5,6,254 +5,1,95~6,1,95 +8,1,28~9,1,28 +3,3,120~3,6,120 +7,2,244~8,2,244 +0,3,166~3,3,166 +2,5,190~4,5,190 +9,7,101~9,8,101 +4,7,238~4,9,238 +2,2,260~4,2,260 +0,7,274~2,7,274 +0,1,279~0,4,279 +8,4,123~8,5,123 +9,2,248~9,4,248 +9,4,2~9,4,3 +2,6,115~5,6,115 +2,5,180~4,5,180 +4,5,221~4,7,221 +4,0,168~7,0,168 +4,7,53~7,7,53 +2,2,253~2,4,253 +3,5,163~5,5,163 +5,1,251~5,3,251 +9,7,232~9,7,233 +6,1,258~6,3,258 +9,7,252~9,9,252 +9,3,212~9,6,212 +7,5,94~9,5,94 +7,5,268~8,5,268 +5,3,28~8,3,28 +5,6,233~7,6,233 +0,1,83~0,3,83 +3,0,100~5,0,100 +0,9,99~3,9,99 +9,7,24~9,9,24 +9,3,34~9,3,36 +5,5,300~5,7,300 +0,0,236~0,3,236 +0,5,2~2,5,2 +5,4,237~5,6,237 +8,1,87~8,3,87 +6,6,289~8,6,289 +8,7,256~9,7,256 +1,9,1~3,9,1 +5,5,48~8,5,48 +9,5,42~9,7,42 +6,3,46~6,5,46 +3,3,167~3,5,167 +3,0,132~3,2,132 +4,6,9~4,9,9 +8,5,266~9,5,266 +5,3,62~5,6,62 +2,1,81~2,3,81 +7,4,86~7,6,86 +3,1,84~3,3,84 +5,5,115~7,5,115 +1,6,226~1,7,226 +6,5,187~6,8,187 +9,6,99~9,7,99 +7,2,116~7,3,116 +2,4,5~2,6,5 +2,2,212~2,5,212 +2,1,229~4,1,229 +7,9,143~9,9,143 +5,1,303~6,1,303 +0,0,130~1,0,130 +3,0,162~3,1,162 +5,0,200~5,2,200 +5,6,200~5,8,200 +8,5,64~8,8,64 +7,7,217~7,7,220 +6,7,163~9,7,163 +4,7,274~7,7,274 +2,8,200~3,8,200 +5,6,21~8,6,21 +3,4,163~5,4,163 +3,4,109~3,7,109 +9,8,175~9,8,175 +5,1,119~7,1,119 +2,9,195~4,9,195 +8,3,125~8,3,126 +5,4,198~5,7,198 +0,0,87~3,0,87 +6,4,9~6,5,9 +9,3,68~9,5,68 +5,1,239~5,3,239 +7,3,177~7,6,177 +4,8,20~5,8,20 +4,9,30~7,9,30 +3,4,184~6,4,184 +8,2,222~8,2,224 +0,4,170~0,6,170 +6,4,98~6,4,100 +0,8,270~2,8,270 +5,7,195~5,9,195 +3,9,273~3,9,273 +3,5,255~6,5,255 +4,0,10~5,0,10 +2,1,113~5,1,113 +0,5,269~0,6,269 +7,6,40~9,6,40 +4,4,301~4,7,301 +4,3,155~4,5,155 +4,3,110~4,5,110 +1,3,90~2,3,90 +7,4,87~7,6,87 +7,7,177~9,7,177 +5,0,84~8,0,84 +9,6,214~9,8,214 +4,6,18~5,6,18 +6,2,97~8,2,97 +4,4,22~4,7,22 +2,7,98~2,9,98 +5,8,26~6,8,26 +5,8,81~7,8,81 +6,7,262~6,7,263 +4,0,262~4,3,262 +6,6,245~7,6,245 +5,1,19~5,4,19 +6,0,211~6,2,211 +6,3,203~6,5,203 +1,3,81~1,5,81 +7,8,113~9,8,113 +3,4,7~3,4,8 +3,7,176~4,7,176 +2,9,214~2,9,217 +3,2,141~3,5,141 +7,5,3~7,7,3 +6,3,144~6,6,144 +8,3,121~8,5,121 +5,5,76~8,5,76 +3,2,126~6,2,126 +7,5,148~7,6,148 +2,8,110~4,8,110 +9,3,121~9,5,121 +6,7,241~6,9,241 +9,1,27~9,3,27 +5,5,207~5,5,209 +7,1,211~7,4,211 +9,5,263~9,7,263 +4,1,243~4,3,243 +0,6,80~0,8,80 +0,6,172~0,6,174 +0,2,230~0,5,230 +4,2,157~4,2,159 +5,1,214~5,2,214 +0,3,220~2,3,220 +9,1,219~9,1,221 +0,6,239~2,6,239 +1,8,7~1,8,8 +5,2,232~7,2,232 +0,8,32~1,8,32 +6,1,77~6,3,77 +7,6,56~7,8,56 +5,5,174~5,7,174 +6,7,205~6,9,205 +2,7,201~5,7,201 +5,9,83~5,9,84 +7,5,101~7,7,101 +4,3,173~4,6,173 +0,6,106~0,8,106 +5,2,230~7,2,230 +2,4,136~2,5,136 +2,2,70~2,2,73 +7,5,107~7,7,107 +4,0,200~4,2,200 +8,3,239~8,5,239 +1,8,155~4,8,155 +2,9,65~5,9,65 +3,4,116~4,4,116 +6,2,228~8,2,228 +1,2,20~1,4,20 +5,1,260~8,1,260 +2,6,52~3,6,52 +3,7,106~5,7,106 +0,2,269~0,4,269 +5,9,24~6,9,24 +0,9,208~3,9,208 +8,2,225~8,5,225 +1,7,184~1,9,184 +6,2,9~6,3,9 +0,6,53~0,8,53 +6,1,29~6,3,29 +1,8,139~2,8,139 +8,6,180~8,8,180 +6,3,17~7,3,17 +4,5,230~4,7,230 +6,1,252~6,3,252 +6,2,17~7,2,17 +0,4,150~0,6,150 +5,5,225~5,8,225 +4,4,292~5,4,292 +6,8,168~8,8,168 +4,7,29~6,7,29 +5,4,169~8,4,169 +4,0,224~6,0,224 +1,0,36~3,0,36 +7,8,15~9,8,15 +4,8,202~4,9,202 +9,1,81~9,3,81 +7,1,150~7,3,150 +5,6,212~5,8,212 +1,9,130~3,9,130 +2,1,271~2,1,274 +0,2,144~2,2,144 +3,0,124~3,2,124 +5,6,258~5,7,258 +4,1,71~4,3,71 +3,7,111~5,7,111 +9,4,44~9,7,44 +7,1,288~7,3,288 +5,3,127~5,5,127 +5,3,285~7,3,285 +3,6,293~5,6,293 +5,5,140~7,5,140 +3,2,296~4,2,296 +0,0,92~0,1,92 +3,3,121~3,3,124 +7,1,214~7,4,214 +4,0,88~4,1,88 +4,7,178~4,9,178 +7,8,114~7,9,114 +6,3,289~9,3,289 +0,3,222~0,6,222 +4,1,1~6,1,1 +0,0,148~0,2,148 +3,0,251~3,2,251 +4,8,93~4,9,93 +7,0,126~7,2,126 +0,2,197~0,3,197 +1,2,23~1,2,25 +4,5,168~6,5,168 +2,1,127~3,1,127 +0,6,124~2,6,124 +1,3,66~1,3,69 +6,9,115~8,9,115 +3,2,190~3,2,191 +4,3,124~4,5,124 +4,0,167~4,1,167 +4,3,277~4,6,277 +3,3,287~5,3,287 +6,0,29~8,0,29 +6,1,26~9,1,26 +8,7,5~8,9,5 +2,0,2~2,0,5 +0,3,176~0,5,176 +7,6,199~7,6,201 +8,2,39~8,2,42 +4,0,152~4,2,152 +7,1,129~9,1,129 +7,9,15~9,9,15 +3,1,85~5,1,85 +2,2,242~5,2,242 +2,0,43~4,0,43 +5,3,219~5,4,219 +2,5,236~2,5,237 +6,4,124~7,4,124 +5,8,53~6,8,53 +0,2,147~0,4,147 +6,4,136~7,4,136 +5,6,64~5,6,64 +7,9,256~9,9,256 +5,3,60~8,3,60 +1,8,262~3,8,262 +5,1,208~7,1,208 +3,6,46~5,6,46 +8,1,180~8,4,180 +2,2,185~3,2,185 +6,9,38~6,9,40 +3,1,265~3,3,265 +3,3,125~3,6,125 +2,2,248~5,2,248 +8,0,263~9,0,263 +2,2,255~2,2,256 +1,7,87~1,9,87 +5,1,279~5,1,281 +5,6,194~5,9,194 +0,5,177~3,5,177 +8,1,178~8,2,178 +5,3,261~8,3,261 +9,1,245~9,2,245 +5,1,93~5,3,93 +3,7,251~5,7,251 +4,4,65~6,4,65 +6,7,232~6,9,232 +9,1,5~9,1,5 +2,9,271~4,9,271 +5,0,223~7,0,223 +8,6,132~8,7,132 +5,6,264~5,8,264 +5,3,130~5,3,132 +6,7,70~6,7,72 +7,4,171~7,6,171 +4,2,46~6,2,46 +0,2,280~0,4,280 +3,0,45~3,1,45 +4,8,33~5,8,33 +6,3,151~7,3,151 +5,8,38~5,8,40 +4,5,299~6,5,299 +3,1,1~3,1,3 +1,3,221~2,3,221 +3,1,96~4,1,96 +1,6,181~1,7,181 +5,4,196~5,6,196 +9,0,3~9,0,4 +6,5,91~6,8,91 +4,0,162~4,3,162 +5,2,163~6,2,163 +4,4,306~5,4,306 +5,3,4~5,5,4 +4,7,243~4,9,243 +7,4,102~8,4,102 +7,2,133~7,4,133 +4,7,38~6,7,38 +4,8,32~6,8,32 +1,2,8~1,3,8 +5,8,209~6,8,209 +6,7,237~6,9,237 +3,7,261~6,7,261 +2,4,25~2,6,25 +8,7,107~8,9,107 +2,1,159~5,1,159 +5,4,37~5,7,37 +9,7,250~9,8,250 +5,1,24~5,3,24 +2,7,196~2,9,196 +3,3,205~3,3,207 +3,6,164~4,6,164 +0,0,181~3,0,181 +0,1,129~0,1,132 +5,5,57~8,5,57 +8,5,187~8,6,187 +3,0,129~6,0,129 +3,0,33~3,2,33 +3,2,195~3,4,195 +0,5,138~0,6,138 +6,7,272~8,7,272 +3,2,267~5,2,267 +3,6,68~3,8,68 +1,8,160~3,8,160 +7,3,130~7,4,130 +0,5,234~0,8,234 +1,5,233~4,5,233 +4,5,125~4,6,125 +0,1,88~1,1,88 +8,1,185~8,3,185 +3,1,224~3,4,224 +2,2,6~2,4,6 +2,9,132~3,9,132 +5,0,99~8,0,99 +7,7,252~7,8,252 +8,6,104~8,8,104 +2,9,221~2,9,221 +5,3,178~5,6,178 +1,3,117~3,3,117 +3,2,17~5,2,17 +1,3,2~1,3,5 +1,9,53~3,9,53 +1,2,259~3,2,259 +4,5,303~4,9,303 +5,2,205~5,6,205 +9,9,79~9,9,81 +4,3,203~4,5,203 +0,7,268~0,8,268 +8,5,109~8,7,109 +3,6,86~5,6,86 +3,5,89~3,8,89 +2,6,1~2,6,3 +0,1,123~2,1,123 +4,1,219~4,1,219 +0,4,85~0,5,85 +9,5,247~9,7,247 +1,1,75~1,3,75 +5,8,278~7,8,278 +1,2,64~1,3,64 +6,7,194~6,7,194 +7,0,86~9,0,86 +1,3,72~3,3,72 +8,4,167~8,6,167 +7,8,236~9,8,236 +1,1,207~2,1,207 +8,6,105~8,9,105 +5,5,81~5,6,81 +0,4,11~2,4,11 +8,0,27~8,2,27 +0,7,83~0,7,86 +5,2,112~5,4,112 +1,4,227~1,6,227 +1,2,58~3,2,58 +3,6,222~3,8,222 +1,1,86~3,1,86 +5,3,23~5,6,23 +8,2,176~8,4,176 +8,5,37~8,7,37 +2,2,66~2,5,66 +5,2,32~6,2,32 +0,2,60~3,2,60 +0,9,211~2,9,211 +8,1,24~8,3,24 +4,6,222~6,6,222 +8,4,13~8,6,13 +6,1,256~9,1,256 +6,4,1~6,4,3 +8,1,242~8,3,242 +0,5,144~0,8,144 +8,4,175~8,5,175 +6,7,239~7,7,239 +3,4,255~5,4,255 +4,1,226~4,3,226 +7,1,107~7,2,107 +1,7,99~1,8,99 +4,2,18~4,3,18 +1,1,27~1,3,27 +0,2,173~0,5,173 +3,2,78~4,2,78 +4,3,133~4,6,133 +1,6,208~2,6,208 +6,1,112~7,1,112 +0,8,4~3,8,4 +9,2,6~9,4,6 +3,2,168~4,2,168 +5,6,207~5,7,207 +3,8,257~5,8,257 +4,8,31~6,8,31 +0,4,49~0,5,49 +3,6,193~3,9,193 +3,1,157~3,3,157 +6,3,138~6,5,138 +4,4,205~4,4,205 +5,6,236~8,6,236 +6,3,134~6,5,134 +0,7,254~3,7,254 +0,2,268~3,2,268 +8,5,241~8,5,243 +6,5,106~6,5,109 +2,2,170~4,2,170 +3,9,203~3,9,205 +9,6,68~9,9,68 +4,3,251~4,5,251 +1,5,112~3,5,112 +5,4,125~5,6,125 +6,1,131~7,1,131 +0,6,224~2,6,224 +2,3,209~4,3,209 +1,3,111~3,3,111 +2,7,265~3,7,265 +4,5,108~5,5,108 +0,1,62~2,1,62 +6,7,190~8,7,190 +7,1,104~7,3,104 +5,5,176~7,5,176 +6,8,3~6,9,3 +6,8,234~8,8,234 +6,9,8~6,9,10 +0,8,157~3,8,157 +4,8,254~6,8,254 +7,5,182~7,5,185 +5,8,23~5,9,23 +3,6,73~4,6,73 +6,3,209~6,3,209 +5,0,97~5,1,97 +1,5,242~3,5,242 +5,1,215~5,2,215 +9,5,186~9,7,186 +7,9,21~9,9,21 +3,6,70~3,8,70 +3,4,37~4,4,37 +6,6,129~9,6,129 +3,0,165~5,0,165 +5,9,206~8,9,206 +5,1,297~5,4,297 +2,4,187~2,5,187 +2,9,100~4,9,100 +7,2,215~9,2,215 +5,8,127~7,8,127 +1,6,174~4,6,174 +1,7,134~1,8,134 +1,4,104~1,4,106 +4,7,269~6,7,269 +6,0,14~6,3,14 +1,1,63~1,2,63 +2,4,57~4,4,57 +4,1,147~4,4,147 +5,6,66~6,6,66 +7,3,179~7,5,179 +3,0,83~4,0,83 +7,2,52~8,2,52 +6,1,250~8,1,250 +3,6,232~3,6,233 +6,1,6~7,1,6 +0,1,11~3,1,11 +8,4,251~9,4,251 +2,2,79~2,5,79 +4,8,55~5,8,55 +1,4,122~1,4,122 +4,7,20~6,7,20 +5,4,53~7,4,53 +0,6,102~2,6,102 +4,4,44~7,4,44 +0,1,90~0,2,90 +5,3,101~8,3,101 +4,2,292~4,2,295 +3,5,230~3,7,230 +2,7,260~2,8,260 +5,1,266~5,4,266 +3,4,97~6,4,97 +4,2,143~4,4,143 +1,4,277~1,7,277 +7,2,129~7,4,129 +1,1,126~2,1,126 +6,1,290~6,1,292 +7,2,218~7,2,220 +9,0,89~9,2,89 +9,4,118~9,6,118 +2,1,122~5,1,122 +0,8,113~3,8,113 +7,7,245~9,7,245 +7,4,14~7,6,14 +1,1,240~1,1,240 +5,1,158~5,2,158 +0,2,26~1,2,26 +0,1,124~0,4,124 +0,1,278~0,3,278 +3,7,202~3,7,205 +5,2,165~5,3,165 +0,6,50~3,6,50 +5,1,45~5,1,48 +2,4,257~3,4,257 +6,4,139~6,4,142 +7,3,99~7,5,99 +8,5,208~8,6,208 +1,3,144~4,3,144 +6,0,213~8,0,213 +4,1,255~6,1,255 +0,4,62~3,4,62 +4,2,74~6,2,74 +5,7,218~5,9,218 +1,0,251~2,0,251 +4,5,89~4,7,89 +5,6,40~6,6,40 +7,3,13~7,6,13 +2,4,3~3,4,3 +1,4,70~1,5,70 +2,9,219~2,9,220 +0,7,264~0,9,264 +4,1,149~7,1,149 +2,9,248~4,9,248 +8,7,295~8,7,297 +6,4,253~9,4,253 +1,1,134~3,1,134 +3,2,85~3,4,85 +7,2,2~7,4,2 +9,5,192~9,5,194 +6,3,4~6,6,4 +0,6,8~0,6,10 +4,0,197~6,0,197 +0,3,257~2,3,257 +4,0,181~4,2,181 +9,9,182~9,9,184 +6,6,69~6,6,71 +2,7,207~4,7,207 +7,1,2~9,1,2 +6,4,236~9,4,236 +1,2,103~1,5,103 +6,8,206~8,8,206 +2,4,8~2,5,8 +6,3,205~6,3,208 +1,3,188~3,3,188 +3,5,81~3,7,81 +7,9,121~9,9,121 +1,4,160~1,4,161 +3,8,252~5,8,252 +6,0,194~6,3,194 +2,4,231~4,4,231 +9,5,65~9,7,65 +5,2,218~5,5,218 +3,5,17~5,5,17 +5,4,269~5,6,269 +4,2,216~4,2,218 +6,0,12~6,3,12 +6,6,147~7,6,147 +7,0,88~7,0,91 +6,6,195~6,7,195 +4,8,143~4,9,143 +8,8,66~9,8,66 +6,8,172~8,8,172 +2,7,6~4,7,6 +3,7,83~3,7,85 +2,5,291~6,5,291 +4,9,128~5,9,128 +7,3,237~7,5,237 +1,3,89~5,3,89 +5,2,82~7,2,82 +6,0,123~8,0,123 +8,2,181~9,2,181 +5,8,134~8,8,134 +4,9,26~6,9,26 +7,8,187~8,8,187 +6,1,58~8,1,58 +1,0,89~2,0,89 +0,8,147~2,8,147 +8,3,22~8,6,22 +0,4,48~3,4,48 +2,5,143~3,5,143 +4,0,37~4,2,37 +6,4,120~6,7,120 +4,8,271~7,8,271 +3,4,304~3,6,304 +4,4,72~5,4,72 +6,4,105~7,4,105 +7,0,243~7,2,243 +8,2,172~8,4,172 +7,0,124~9,0,124 +4,7,233~5,7,233 +1,1,77~1,1,79 +4,8,34~6,8,34 +8,8,208~8,9,208 +5,7,126~5,8,126 +0,7,150~0,8,150 +7,7,37~7,7,40 +5,1,3~7,1,3 +2,6,164~2,7,164 +3,0,8~3,2,8 +7,8,211~7,9,211 +8,9,253~9,9,253 +8,6,291~8,8,291 +6,1,78~9,1,78 +5,7,162~5,9,162 +6,3,270~6,5,270 +3,2,218~3,3,218 +7,4,139~7,6,139 +4,4,129~4,5,129 +4,7,69~7,7,69 +4,8,141~4,9,141 +7,7,138~9,7,138 +6,4,127~6,6,127 +8,7,110~8,9,110 +5,8,228~8,8,228 +4,6,118~4,7,118 +9,7,70~9,9,70 +0,8,237~0,9,237 +6,7,168~9,7,168 +2,2,175~5,2,175 +7,7,15~9,7,15 +3,4,5~3,7,5 +6,3,123~8,3,123 +5,1,111~7,1,111 +6,3,6~6,5,6 +1,3,152~4,3,152 +3,4,19~3,6,19 +2,7,165~2,8,165 +0,9,105~2,9,105 +4,7,59~6,7,59 +1,3,190~1,5,190 +3,6,20~3,7,20 +8,5,210~9,5,210 +6,3,55~6,6,55 +8,1,220~8,3,220 +4,9,66~4,9,66 +4,7,203~5,7,203 +1,7,149~2,7,149 +6,7,199~6,8,199 +7,2,46~9,2,46 +5,9,208~6,9,208 +0,3,114~3,3,114 +7,6,132~7,8,132 +3,3,59~6,3,59 +2,3,286~5,3,286 +5,0,26~5,3,26 +9,6,1~9,6,2 +4,5,131~4,8,131 +4,3,94~4,3,97 +3,1,252~3,1,253 +9,3,184~9,7,184 +8,6,120~8,7,120 +0,4,240~0,6,240 +1,1,224~1,3,224 +8,9,3~9,9,3 +7,4,36~7,4,39 +4,5,14~4,7,14 +8,5,65~8,5,66 +4,8,247~5,8,247 +7,0,153~7,3,153 +0,0,127~0,2,127 +1,2,106~4,2,106 +5,1,182~8,1,182 +4,0,39~6,0,39 +4,2,34~4,4,34 +0,4,226~0,5,226 +5,4,275~5,5,275 +7,8,60~7,9,60 +7,1,42~7,4,42 +3,2,56~3,4,56 +5,4,215~7,4,215 +6,4,131~6,6,131 +4,5,127~4,8,127 +1,8,137~1,8,138 +9,7,231~9,8,231 +7,6,198~7,8,198 +3,4,114~5,4,114 +5,2,139~8,2,139 +3,1,242~6,1,242 +0,3,88~0,5,88 +0,7,276~0,9,276 +6,7,191~7,7,191 +0,8,199~2,8,199 +5,8,4~6,8,4 +7,6,204~7,8,204 +0,7,149~0,9,149 +1,7,35~1,9,35 +7,4,71~7,7,71 +7,7,66~8,7,66 +3,5,158~6,5,158 +3,2,182~5,2,182 +2,6,104~2,7,104 +0,4,108~0,6,108 +8,3,264~8,5,264 +4,2,2~4,4,2 +4,1,223~5,1,223 +7,0,117~7,2,117 +6,7,202~8,7,202 +7,8,174~9,8,174 +1,9,131~3,9,131 +6,6,165~6,8,165 +4,7,204~5,7,204 +3,6,256~6,6,256 +1,7,126~2,7,126 +8,0,136~9,0,136 +0,6,181~0,9,181 +4,1,301~5,1,301 +5,5,56~5,7,56 +7,1,278~7,3,278 +2,8,153~4,8,153 +8,7,182~8,8,182 +4,0,263~6,0,263 +0,6,90~0,7,90 +3,0,109~3,3,109 +4,2,70~4,5,70 +5,5,85~5,5,88 +4,0,42~6,0,42 +0,3,61~2,3,61 +2,1,59~2,3,59 +6,7,174~9,7,174 +6,7,7~8,7,7 +8,2,1~8,4,1 +4,0,139~8,0,139 +0,3,228~1,3,228 +5,8,249~7,8,249 +6,4,230~6,7,230 +2,0,84~2,2,84 +9,0,131~9,2,131 +8,5,164~8,7,164 +9,7,254~9,7,254 +3,6,16~4,6,16 +5,9,125~8,9,125 +4,7,173~7,7,173 +2,8,108~2,9,108 +8,4,214~8,5,214 +3,8,196~3,8,197 +0,4,90~0,4,90 +7,6,58~7,9,58 +1,4,159~1,7,159 +0,0,253~2,0,253 +6,6,90~9,6,90 +0,1,151~0,3,151 +0,1,64~0,2,64 +4,4,248~4,7,248 +5,6,288~8,6,288 +4,3,141~4,4,141 +3,2,5~3,2,6 +3,8,190~4,8,190 +9,2,115~9,5,115 +1,6,3~1,6,4 +8,4,49~8,7,49 +3,5,274~6,5,274 +2,8,53~3,8,53 +6,4,111~6,7,111 +7,3,82~7,5,82 +7,7,214~7,9,214 +3,3,49~6,3,49 +0,9,114~2,9,114 +3,3,65~5,3,65 +1,7,96~4,7,96 +6,6,103~8,6,103 +1,8,163~3,8,163 +6,8,185~8,8,185 +7,2,271~7,2,274 +2,4,59~4,4,59 +8,0,261~8,2,261 +5,1,163~8,1,163 +2,1,206~3,1,206 +6,5,83~7,5,83 +7,3,220~7,4,220 +0,8,2~2,8,2 +8,1,231~8,4,231 +6,3,286~6,6,286 +2,0,13~3,0,13 +4,1,267~7,1,267 +0,5,73~2,5,73 +3,6,201~5,6,201 +1,4,178~1,6,178 +6,0,294~6,2,294 +1,6,30~1,8,30 +7,4,35~7,5,35 +0,6,89~0,8,89 +1,2,146~1,2,148 +9,9,76~9,9,77 +3,3,45~3,7,45 +5,3,74~5,5,74 +9,2,30~9,4,30 +3,2,228~3,3,228 +6,1,56~6,3,56 +1,7,229~1,7,231 +2,1,38~4,1,38 +2,7,257~4,7,257 +1,8,101~3,8,101 +7,5,105~9,5,105 +1,6,222~2,6,222 +5,3,179~5,6,179 +2,8,132~4,8,132 +6,1,80~6,4,80 +7,2,72~7,4,72 +7,3,141~7,4,141 +0,5,228~3,5,228 +6,6,5~6,9,5 +7,2,135~9,2,135 +7,1,108~7,2,108 +5,4,295~8,4,295 +0,4,178~0,6,178 +8,6,184~8,8,184 +6,9,33~6,9,35 +4,8,133~4,8,135 +4,0,169~7,0,169 +7,9,118~8,9,118 +6,5,32~8,5,32 +3,6,255~5,6,255 +8,2,213~8,5,213 +8,2,49~9,2,49 +0,5,27~2,5,27 +1,6,236~3,6,236 +5,4,189~8,4,189 +1,1,278~3,1,278 +4,1,161~6,1,161 +2,5,295~2,5,297 +2,4,53~4,4,53 +3,6,204~5,6,204 +1,6,156~1,9,156 +8,9,259~9,9,259 +2,0,182~2,0,185 +3,6,43~5,6,43 +3,2,264~5,2,264 +1,9,202~3,9,202 +3,5,49~3,7,49 +6,4,31~6,6,31 +1,0,186~3,0,186 +7,6,35~7,8,35 +6,2,188~6,5,188 +0,5,22~3,5,22 +6,4,113~6,6,113 +3,8,50~5,8,50 +2,3,121~2,5,121 +2,1,162~2,3,162 +0,3,87~0,5,87 +0,3,259~2,3,259 +1,5,29~1,5,30 +4,5,117~5,5,117 +3,4,234~3,5,234 +4,8,208~7,8,208 +0,3,193~3,3,193 +9,3,130~9,6,130 +4,0,80~4,3,80 +7,9,18~7,9,19 +5,2,203~5,4,203 +3,6,92~5,6,92 +7,2,113~9,2,113 +2,5,11~2,5,12 +6,2,173~9,2,173 +5,6,35~5,7,35 +2,8,244~4,8,244 +2,3,96~2,5,96 +0,5,279~0,7,279 +3,4,187~3,4,188 +6,6,106~6,9,106 +7,6,117~9,6,117 +5,0,101~8,0,101 +3,0,104~5,0,104 +1,5,77~4,5,77 +4,4,121~7,4,121 +8,5,188~9,5,188 +3,6,258~3,7,258 +5,4,290~5,6,290 +2,6,205~4,6,205 +3,2,98~3,4,98 +7,2,96~7,6,96 +7,6,6~8,6,6 +4,6,227~6,6,227 +0,2,143~3,2,143 +1,7,200~1,9,200 +2,2,94~4,2,94 +6,8,236~6,9,236 +9,2,1~9,3,1 +5,1,15~8,1,15 +0,2,79~0,5,79 +2,1,269~5,1,269 +2,8,18~5,8,18 +2,3,256~2,5,256 +6,4,289~8,4,289 +5,1,210~8,1,210 +5,7,280~7,7,280 +9,7,141~9,9,141 +4,5,231~7,5,231 +4,1,291~4,3,291 +6,8,273~8,8,273 +3,9,127~5,9,127 +2,3,3~5,3,3 +1,4,138~4,4,138 +0,1,226~0,3,226 +7,6,1~7,8,1 +7,4,15~7,6,15 +6,8,8~9,8,8 +4,4,104~7,4,104 +5,1,98~5,1,99 +3,2,288~3,4,288 +6,6,62~6,7,62 +6,8,173~6,9,173 +1,2,172~3,2,172 +2,8,276~5,8,276 +8,2,243~8,4,243 +0,3,267~3,3,267 +9,5,279~9,8,279 +2,4,305~2,4,306 +2,9,200~4,9,200 +2,5,294~5,5,294 +6,4,241~9,4,241 +3,8,189~6,8,189 +2,6,86~2,6,89 +5,2,77~5,5,77 +1,7,78~1,8,78 +9,3,131~9,4,131 +6,0,92~8,0,92 +7,4,297~8,4,297 +4,9,11~7,9,11 +3,4,75~3,6,75 +7,0,290~7,2,290 +3,2,188~3,2,188 +4,2,279~4,4,279 +3,3,154~3,4,154 +2,5,23~4,5,23 +1,6,281~1,8,281 +1,9,101~1,9,102 +0,4,267~0,7,267 +0,7,77~2,7,77 +6,2,58~6,2,60 +4,1,44~7,1,44 +4,8,51~4,8,53 +8,5,97~8,7,97 +3,1,165~3,4,165 +0,6,141~1,6,141 +1,5,239~2,5,239 +9,9,72~9,9,73 +1,2,271~2,2,271 +8,3,223~8,5,223 +6,0,114~6,2,114 +1,5,101~1,7,101 +3,4,162~5,4,162 +6,2,291~9,2,291 +2,1,187~2,3,187 +1,5,75~1,7,75 +2,4,303~5,4,303 +0,6,227~0,8,227 +9,3,96~9,7,96 +6,0,134~6,2,134 +2,3,153~2,5,153 +1,9,135~3,9,135 +9,9,186~9,9,187 +5,6,114~8,6,114 +5,4,185~5,4,187 +9,2,217~9,2,220 +2,7,233~3,7,233 +4,1,246~4,2,246 +2,1,277~5,1,277 +5,3,267~8,3,267 diff --git a/22/src/main.rs b/22/src/main.rs new file mode 100644 index 0000000..13385bd --- /dev/null +++ b/22/src/main.rs @@ -0,0 +1,386 @@ +use itertools::Itertools; +use ndarray::prelude::*; +use std::borrow::BorrowMut; +use std::collections::{BinaryHeap, HashMap, VecDeque}; +use std::fmt::{Display, Write}; +use std::fs::File; +use std::io::{BufRead, BufReader, Lines}; +use std::str::FromStr; +use std::time::Instant; + +// BOILERPLATE +type InputIter = Lines>; + +fn get_input() -> InputIter { + let f = File::open("input").unwrap(); + let br = BufReader::new(f); + br.lines() +} + +fn main() { + let start = Instant::now(); + let ans1 = problem1(get_input()); + let duration = start.elapsed(); + println!("Problem 1 solution: {} [{}s]", ans1, duration.as_secs_f64()); + + let start = Instant::now(); + let ans2 = problem2(get_input()); + let duration = start.elapsed(); + println!("Problem 2 solution: {} [{}s]", ans2, duration.as_secs_f64()); +} + +// PARSE + +#[derive(Hash, PartialEq, Eq, Clone, Debug)] +struct Coord { + x: usize, + y: usize, + z: usize, +} + +impl FromStr for Coord { + type Err = Box; + fn from_str(value: &str) -> Result { + let (x, y, z) = value.split(',').next_tuple().unwrap(); + Ok(Self { + x: x.parse()?, + y: y.parse()?, + z: z.parse()?, + }) + } +} + +#[derive(Clone, Hash, PartialEq, Eq)] +struct BrickBlock { + c1: Coord, + c2: Coord, +} + +impl std::fmt::Debug for BrickBlock { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!( + f, + "[{},{},{} - {},{},{}]", + self.c1.x, self.c1.y, self.c1.z, self.c2.x, self.c2.y, self.c2.z + ) + } +} + +impl BrickBlock { + fn map_remove(&self, mut map: BlockMap) -> BlockMap { + // loop over the (inclusive) bounding coordinates and remove them all from the map + map.slice_mut(s![ + std::cmp::min(self.c1.x, self.c2.x)..std::cmp::max(self.c1.x, self.c2.x) + 1, + std::cmp::min(self.c1.y, self.c2.y)..std::cmp::max(self.c1.y, self.c2.y) + 1, + std::cmp::min(self.c1.z, self.c2.z)..std::cmp::max(self.c1.z, self.c2.z) + 1 + ]) + .fill(None); + map + } + fn map_into(&self, mut map: BlockMap) -> BlockMap { + // loop over the (inclusive) bounding coordinates and add them all to the map + map.slice_mut(s![ + std::cmp::min(self.c1.x, self.c2.x)..std::cmp::max(self.c1.x, self.c2.x) + 1, + std::cmp::min(self.c1.y, self.c2.y)..std::cmp::max(self.c1.y, self.c2.y) + 1, + std::cmp::min(self.c1.z, self.c2.z)..std::cmp::max(self.c1.z, self.c2.z) + 1 + ]) + .fill(Some(self.to_owned())); + map + } + fn bottom_z_plane(&self) -> usize { + std::cmp::min(self.c1.z, self.c2.z) + } + fn top_z_plane(&self) -> usize { + std::cmp::max(self.c1.z, self.c2.z) + } + fn bottom_x_plane(&self) -> usize { + std::cmp::min(self.c1.x, self.c2.x) + } + fn top_x_plane(&self) -> usize { + std::cmp::max(self.c1.x, self.c2.x) + } + fn bottom_y_plane(&self) -> usize { + std::cmp::min(self.c1.y, self.c2.y) + } + fn top_y_plane(&self) -> usize { + std::cmp::max(self.c1.y, self.c2.y) + } +} + +impl From<&str> for BrickBlock { + fn from(value: &str) -> Self { + let (c1, c2) = value.split_once('~').unwrap(); + Self { + c1: c1.parse().unwrap(), + c2: c2.parse().unwrap(), + } + } +} + +impl PartialOrd for BrickBlock { + fn partial_cmp(&self, other: &Self) -> Option { + Some(other.bottom_z_plane().cmp(&self.bottom_z_plane())) + } +} + +// Note this is a reversed ordering +impl Ord for BrickBlock { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.bottom_z_plane().cmp(&other.bottom_z_plane()) + } +} + +type BlockMap = Array3; +type MapTile = Option; + +struct BlockPile { + blocks: Vec, + block_map: Array3, + bounds: (usize, usize, usize), +} + +impl BlockPile { + fn remove_block(&mut self, block: &BrickBlock) { + // loop over the (inclusive) bounding coordinates and remove them all from the map + self.block_map + .slice_mut(s![ + std::cmp::min(block.c1.x, block.c2.x)..std::cmp::max(block.c1.x, block.c2.x) + 1, + std::cmp::min(block.c1.y, block.c2.y)..std::cmp::max(block.c1.y, block.c2.y) + 1, + std::cmp::min(block.c1.z, block.c2.z)..std::cmp::max(block.c1.z, block.c2.z) + 1 + ]) + .fill(None); + self.blocks.remove(self.blocks.iter().position(|b| b == block).unwrap()); + } + fn add_block(&mut self, block: &BrickBlock) { + // loop over the (inclusive) bounding coordinates and remove them all from the map + self.block_map + .slice_mut(s![ + std::cmp::min(block.c1.x, block.c2.x)..std::cmp::max(block.c1.x, block.c2.x) + 1, + std::cmp::min(block.c1.y, block.c2.y)..std::cmp::max(block.c1.y, block.c2.y) + 1, + std::cmp::min(block.c1.z, block.c2.z)..std::cmp::max(block.c1.z, block.c2.z) + 1 + ]) + .fill(Some(block.to_owned())); + self.blocks.push(block.clone()); + } + fn blocks_directly_above(&self, block: &BrickBlock) -> Vec { + // find the top plane of the block + // get the array range of all squares at z_plane + 1 within the bounds of x & y + // i think there is a built in way in ndarray to do this... + let directly_above = self.block_map.slice(s![ + block.bottom_x_plane()..block.top_x_plane() + 1, + block.bottom_y_plane()..block.top_y_plane() + 1, + block.top_z_plane() + 1..std::cmp::min(block.top_z_plane() + 2, self.bounds.2) + ]); + + directly_above.iter().filter_map(|v| v.clone()).dedup().collect() + } + fn supported_by(&self, block: &BrickBlock) -> usize { + println!("{:?} is supported by:", block); + let z_plane = std::cmp::min(block.c1.z, block.c2.z); + println!(" z plane: {}", z_plane); + // get the slice of tiles below us + let directly_below = self.block_map.slice(s![ + block.bottom_x_plane()..block.top_x_plane() + 1, + block.bottom_y_plane()..block.top_y_plane() + 1, + z_plane - 1..z_plane // don't include our own plane + ]); + println!( + " {} directly below {:?}", + directly_below.iter().filter_map(|v| v.clone()).dedup().count(), + block + ); + directly_below.iter().filter_map(|v| v.clone()).dedup().count() + } + fn blocks_above_will_move_if_we_are_gone(&mut self, block: &BrickBlock) -> bool { + println!("checking directly above block {:?}", block); + self.blocks_directly_above(&block) + .iter() + .map(|b| self.supported_by(b)) + .any(|b| b == 1) // 0 can happen at the origin, and an empty iterator (falsy) will happen at the top + } + /// Find the plane of the first block directly below us + fn supporting_plane(&self, block: &BrickBlock) -> Option { + // find the bottom plane of ourselves + let z_plane = std::cmp::min(block.c1.z, block.c2.z); + // get the slice of tiles below us + let directly_below = self.block_map.slice(s![ + block.bottom_x_plane()..block.top_x_plane() + 1, + block.bottom_y_plane()..block.top_y_plane() + 1, + 1..z_plane // don't include our own plane + ]); + // find the highest z value + let block_below = directly_below + .indexed_iter() + .filter_map(|(idx, v)| if let Some(val) = v { Some((idx, val)) } else { None }) + .max_by(|(_, a), (_, b)| a.top_z_plane().cmp(&b.top_z_plane())); + + if let Some(block) = block_below { + Some(block.1.top_z_plane()) + } else { + None + } + } + + fn drop_blocks(&mut self) { + let mut blocks_to_move = BinaryHeap::from(self.blocks.clone()); + while let Some(mut block) = blocks_to_move.pop() { + match self.supporting_plane(&block) { + Some(z) if z + 1 != block.bottom_z_plane() => { + // we can move down to this position + // set old position to None + self.remove_block(&block); + // set new positions + let z_height = block.c1.z.abs_diff(block.c2.z); + block.c1.z = z + 1; + block.c2.z = z + 1 + z_height; + self.add_block(&block); + // queue the block again + blocks_to_move.push(block); + } + None if block.bottom_z_plane() != 1 => { + // we can move down to this position + // set old position to None + let z = 1; + self.remove_block(&block); + // set new positions + let z_height = block.c1.z.abs_diff(block.c2.z); + block.c1.z = z; + block.c2.z = z + z_height; + self.add_block(&block); + // queue the block again + blocks_to_move.push(block); + } + _ => { + continue; + } // we are in position already with nothing below us + } + } + } + fn can_move(&self, block: &BrickBlock) -> bool { + match self.supporting_plane(&block) { + Some(z) if z + 1 != block.bottom_z_plane() => { + return true; + } + None if block.bottom_z_plane() != 1 => { + return true; + } + _ => { + return false; + } // we are in position already with nothing below us + } + } +} + +impl From> for BlockPile { + fn from(lines: Lines) -> Self { + let mut new: BlockPile = Self { + blocks: lines.map(|line| BrickBlock::from(line.unwrap().as_str())).collect(), + block_map: Array3::from_elem([0, 0, 0], None), + bounds: (0, 0, 0), + }; + + for block in &new.blocks { + new.bounds.0 = std::cmp::max(block.c1.x + 1, std::cmp::max(block.c2.y + 1, new.bounds.0)); + new.bounds.1 = std::cmp::max(block.c1.y + 1, std::cmp::max(block.c2.y + 1, new.bounds.1)); + new.bounds.2 = std::cmp::max(block.c1.z + 1, std::cmp::max(block.c2.z + 1, new.bounds.2)); + } + let mut block_map = BlockMap::from_elem(new.bounds, None); + + for block in &new.blocks { + block_map = block.map_into(block_map); + } + new.block_map = block_map; + + new + } +} + +impl Display for BlockPile { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // XZ view + writeln!(f, "XZ: [{}, {}]", self.bounds.0, self.bounds.2)?; + for z in (0..self.bounds.2).rev() { + for x in 0..self.bounds.0 { + let y = self.block_map.slice(s![x..x + 1, .., z..z + 1]); + f.write_char(match y.iter().filter(|v| v.is_some()).count() { + 0 => '.', + 1 => '#', + _ => '?', + })?; + } + writeln!(f, " {}", z)?; + } + // YZ view + writeln!(f)?; + writeln!(f, "YZ: [{}, {}]", self.bounds.1, self.bounds.2)?; + for z in (0..self.bounds.2).rev() { + for y in 0..self.bounds.1 { + let x = self.block_map.slice(s![.., y..y + 1, z..z + 1]); + f.write_char(match x.iter().filter(|v| v.is_some()).count() { + 0 => '.', + 1 => '#', + _ => '?', + })?; + } + writeln!(f, " {}", z)?; + } + Ok(()) + } +} + +// PROBLEM 1 solution + +fn problem1(input: Lines) -> u64 { + let mut pile = BlockPile::from(input); + println!("{}", pile); + println!("dropping blocks!"); + pile.drop_blocks(); + println!("{}", pile); + + let blocks = pile.blocks.clone(); + let mut must_keep: Vec<_> = blocks + .iter() + .filter(|b| pile.blocks_above_will_move_if_we_are_gone(*b)) + .collect(); + let mut removable: Vec<_> = blocks + .iter() + .filter(|b| !pile.blocks_above_will_move_if_we_are_gone(*b)) + .collect(); + removable.sort_by(|a, b| a.bottom_z_plane().cmp(&b.bottom_z_plane())); + must_keep.sort_by(|a, b| a.bottom_z_plane().cmp(&b.bottom_z_plane())); + + println!("remove: {:?}", removable); + + removable.len() as u64 +} + +// PROBLEM 2 solution +fn problem2(input: Lines) -> u64 { + 0 +} + +#[cfg(test)] +mod tests { + use crate::*; + use std::io::Cursor; + + const EXAMPLE: &str = &"1,0,1~1,2,1 +0,0,2~2,0,2 +0,2,3~2,2,3 +0,0,4~0,2,4 +2,0,5~2,2,5 +0,1,6~2,1,6 +1,1,8~1,1,9"; + + #[test] + fn problem1_example() { + let c = Cursor::new(EXAMPLE); + assert_eq!(problem1(c.lines()), 5); + } + + #[test] + fn problem2_example() { + let c = Cursor::new(EXAMPLE); + assert_eq!(problem2(c.lines()), 0); + } +}