From 7fdf32342a4170b69c250d48b2297641b320c84d Mon Sep 17 00:00:00 2001 From: hal8174 Date: Sat, 17 Feb 2024 02:42:38 +0100 Subject: [PATCH] Rewrote path selection for conflict avoidance. --- Cargo.lock | 324 ++++++++----------------- Cargo.toml | 2 +- examples/solve_belt.rs | 16 +- src/belt_finding/brute_force.rs | 65 ++--- src/belt_finding/common.rs | 85 +++++++ src/belt_finding/conflict_avoidance.rs | 222 ++++++++++------- src/belt_finding/mod.rs | 237 ++++++++++++------ src/misc/map.rs | 2 +- 8 files changed, 514 insertions(+), 439 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 857763d..1603cd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" dependencies = [ "anstyle", "anstyle-parse", @@ -33,36 +33,36 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -71,7 +71,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.19", + "hermit-abi", "libc", "winapi", ] @@ -84,9 +84,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "bitflags" @@ -94,12 +94,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" - [[package]] name = "bumpalo" version = "3.14.0" @@ -124,16 +118,16 @@ version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ - "bitflags 1.3.2", + "bitflags", "textwrap", "unicode-width", ] [[package]] name = "clap" -version = "4.4.8" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" +checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" dependencies = [ "clap_builder", "clap_derive", @@ -141,9 +135,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.8" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" +checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" dependencies = [ "anstream", "anstyle", @@ -153,9 +147,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", @@ -165,9 +159,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "colorchoice" @@ -175,22 +169,11 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" -[[package]] -name = "colored" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" -dependencies = [ - "is-terminal", - "lazy_static", - "windows-sys 0.48.0", -] - [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -233,34 +216,28 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.17" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.18" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "csv" @@ -285,31 +262,21 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "factorio_blueprint" version = "0.1.0" dependencies = [ "base64", - "clap 4.4.8", - "colored", + "clap 4.5.0", "criterion", "flate2", "serde", "serde_json", + "termcolor", ] [[package]] @@ -343,23 +310,6 @@ dependencies = [ "libc", ] -[[package]] -name = "hermit-abi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" - -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi 0.3.3", - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "itertools" version = "0.10.5" @@ -371,15 +321,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] @@ -392,15 +342,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" - -[[package]] -name = "linux-raw-sys" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "log" @@ -416,18 +360,18 @@ checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] @@ -474,27 +418,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] [[package]] name = "rayon" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -502,9 +446,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -512,9 +456,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", @@ -524,9 +468,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", @@ -539,24 +483,11 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" -[[package]] -name = "rustix" -version = "0.38.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" -dependencies = [ - "bitflags 2.4.1", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "same-file" @@ -569,9 +500,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.192" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] @@ -588,9 +519,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", @@ -599,9 +530,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", @@ -610,21 +541,30 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" [[package]] name = "syn" -version = "2.0.39" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -674,9 +614,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -684,9 +624,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", @@ -699,9 +639,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -709,9 +649,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", @@ -722,15 +662,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" dependencies = [ "js-sys", "wasm-bindgen", @@ -767,37 +707,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -806,93 +722,51 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 6e65a76..cc9364c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ harness = false [dependencies] base64 = "0.21.5" clap = { version = "4.4.8", features = ["derive"] } -colored = "2.0.4" flate2 = "1.0.28" serde = { version = "1.0.192", features = ["derive"] } serde_json = "1.0.108" +termcolor = "1.4.1" diff --git a/examples/solve_belt.rs b/examples/solve_belt.rs index 26a53ce..da8aea2 100644 --- a/examples/solve_belt.rs +++ b/examples/solve_belt.rs @@ -15,6 +15,7 @@ enum ProblemCase { Level1, Level2, Level3, + Level5, } impl ProblemCase { @@ -23,6 +24,7 @@ impl ProblemCase { ProblemCase::Level1 => problems::belt_madness_level_1(), ProblemCase::Level2 => problems::belt_madness_level_2(), ProblemCase::Level3 => problems::belt_madness_level_3(), + ProblemCase::Level5 => problems::belt_madness_level_5(), } } } @@ -31,7 +33,7 @@ impl ProblemCase { struct Args { #[arg(value_enum, default_value = "level1")] problem: ProblemCase, - #[arg(value_enum, default_value = "solve")] + #[arg(value_enum, default_value = "conflict-avoidance")] mode: Mode, } @@ -47,6 +49,12 @@ fn main() { println!("{}", p); } Mode::ConflictAvoidance => { + println!("{}", p); + p.find_path(); + println!("{}", p); + p.find_path(); + println!("{}", p); + p.find_path(); println!("{}", p); p.find_path(); println!("{}", p); @@ -57,6 +65,12 @@ fn main() { } } Mode::ConflictStep => { + println!("{}", p); + p.find_path(); + println!("{}", p); + p.find_path(); + println!("{}", p); + p.find_path(); println!("{}", p); p.find_path(); println!("{}", p); diff --git a/src/belt_finding/brute_force.rs b/src/belt_finding/brute_force.rs index b182fd4..26fbbea 100644 --- a/src/belt_finding/brute_force.rs +++ b/src/belt_finding/brute_force.rs @@ -1,15 +1,15 @@ use std::fmt::Display; -use colored::Colorize; +use termcolor::ColorSpec; use crate::misc::Map; use super::{ - common::{Dimension, Direction, PathField, PositionType}, + common::{print_map, Dimension, Direction, PathField, PositionType}, Position, COLORS, }; -#[derive(Default, Clone)] +#[derive(Default, Debug, Clone)] pub struct BruteforceField { pub blocked: bool, underground_vertical: bool, @@ -18,7 +18,7 @@ pub struct BruteforceField { static MAX_UNDERGROUND_LENGTH: u8 = 6; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct BruteforceBuilder { map: Map, path: Vec<[(Position, Direction); 2]>, @@ -49,6 +49,7 @@ impl BruteforceBuilder { } pub fn build(self) -> Bruteforce { + // dbg!(&self); let dimension = Dimension { width: self.map.width, height: self.map.height, @@ -583,26 +584,6 @@ impl Display for Bruteforce { let width_digits = self.map.width.ilog10() + 1; let height_digits = self.map.height.ilog10() + 1; - // print header - for i in 0..width_digits { - let d = width_digits - i - 1; - // padding - for _ in 0..height_digits { - write!(f, " ")?; - } - - for x in 0..self.map.width { - let digits = x / (usize::pow(10, d)); - if digits == 0 && d > 0 { - write!(f, " ")?; - } else { - write!(f, "{}", char::from_u32((digits % 10) as u32 + 48).unwrap())?; - } - } - - writeln!(f)?; - } - let mut m: Map> = Map::new(self.map.width, self.map.height); for (i, problem) in self.problems.iter().enumerate() { @@ -662,27 +643,23 @@ impl Display for Bruteforce { // Print body - for y in 0..self.map.height { - write!(f, "{:1$}", y, height_digits as usize)?; - - for x in 0..self.map.width { - if let Some((i, c)) = m.get(x, y) { - write!(f, "{}", c.color(COLORS[*i]))?; - } else if self.map.get(x, y).blocked { - write!(f, "#")?; - } else if self.map.get(x, y).underground_horizontal { - write!(f, "_")?; - } else if self.map.get(x, y).underground_vertical { - write!(f, "|")?; - } else if x % 8 == 0 || y % 8 == 0 { - write!(f, "∙")?; - } else { - write!(f, " ")?; - } + print_map(self.map.width as i32, self.map.height as i32, |x, y| { + if let Some((i, c)) = m.get(x as usize, y as usize) { + let mut color = ColorSpec::new(); + color.set_fg(Some(COLORS[*i])); + (color, *c) + } else if self.map.get(x as usize, y as usize).blocked { + (ColorSpec::new(), "#") + } else if self.map.get(x as usize, y as usize).underground_horizontal { + (ColorSpec::new(), "_") + } else if self.map.get(x as usize, y as usize).underground_vertical { + (ColorSpec::new(), "|") + } else if x % 8 == 0 || y % 8 == 0 { + (ColorSpec::new(), "∙") + } else { + (ColorSpec::new(), " ") } - - writeln!(f)?; - } + }); Ok(()) } diff --git a/src/belt_finding/common.rs b/src/belt_finding/common.rs index 87ef90f..1c46caf 100644 --- a/src/belt_finding/common.rs +++ b/src/belt_finding/common.rs @@ -1,3 +1,8 @@ +use std::io::Write; + +use base64::write; +use termcolor::{ColorSpec, StandardStream, WriteColor}; + pub type PositionType = i32; #[derive(Clone, Copy, PartialEq, Eq, Debug)] @@ -108,6 +113,16 @@ impl Position { } } +impl std::ops::Sub for Position { + type Output = Position; + + fn sub(mut self, rhs: Self) -> Self::Output { + self.x -= rhs.x; + self.y -= rhs.y; + self + } +} + #[derive(Clone, Debug, Copy)] pub enum PathField { Belt { @@ -167,3 +182,73 @@ impl PathField { } } } + +pub fn print_map(width: i32, height: i32, f: F) +where + F: Fn(i32, i32) -> (ColorSpec, &'static str), +{ + let stdout = &mut StandardStream::stdout(termcolor::ColorChoice::Always); + + let width_digits = width.ilog10() + 1; + let height_digits = height.ilog10() + 1; + + // print header + for i in 0..width_digits { + let d = width_digits - i - 1; + + //padding + for _ in 0..height_digits { + write!(stdout, " "); + } + + for x in 0..width { + let digits = x / (i32::pow(10, d)); + if digits == 0 && d > 0 { + write!(stdout, " "); + } else { + write!( + stdout, + "{}", + char::from_u32((digits % 10) as u32 + 48).unwrap() + ); + } + } + writeln!(stdout); + } + + for y in 0..height { + write!(stdout, "{:1$}", y, height_digits as usize); + + for x in 0..width { + let (c, s) = f(x, y); + stdout.set_color(&c); + write!(stdout, "{:1}", s); + stdout.reset(); + } + + writeln!(stdout, "{:1$}", y, height_digits as usize); + } + + for i in 0..width_digits { + let d = width_digits - i - 1; + + //padding + for _ in 0..height_digits { + write!(stdout, " "); + } + + for x in 0..width { + let digits = x / (i32::pow(10, d)); + if digits == 0 && d > 0 { + write!(stdout, " "); + } else { + write!( + stdout, + "{}", + char::from_u32((digits % 10) as u32 + 48).unwrap() + ); + } + } + writeln!(stdout); + } +} diff --git a/src/belt_finding/conflict_avoidance.rs b/src/belt_finding/conflict_avoidance.rs index 7318195..e054ee1 100644 --- a/src/belt_finding/conflict_avoidance.rs +++ b/src/belt_finding/conflict_avoidance.rs @@ -1,12 +1,15 @@ -use std::{fmt::Display, ops::RangeInclusive}; +use std::{ + fmt::Display, + ops::{RangeBounds, RangeInclusive}, +}; use clap::builder::PathBufValueParser; -use colored::Colorize; +use termcolor::ColorSpec; use crate::{belt_finding::brute_force::BruteforceBuilder, misc::Map}; use super::{ - common::{Dimension, Direction, PathField, Position, PositionType}, + common::{print_map, Dimension, Direction, PathField, Position, PositionType}, Problem, COLORS, }; @@ -18,6 +21,7 @@ struct Field { pub struct ConflictAvoidance { map: Map, belts: Vec>, + range: Option<(RangeInclusive, RangeInclusive)>, } #[derive(Debug, PartialEq, Eq)] @@ -89,7 +93,11 @@ impl ConflictAvoidance { belts.push(p); } - Self { map, belts } + Self { + map, + belts, + range: None, + } } pub fn remove_conflict(&mut self) -> bool { @@ -153,10 +161,12 @@ impl ConflictAvoidance { loop { candidates.sort_by_key(|c| -c.area()); let c = candidates.pop().unwrap(); - let mut xrange = c.min.x as usize..=c.max.x as usize; - let mut yrange = c.min.y as usize..=c.max.y as usize; + let xrange = c.min.x as usize..=c.max.x as usize; + let yrange = c.min.y as usize..=c.max.y as usize; - println!("x: {:?}, y: {:?}", xrange, yrange); + self.range = Some((c.min.x..=c.max.x, c.min.y..=c.max.y)); + + // println!("x: {:?}, y: {:?}", xrange, yrange); let xsize = xrange.end() - xrange.start() + 1; let ysize = yrange.end() - yrange.start() + 1; @@ -180,63 +190,66 @@ impl ConflictAvoidance { } let mut mapping = Vec::new(); + let offset = Position::new(*xrange.start() as i32 - 1, *yrange.start() as i32 - 1); + + dbg!(&xrange, &yrange); for (i, path) in self.belts.iter().enumerate() { - let s = path + // index of first PathField where the next position is in the area + let start_index = path .iter() - .map(|p| p.pos()) - .position(|p| { - xrange.contains(&(p.x as usize)) && yrange.contains(&(p.y as usize)) + .map(|p| { + let (pos, dir) = p.end_pos(); + pos.in_direction(&dir, 1) }) - .map(|i| i.saturating_sub(1)); - let e = path - .iter() - .map(|p| p.pos()) - .rev() - .position(|p| { - xrange.contains(&(p.x as usize)) && yrange.contains(&(p.y as usize)) - }) - .map(|i| usize::min(path.len() - 1, path.len() - i)); + .position(|pos| { + xrange.contains(&(pos.x as usize)) && yrange.contains(&(pos.y as usize)) + }); - if let Some((start, mut end)) = s.zip(e) { - // dbg!(start, end); - if matches!(path[end - 1], PathField::Underground { .. }) { - end -= 1; + // index of last PathField that ends inside the area + let end_index = path + .iter() + .rev() + .map(|p| p.end_pos().0) + .position(|pos| { + xrange.contains(&(pos.x as usize)) && yrange.contains(&(pos.y as usize)) + }) + .map(|rev_i| path.len() - rev_i - 1); + + if let Some((start_index, end_index)) = Option::zip(start_index, end_index) { + // dbg!(start_index, end_index, path[start_index], path[end_index]); + + let (start_pos, start_dir) = path[start_index].end_pos(); + + let (end_pos, end_dir) = path[end_index].end_pos(); + + // edge cases with underground into and end + + if let Some(PathField::Underground { + pos, + dir: _, + len: _, + }) = path.get(end_index + 1) + { + if xrange.contains(&(pos.x as usize)) && yrange.contains(&(pos.y as usize)) + { + let p = *pos - offset; + println!("Blocked {:?}", p); + b.set_blocked(p.x as usize, p.y as usize, true); + } } - mapping.push((i, start, end)); + b.add_path((start_pos - offset, start_dir), (end_pos - offset, end_dir)); - let (start_pos, start_dir) = path[start].end_pos(); - let end_pos = path[end].pos(); - let end_dir = path[end].dir(); - - // dbg!(start_pos, end_pos); - // dbg!(i, path[start], path[end]); - - b.add_path( - ( - Position::new( - start_pos.x - (*xrange.start() as i32 - 1), - start_pos.y - (*yrange.start() as i32 - 1), - ), - start_dir, - ), - ( - Position::new( - end_pos.x - (*xrange.start() as i32 - 1), - end_pos.y - (*yrange.start() as i32 - 1), - ), - *end_dir, - ), - ); + mapping.push((i, start_index, end_index)); } } - println!("{:?}", mapping); + // println!("{:?}", mapping); let mut b = b.build(); - println!("{}", b); + println!("{}", self); let mut min_cost = f64::INFINITY; let mut solutions = Vec::new(); @@ -250,26 +263,38 @@ impl ConflictAvoidance { } } - println!("{}", b.solution_count()); + // dbg!(&solutions); + + // println!("{}", b.solution_count()); if b.solution_count() > 0 { for (p, (index, start, end)) in solutions.iter().zip(mapping) { let mut t = Vec::new(); + // println!("{:?}", p); t.extend_from_slice(&self.belts[index][0..=start]); - t.extend(p[1..].iter().map(|p| { - p.offset(&Position::new( - (*xrange.start() as i32) - 1, - (*yrange.start() as i32) - 1, - )) - })); - t.extend_from_slice(&self.belts[index][end..]); + t.extend(p[1..].iter().map(|p| p.offset(&offset))); + let (end_pos, end_dir) = self.belts[index][end].end_pos(); + t.push(PathField::Belt { + pos: end_pos, + dir: end_dir, + }); + if end + 1 < self.belts[index].len() { + t.extend_from_slice(&self.belts[index][end + 1..]); + } // println!("{:?}", &t); + // println!(); // println!("{:?}", &self.belts[index]); self.belts[index] = t; } + for (i, path) in self.belts.iter().enumerate() { + if path.iter().any(|p| (p.pos().x == 18) && p.pos().y == 18) { + dbg!(i); + } + } + return true; } else { let mut candidate = Candidate::new( @@ -333,29 +358,6 @@ impl ConflictAvoidance { impl Display for ConflictAvoidance { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let width_digits = self.map.width.ilog10() + 1; - let height_digits = self.map.height.ilog10() + 1; - - // print header - for i in 0..width_digits { - let d = width_digits - i - 1; - // padding - for _ in 0..height_digits { - write!(f, " ")?; - } - - for x in 0..self.map.width { - let digits = x / (usize::pow(10, d)); - if digits == 0 && d > 0 { - write!(f, " ")?; - } else { - write!(f, "{}", char::from_u32((digits % 10) as u32 + 48).unwrap())?; - } - } - - writeln!(f)?; - } - let mut m: Map> = Map::new(self.map.width, self.map.height); for (i, problem) in self.belts.iter().enumerate() { @@ -402,25 +404,57 @@ impl Display for ConflictAvoidance { m.set(last_pos.x as usize, last_pos.y as usize, Some((i, "T"))); } + // create conflict map + let mut conflicts: Map = Map::new(self.map.width, self.map.height); + + for x in 0..self.map.width { + for y in 0..self.map.height { + if self.map.get(x, y).blocked { + *conflicts.get_mut(x, y) += 1; + } + } + } + + for path in &self.belts { + for p in path { + match p { + PathField::Belt { pos, dir: _ } => { + *conflicts.get_mut(pos.x as usize, pos.y as usize) += 1 + } + PathField::Underground { pos, dir, len } => { + *conflicts.get_mut(pos.x as usize, pos.y as usize) += 1; + let end = pos.in_direction(dir, *len as PositionType); + *conflicts.get_mut(end.x as usize, end.y as usize) += 1; + } + } + } + } // Print body - for y in 0..self.map.height { - write!(f, "{:1$}", y, height_digits as usize)?; + print_map(self.map.width as i32, self.map.height as i32, |x, y| { + let mut color = ColorSpec::new(); - for x in 0..self.map.width { - if let Some((i, c)) = m.get(x, y) { - write!(f, "{}", c.color(COLORS[*i]))?; - } else if self.map.get(x, y).blocked { - write!(f, "#")?; - } else if x % 8 == 0 || y % 8 == 0 { - write!(f, "∙")?; - } else { - write!(f, " ")?; + if let Some((xrange, yrange)) = &self.range { + if xrange.contains(&x) && yrange.contains(&y) { + color.set_bg(Some(termcolor::Color::Rgb(96, 96, 0))); } } - writeln!(f)?; - } + if conflicts.get(x as usize, y as usize) > &1 { + color.set_bg(Some(termcolor::Color::Black)); + } + + if let Some((i, c)) = m.get(x as usize, y as usize) { + color.set_fg(Some(COLORS[*i])); + (color, c) + } else if self.map.get(x as usize, y as usize).blocked { + (color, "#") + } else if x % 8 == 0 || y % 8 == 0 { + (color, "∙") + } else { + (color, " ") + } + }); Ok(()) } diff --git a/src/belt_finding/mod.rs b/src/belt_finding/mod.rs index d9210b0..fdf2157 100644 --- a/src/belt_finding/mod.rs +++ b/src/belt_finding/mod.rs @@ -1,12 +1,14 @@ +use termcolor::{Color, ColorSpec}; + use crate::belt_finding::{brute_force::BruteforceBuilder, common::Direction}; use crate::graph::wheighted_graph::shortest_path::dijkstra; use crate::graph::wheighted_graph::WheightedGraph; use crate::misc::Map; use crate::priority_queue::BinaryHeap; -use colored::{Color, Colorize}; use std::fmt::Display; +use std::ops::{Deref, Index}; -use self::common::{Position, PositionType}; +use self::common::{print_map, Position, PositionType}; pub mod brute_force; pub mod common; @@ -69,7 +71,11 @@ impl Problem { for (i, path) in self.path.iter().enumerate() { if i != without { for p in path { - self.map.get_mut(p.x as usize, p.y as usize).wheight += 50.0; + let weight = 50.0; + let x = p.x as usize; + let y = p.y as usize; + + self.map.get_mut(x, y).wheight += weight; } } } @@ -84,89 +90,68 @@ impl Problem { } } -static COLORS: [Color; 12] = [ +static COLORS: Cyclic = Cyclic([ Color::Red, Color::Green, Color::Yellow, Color::Blue, Color::Magenta, Color::Cyan, - Color::BrightRed, - Color::BrightGreen, - Color::BrightYellow, - Color::BrightBlue, - Color::BrightMagenta, - Color::Cyan, -]; +]); + +struct Cyclic([T; N]); + +impl Index for Cyclic { + type Output = T; + + fn index(&self, index: usize) -> &Self::Output { + &self.0[index % N] + } +} impl Display for Problem { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let width_digits = self.map.width.ilog10() + 1; - let height_digits = self.map.height.ilog10() + 1; - - // print header - for i in 0..width_digits { - let d = width_digits - i - 1; - // padding - for _ in 0..height_digits { - write!(f, " ")?; - } - - for x in 0..self.map.width { - let digits = x / (usize::pow(10, d)); - if digits == 0 && d > 0 { - write!(f, " ")?; - } else { - write!(f, "{}", char::from_u32((digits % 10) as u32 + 48).unwrap())?; - } - } - - writeln!(f)?; - } - - // Print body - - for y in 0..self.map.height { - write!(f, "{:1$}", y, height_digits as usize)?; - - for x in 0..self.map.width { - if let Some(i) = self - .start - .iter() + print_map(self.map.width as i32, self.map.height as i32, |x, y| { + let mut color = ColorSpec::new(); + if let Some(i) = self + .start + .iter() + .position(|p| p == &Position::new(x as PositionType, y as PositionType)) + { + color.set_fg(Some(COLORS[i])); + (color, "s") + } else if let Some(i) = self + .end + .iter() + .position(|p| p == &Position::new(x as PositionType, y as PositionType)) + { + color.set_fg(Some(COLORS[i])); + (color, "t") + } else if let Some((i, p)) = self.path.iter().enumerate().find_map(|(i, v)| { + v.iter() .position(|p| p == &Position::new(x as PositionType, y as PositionType)) - { - write!(f, "{}", "s".color(COLORS[i]))?; - } else if let Some(i) = self - .end - .iter() - .position(|p| p == &Position::new(x as PositionType, y as PositionType)) - { - write!(f, "{}", "t".color(COLORS[i]))?; - } else if let Some((i, p)) = self.path.iter().enumerate().find_map(|(i, v)| { - v.iter() - .position(|p| p == &Position::new(x as PositionType, y as PositionType)) - .map(|j| (i, j)) - }) { - if self.path[i][p].x < self.path[i][p + 1].x { - write!(f, "{}", "→".color(COLORS[i]))?; - } else if self.path[i][p].x > self.path[i][p + 1].x { - write!(f, "{}", "←".color(COLORS[i]))?; - } else if self.path[i][p].y < self.path[i][p + 1].y { - write!(f, "{}", "↓".color(COLORS[i]))?; - } else if self.path[i][p].y > self.path[i][p + 1].y { - write!(f, "{}", "↑".color(COLORS[i]))?; - } - } else if self.map.get(x, y).blocked { - write!(f, "#")?; - } else if x % 8 == 0 || y % 8 == 0 { - write!(f, "∙")?; + .map(|j| (i, j)) + }) { + color.set_fg(Some(COLORS[i])); + if self.path[i][p].x < self.path[i][p + 1].x { + (color, "→") + } else if self.path[i][p].x > self.path[i][p + 1].x { + (color, "←") + } else if self.path[i][p].y < self.path[i][p + 1].y { + (color, "↓") + } else if self.path[i][p].y > self.path[i][p + 1].y { + (color, "↑") } else { - write!(f, " ")?; + unreachable!() } + } else if self.map.get(x as usize, y as usize).blocked { + (color, "#") + } else if x % 8 == 0 || y % 8 == 0 { + (color, "∙") + } else { + (color, " ") } - - writeln!(f)?; - } + }); Ok(()) } @@ -339,4 +324,110 @@ pub mod problems { p } + + pub fn belt_madness_level_5() -> Problem { + let mut p = Problem::new(31, 29); + + // power stations + p.set_blocked_range(8, 8, 9, 9, true); + p.set_blocked_range(21, 8, 22, 9, true); + p.set_blocked_range(8, 19, 9, 20, true); + p.set_blocked_range(21, 19, 22, 20, true); + + // solar panels + p.set_blocked_range(12, 11, 14, 13, true); + p.set_blocked_range(16, 11, 18, 13, true); + p.set_blocked_range(12, 15, 14, 17, true); + p.set_blocked_range(16, 15, 18, 17, true); + + // Top + p.set_blocked_range(7, 0, 8, 2, true); + p.set_blocked(8, 3, true); + p.set_blocked(9, 4, true); + p.set_blocked_range(10, 5, 20, 5, true); + p.set_blocked(21, 4, true); + p.set_blocked(22, 3, true); + p.set_blocked_range(22, 0, 23, 2, true); + + p.set_blocked_range(2, 1, 2, 2, true); + p.set_blocked_range(4, 1, 4, 2, true); + p.set_blocked_range(1, 4, 2, 4, true); + + p.set_blocked_range(12, 1, 12, 2, true); + p.set_blocked_range(14, 1, 14, 2, true); + p.set_blocked_range(16, 1, 16, 2, true); + p.set_blocked_range(18, 1, 18, 2, true); + + p.set_blocked_range(28, 4, 29, 4, true); + p.set_blocked_range(26, 1, 26, 2, true); + p.set_blocked_range(28, 1, 28, 2, true); + + // Bottom + p.set_blocked_range(7, 26, 8, 28, true); + p.set_blocked(8, 25, true); + p.set_blocked(9, 24, true); + p.set_blocked_range(10, 23, 20, 23, true); + p.set_blocked(21, 24, true); + p.set_blocked(22, 25, true); + p.set_blocked_range(22, 26, 23, 28, true); + + p.set_blocked_range(1, 26, 2, 26, true); + p.set_blocked_range(4, 26, 4, 27, true); + p.set_blocked_range(1, 24, 2, 24, true); + + p.set_blocked_range(12, 26, 12, 27, true); + p.set_blocked_range(14, 26, 14, 27, true); + p.set_blocked_range(16, 26, 16, 27, true); + p.set_blocked_range(18, 26, 18, 27, true); + + p.set_blocked_range(28, 24, 29, 24, true); + p.set_blocked_range(26, 26, 26, 27, true); + p.set_blocked_range(28, 26, 29, 26, true); + + // Left + p.set_blocked_range(0, 7, 2, 8, true); + p.set_blocked(3, 8, true); + p.set_blocked(4, 9, true); + p.set_blocked_range(5, 10, 5, 18, true); + p.set_blocked(4, 19, true); + p.set_blocked(3, 20, true); + p.set_blocked_range(0, 20, 2, 21, true); + + p.set_blocked_range(1, 11, 2, 11, true); + p.set_blocked_range(1, 13, 2, 13, true); + p.set_blocked_range(1, 15, 2, 15, true); + p.set_blocked_range(1, 17, 2, 17, true); + + // Right + p.set_blocked_range(28, 7, 30, 8, true); + p.set_blocked(27, 8, true); + p.set_blocked(26, 9, true); + p.set_blocked_range(25, 10, 25, 18, true); + p.set_blocked(26, 19, true); + p.set_blocked(27, 20, true); + p.set_blocked_range(28, 20, 30, 21, true); + + p.set_blocked_range(28, 11, 29, 11, true); + p.set_blocked_range(28, 13, 29, 13, true); + p.set_blocked_range(28, 15, 29, 15, true); + p.set_blocked_range(28, 17, 29, 17, true); + + // Path + p.add_connection(Position::new(4, 3), Position::new(26, 25)); + p.add_connection(Position::new(12, 3), Position::new(18, 25)); + p.add_connection(Position::new(14, 3), Position::new(3, 26)); + p.add_connection(Position::new(16, 3), Position::new(14, 25)); + p.add_connection(Position::new(3, 4), Position::new(27, 24)); + p.add_connection(Position::new(3, 11), Position::new(27, 17)); + p.add_connection(Position::new(3, 13), Position::new(27, 26)); + p.add_connection(Position::new(3, 15), Position::new(27, 13)); + p.add_connection(Position::new(27, 15), Position::new(2, 3)); + p.add_connection(Position::new(3, 17), Position::new(18, 3)); + p.add_connection(Position::new(3, 24), Position::new(26, 3)); + p.add_connection(Position::new(4, 25), Position::new(27, 4)); + p.add_connection(Position::new(12, 25), Position::new(27, 11)); + p.add_connection(Position::new(16, 25), Position::new(28, 3)); + + p + } } diff --git a/src/misc/map.rs b/src/misc/map.rs index 7506781..27eb011 100644 --- a/src/misc/map.rs +++ b/src/misc/map.rs @@ -1,4 +1,4 @@ -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Map { pub width: usize, pub height: usize,