Merge branch 'master' into multi-thread
This commit is contained in:
commit
044099379d
5 changed files with 1149 additions and 101 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,5 +1,4 @@
|
|||
/target
|
||||
/.idea
|
||||
*.iml
|
||||
Cargo.lock
|
||||
*.pdf
|
||||
|
|
969
Cargo.lock
generated
Normal file
969
Cargo.lock
generated
Normal file
|
@ -0,0 +1,969 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
|
||||
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "argparse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f8ebf5827e4ac4fd5946560e6a99776ea73b596d80898f357007317a7141e47"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "base-x"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b20b618342cf9891c292c4f5ac2cde7287cc5c87e87e9c769d617793607dec1"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41aa2ec95ca3b5c54cf73c91acf06d24f4495d5f1b1c12506ae3483d646177ac"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
|
||||
|
||||
[[package]]
|
||||
name = "const_fn"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce90df4c658c62f12d78f7508cf92f9173e5184a539c10bfe54a3107b3ffd0f2"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"maybe-uninit",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"csv-core",
|
||||
"itoa 0.4.6",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deflate"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "discard"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "encoding"
|
||||
version = "0.2.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec"
|
||||
dependencies = [
|
||||
"encoding-index-japanese",
|
||||
"encoding-index-korean",
|
||||
"encoding-index-simpchinese",
|
||||
"encoding-index-singlebyte",
|
||||
"encoding-index-tradchinese",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-japanese"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91"
|
||||
dependencies = [
|
||||
"encoding_index_tests",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-korean"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81"
|
||||
dependencies = [
|
||||
"encoding_index_tests",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-simpchinese"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7"
|
||||
dependencies = [
|
||||
"encoding_index_tests",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-singlebyte"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a"
|
||||
dependencies = [
|
||||
"encoding_index_tests",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-tradchinese"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18"
|
||||
dependencies = [
|
||||
"encoding_index_tests",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_index_tests"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "766d0e77a2c1502169d4a93ff3b8c15a71fd946cd0126309752104e5f3c46d94"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz_oxide 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af"
|
||||
dependencies = [
|
||||
"color_quant",
|
||||
"lzw",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.23.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "974e194911d1f7efe3cd8a8f9db3b767e43536327e899e8bc9a12ef5711b74d2"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"gif",
|
||||
"jpeg-decoder",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"png",
|
||||
"tiff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
|
||||
|
||||
[[package]]
|
||||
name = "jpeg-decoder"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc797adac5f083b8ff0ca6f6294a999393d76e197c36488e2ef732c4715f6fa3"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lopdf"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c431c050a4b89f90beb395b0bab726d609aab84d3b93b01b366bcec60412aea2"
|
||||
dependencies = [
|
||||
"dtoa",
|
||||
"encoding",
|
||||
"flate2",
|
||||
"itoa 0.3.4",
|
||||
"linked-hash-map",
|
||||
"log",
|
||||
"lzw",
|
||||
"pom",
|
||||
"rayon",
|
||||
"time 0.1.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lzw"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
|
||||
|
||||
[[package]]
|
||||
name = "maybe-uninit"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3741934be594d77de1c8461ebcbbe866f585ea616a9753aa78f2bdc69f0e4579"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.16.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfe7f9f1c730833200b134370e1d5098964231af8450bce9b78ee3ab5278b970"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"deflate",
|
||||
"miniz_oxide 0.3.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pom"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e2192780e9f8e282049ff9bffcaa28171e1cb0844f49ed5374e518ae6024ec"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20"
|
||||
|
||||
[[package]]
|
||||
name = "printpdf"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5291e5e1d48b8e90d61efd22710ccab2f751ca2b0c94b2a47d2f2a688b11473f"
|
||||
dependencies = [
|
||||
"image",
|
||||
"lopdf",
|
||||
"rusttype",
|
||||
"time 0.2.21",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
"rand_pcg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfd016f0c045ad38b5251be2c9c0ab806917f82da4d36b2a327e5166adad9270"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8c4fec834fb6e6d2dd5eece3c7b432a52f0ba887cf40e595190c4107edc08bf"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusttype"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f61411055101f7b60ecf1041d87fb74205fb20b0c7a723f07ef39174cf6b4c0"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"ordered-float",
|
||||
"stb_truetype",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
|
||||
dependencies = [
|
||||
"itoa 0.4.6",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
|
||||
|
||||
[[package]]
|
||||
name = "standback"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33a71ea1ea5f8747d1af1979bfb7e65c3a025a70609f04ceb78425bc5adad8e6"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stb_truetype"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
|
||||
dependencies = [
|
||||
"discard",
|
||||
"rustc_version",
|
||||
"stdweb-derive",
|
||||
"stdweb-internal-macros",
|
||||
"stdweb-internal-runtime",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb-derive"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb-internal-macros"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
|
||||
dependencies = [
|
||||
"base-x",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"sha1",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb-internal-runtime"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
|
||||
|
||||
[[package]]
|
||||
name = "sudoku_solver"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"argparse",
|
||||
"csv",
|
||||
"printpdf",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiff"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f3b8a87c4da944c3f27e5943289171ac71a6150a79ff6bacfff06d159dfff2f"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"lzw",
|
||||
"miniz_oxide 0.3.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c2e31fb28e2a9f01f5ed6901b066c1ba2333c04b64dc61254142bafcb3feb2c"
|
||||
dependencies = [
|
||||
"const_fn",
|
||||
"libc",
|
||||
"standback",
|
||||
"stdweb",
|
||||
"time-macros",
|
||||
"version_check",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ae9b6e9f095bc105e183e3cd493d72579be3181ad4004fceb01adbe9eecab2d"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"time-macros-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-macros-impl"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"standback",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
@ -1,4 +1,4 @@
|
|||
use crate::grid::{Cell, Grid, CellValue, Line};
|
||||
use crate::grid::{Cell, Grid, CellValue, Section};
|
||||
use crate::solver::{SolveStatus, SolveController, Uniqueness, evaluate_grid_with_solve_controller, SolveStatistics};
|
||||
use std::rc::Rc;
|
||||
use rand::prelude::*;
|
||||
|
@ -60,7 +60,7 @@ impl Cell {
|
|||
fn calculate_possibilities(&self) -> Vec<u8> {
|
||||
// Need to calculate possibilities for this cell
|
||||
let mut possibilities = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
fn eliminate_possibilities(possibilities: &mut Vec<u8>, line: &Line, cell: &Cell){
|
||||
fn eliminate_possibilities(possibilities: &mut Vec<u8>, line: &Section, cell: &Cell){
|
||||
for (_index, other) in line.vec.iter().enumerate(){
|
||||
if other.x != cell.x || other.y != cell.y {
|
||||
let value = &*other.value.borrow();
|
||||
|
@ -88,7 +88,7 @@ impl Cell {
|
|||
}
|
||||
}
|
||||
|
||||
impl Line {
|
||||
impl Section {
|
||||
fn recalculate_and_set_possibilities(&self) {
|
||||
for (_index, cell) in self.vec.iter().enumerate() {
|
||||
let cell = &**cell;
|
||||
|
|
141
src/grid.rs
141
src/grid.rs
|
@ -10,16 +10,38 @@ pub enum CellValue {
|
|||
Unknown(Vec<u8>)
|
||||
}
|
||||
|
||||
/// A representation of a single cell in a Sudoku grid. Don't make this directly; make a Grid.
|
||||
pub struct Cell {
|
||||
pub x: usize,
|
||||
pub y: usize,
|
||||
pub value: RefCell<CellValue>,
|
||||
pub row: Weak<RefCell<Line>>,
|
||||
pub column: Weak<RefCell<Line>>,
|
||||
pub section: Weak<RefCell<Line>>,
|
||||
pub row: Weak<RefCell<Section>>,
|
||||
pub column: Weak<RefCell<Section>>,
|
||||
pub section: Weak<RefCell<Section>>,
|
||||
}
|
||||
|
||||
impl Cell {
|
||||
/// Set the `Cell`'s value to be a fixed digit. This method also removes the digit from any
|
||||
/// affected cells in the same row, column, or square.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use sudoku_solver::grid::{Grid, CellValue};
|
||||
/// let grid = Grid::new();
|
||||
///
|
||||
/// let cell1 = grid.get(0,0).unwrap();
|
||||
/// let cell2 = grid.get(0,1).unwrap();
|
||||
///
|
||||
/// assert_eq!(cell1.get_value_copy(), CellValue::Unknown(vec![1,2,3,4,5,6,7,8,9]));
|
||||
/// assert_eq!(cell2.get_value_copy(), CellValue::Unknown(vec![1,2,3,4,5,6,7,8,9]));
|
||||
///
|
||||
/// cell1.set(1);
|
||||
///
|
||||
/// assert_eq!(cell1.get_value_copy(), CellValue::Fixed(1));
|
||||
/// assert_eq!(cell2.get_value_copy(), CellValue::Unknown(vec![2,3,4,5,6,7,8,9]));
|
||||
///
|
||||
/// ```
|
||||
pub fn set(&self, digit: u8){
|
||||
unsafe {
|
||||
if DEBUG {
|
||||
|
@ -46,11 +68,14 @@ impl Cell {
|
|||
Cell::process_possibilities(section, digit);
|
||||
}
|
||||
|
||||
/// Get a copy of the `CellValue`
|
||||
pub fn get_value_copy(&self) -> CellValue {
|
||||
let value = &*self.value.borrow();
|
||||
return value.clone();
|
||||
}
|
||||
|
||||
/// Set the cell value with a provided `CellValue`; if `value` is Fixed then the related cell's
|
||||
/// possibilities are adjusted like in `set`.
|
||||
pub fn set_value(&self, value: CellValue){
|
||||
match value {
|
||||
CellValue::Fixed(digit) => {
|
||||
|
@ -63,6 +88,26 @@ impl Cell {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set the `Cell`'s value to be a value **without** adjusting any of the nearby cells.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use sudoku_solver::grid::{Grid, CellValue};
|
||||
/// let grid = Grid::new();
|
||||
///
|
||||
/// let cell1 = grid.get(0,0).unwrap();
|
||||
/// let cell2 = grid.get(0,1).unwrap();
|
||||
///
|
||||
/// assert_eq!(cell1.get_value_copy(), CellValue::Unknown(vec![1,2,3,4,5,6,7,8,9]));
|
||||
/// assert_eq!(cell2.get_value_copy(), CellValue::Unknown(vec![1,2,3,4,5,6,7,8,9]));
|
||||
///
|
||||
/// cell1.set_value_exact(CellValue::Fixed(1));
|
||||
///
|
||||
/// assert_eq!(cell1.get_value_copy(), CellValue::Fixed(1));
|
||||
/// assert_eq!(cell2.get_value_copy(), CellValue::Unknown(vec![1,2,3,4,5,6,7,8,9])); // still contains 1
|
||||
///
|
||||
/// ```
|
||||
pub fn set_value_exact(&self, value: CellValue){
|
||||
unsafe {
|
||||
if DEBUG {
|
||||
|
@ -74,6 +119,7 @@ impl Cell {
|
|||
self.mark_updates();
|
||||
}
|
||||
|
||||
/// Return a copy of the cell's possibilities if it has them.
|
||||
pub fn get_value_possibilities(&self) -> Option<Vec<u8>> {
|
||||
let value = &*self.value.borrow();
|
||||
match value {
|
||||
|
@ -82,6 +128,8 @@ impl Cell {
|
|||
}
|
||||
}
|
||||
|
||||
// Internal function - mark all the Sections the cell belongs to as having had a change
|
||||
// so that the solver will look at it later
|
||||
fn mark_updates(&self){
|
||||
{
|
||||
let row = &*self.row.upgrade().unwrap();
|
||||
|
@ -100,7 +148,8 @@ impl Cell {
|
|||
}
|
||||
}
|
||||
|
||||
fn process_possibilities(line: &Line, digit: u8){
|
||||
// Go through and remove digit from the Section's Cells' possibilities
|
||||
fn process_possibilities(line: &Section, digit: u8){
|
||||
for (_index, cell) in line.vec.iter().enumerate() {
|
||||
let cell = &**cell;
|
||||
|
||||
|
@ -143,38 +192,44 @@ impl Cell {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Line {
|
||||
/// A representation of either a Row, Column, or Square in a Sudoku grid. Don't make this directly; make a Grid.
|
||||
pub struct Section {
|
||||
/// A vector of `Rc`s of the `Cell`s inside this Section. We use `Rc` because one of the
|
||||
/// Sections needs to have ownership of the Cells but then the others have to have a different
|
||||
/// signature.
|
||||
pub vec: Vec<Rc<Cell>>,
|
||||
pub do_update: RefCell<bool>,
|
||||
pub index: usize,
|
||||
pub line_type: LineType
|
||||
pub section_type: SectionType
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum LineType {
|
||||
pub enum SectionType {
|
||||
Row,
|
||||
Column,
|
||||
Section
|
||||
Square
|
||||
}
|
||||
|
||||
impl Line {
|
||||
impl Section {
|
||||
fn push(&mut self, x: Rc<Cell>){
|
||||
self.vec.push(x);
|
||||
}
|
||||
|
||||
/// Short-hand for accessing `vec` and calling it's `get` method.
|
||||
pub fn get(&self, index: usize) -> Option<&Rc<Cell>>{
|
||||
self.vec.get(index)
|
||||
}
|
||||
|
||||
fn new(index: usize, line_type: LineType) -> Line {
|
||||
Line {
|
||||
fn new(index: usize, line_type: SectionType) -> Section {
|
||||
Section {
|
||||
vec: Vec::new(),
|
||||
do_update: RefCell::new(false),
|
||||
index,
|
||||
line_type
|
||||
section_type: line_type
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a copy of whether this `Section` has been marked for the solver to work on it or not.
|
||||
pub fn do_update(&self) -> bool {
|
||||
let do_update = &self.do_update.borrow();
|
||||
let do_update = &**do_update;
|
||||
|
@ -185,23 +240,25 @@ impl Line {
|
|||
|
||||
type MultiMut<T> = Rc<RefCell<T>>;
|
||||
|
||||
/// A representation of a Sudoku grid.
|
||||
pub struct Grid {
|
||||
pub rows: Vec<MultiMut<Line>>, // Read from top to bottom
|
||||
pub columns: Vec<MultiMut<Line>>,
|
||||
pub sections: Vec<MultiMut<Line>>,
|
||||
pub rows: Vec<MultiMut<Section>>, // Read from top to bottom
|
||||
pub columns: Vec<MultiMut<Section>>,
|
||||
pub sections: Vec<MultiMut<Section>>,
|
||||
}
|
||||
|
||||
impl Grid {
|
||||
/// Generate a new empty `Grid` with full empty possibilities for each `Cell`
|
||||
pub fn new() -> Grid {
|
||||
|
||||
let mut rows: Vec<MultiMut<Line>> = Vec::new();
|
||||
let mut columns: Vec<MultiMut<Line>> = Vec::new();
|
||||
let mut sections: Vec<MultiMut<Line>> = Vec::new();
|
||||
let mut rows: Vec<MultiMut<Section>> = Vec::new();
|
||||
let mut columns: Vec<MultiMut<Section>> = Vec::new();
|
||||
let mut sections: Vec<MultiMut<Section>> = Vec::new();
|
||||
|
||||
for i in 0..9 {
|
||||
rows.push(Rc::new(RefCell::new(Line::new(i, LineType::Row))));
|
||||
columns.push(Rc::new(RefCell::new(Line::new(i, LineType::Column))));
|
||||
sections.push(Rc::new(RefCell::new(Line::new(i, LineType::Section))));
|
||||
rows.push(Rc::new(RefCell::new(Section::new(i, SectionType::Row))));
|
||||
columns.push(Rc::new(RefCell::new(Section::new(i, SectionType::Column))));
|
||||
sections.push(Rc::new(RefCell::new(Section::new(i, SectionType::Square))));
|
||||
}
|
||||
|
||||
for row_index in 0..9 {
|
||||
|
@ -248,24 +305,26 @@ impl Grid {
|
|||
return Grid { rows, columns, sections };
|
||||
}
|
||||
|
||||
pub fn get(&self, r: usize, c: usize) -> Result<Rc<Cell>, &str> {
|
||||
if (r > 9) | (c > 9) {
|
||||
return Err("Row or column indices are out of bounds");
|
||||
}
|
||||
/// Returns the `Cell` (in an `Rc`) at the specified coordinates.
|
||||
/// * `r` is the row coordinate (first row starting at 0)
|
||||
/// * `c` is the column coordinate (first column starting at 0)
|
||||
///
|
||||
/// Returns None if the coordinates are out of bounds.
|
||||
pub fn get(&self, r: usize, c: usize) -> Option<Rc<Cell>> {
|
||||
|
||||
let row = match self.rows.get(r) {
|
||||
Some(x) => x,
|
||||
None => {return Err("Row index is out of bounds")}
|
||||
None => return None
|
||||
};
|
||||
|
||||
let row = &*(&**row).borrow();
|
||||
|
||||
let cell = match row.get(c) {
|
||||
Some(x) => x,
|
||||
None => {return Err("Column index is out of bounds")}
|
||||
None => return None
|
||||
};
|
||||
|
||||
return Ok(Rc::clone(cell));
|
||||
return Some(Rc::clone(cell));
|
||||
}
|
||||
|
||||
fn process_unknown(x: &Vec<u8>, digit: u8, row: &mut String){
|
||||
|
@ -275,6 +334,32 @@ impl Grid {
|
|||
row.push(' ');
|
||||
}
|
||||
}
|
||||
|
||||
/// Find the smallest empty `Cell` in terms of possibilities; returns `None` if all Cells have
|
||||
/// `Fixed` `CellValue`s.
|
||||
pub fn find_smallest_cell(&self) -> Option<Rc<Cell>>{
|
||||
let mut smallest_cell : Option<Rc<Cell>> = None;
|
||||
let mut smallest_size = usize::MAX;
|
||||
|
||||
for x in 0..9 {
|
||||
for y in 0..9 {
|
||||
let cell_rc = self.get(x, y).unwrap();
|
||||
let cell = &*self.get(x, y).unwrap();
|
||||
let cell_value = &*cell.value.borrow();
|
||||
|
||||
match cell_value {
|
||||
CellValue::Unknown(possibilities) => {
|
||||
if (possibilities.len() < smallest_size) && (possibilities.len() > 0){
|
||||
smallest_size = possibilities.len();
|
||||
smallest_cell = Some(cell_rc);
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
smallest_cell
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Grid {
|
||||
|
|
131
src/solver.rs
131
src/solver.rs
|
@ -1,6 +1,6 @@
|
|||
|
||||
use std::rc::Rc;
|
||||
use crate::grid::{Cell, Line, Grid, CellValue};
|
||||
use crate::grid::{Cell, Section, Grid, CellValue};
|
||||
|
||||
pub static mut DEBUG: bool = false;
|
||||
|
||||
|
@ -17,7 +17,7 @@ pub enum SolveStatus {
|
|||
Invalid
|
||||
}
|
||||
|
||||
|
||||
/// See `SolveController` for a description of the solving strategies.
|
||||
enum SolveAction{
|
||||
Single,
|
||||
HiddenSingle,
|
||||
|
@ -54,13 +54,30 @@ impl SolveStatus {
|
|||
}
|
||||
}
|
||||
|
||||
/// A struct representing some options & solving strategies for solving a `Grid`.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct SolveController {
|
||||
/// Whether the solver should try to determine if the solution is unique at the cost of extra computation.
|
||||
pub determine_uniqueness: bool,
|
||||
|
||||
/// Whether the solving strategy where Cells with a single possibility are set to their value is enabled.
|
||||
/// Has never been tested with a `false` value.
|
||||
pub search_singles: bool,
|
||||
|
||||
/// Whether the solving strategy where Cells that contain as a digit a possibility that only occurs
|
||||
/// once in that `Section` should be set to that value, is enabled. Has never been tested with a `false` value.
|
||||
pub search_hidden_singles: bool,
|
||||
|
||||
/// Whether the solving strategy where, in a given `Section`, the solver tries to divide the un-set cells up
|
||||
/// into two or more exclusive groups based on their possibilities, is enabled.
|
||||
pub find_possibility_groups: bool,
|
||||
|
||||
/// Whether the solving strategy where if you know that a digit must occur in a part of Section A that overlaps
|
||||
/// entirely with Section B, that you can then determine that that digit cannot occur in the rest of
|
||||
/// Section B, is enabled.
|
||||
pub search_useful_constraint: bool,
|
||||
|
||||
/// Whether the solver can make guesses as a last resort to try to solve the puzzle.
|
||||
pub make_guesses: bool,
|
||||
}
|
||||
|
||||
|
@ -90,10 +107,10 @@ impl SolveController {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Tracks when we relied on a method to make progress. We'll consider 'relied on' to mean that the method make at least
|
||||
one change to the line it was originally called on, whether that be setting a value or adjusting the possibilities in a cell.
|
||||
*/
|
||||
/// Tracks how often we relied on each solving strategy to make progress. We'll consider 'relied on' to mean
|
||||
/// that the method make at least one change to the line it was originally called on, whether that
|
||||
/// be setting a value or adjusting the possibilities in a cell. Multiple contributions in one call
|
||||
/// of the strategy on a `Section` are only counted as one contribution.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct SolveStatistics {
|
||||
pub singles: u32,
|
||||
|
@ -104,7 +121,9 @@ pub struct SolveStatistics {
|
|||
}
|
||||
|
||||
impl SolveStatistics {
|
||||
pub(crate) fn new() -> SolveStatistics {
|
||||
|
||||
/// Create a new SolveStatistics with `0` counts set for all the fields.
|
||||
pub fn new() -> SolveStatistics {
|
||||
SolveStatistics{
|
||||
singles: 0,
|
||||
hidden_singles: 0,
|
||||
|
@ -125,43 +144,13 @@ impl SolveStatistics {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn find_smallest_cell(grid: &Grid) -> Option<Rc<Cell>>{
|
||||
// Find a cell of smallest size (in terms of possibilities) and make a guess
|
||||
// Can assume that no cells of only possibility 1 exist
|
||||
|
||||
let mut smallest_cell : Option<Rc<Cell>> = None;
|
||||
let mut smallest_size = usize::MAX;
|
||||
|
||||
'outer: for x in 0..9 {
|
||||
for y in 0..9 {
|
||||
let cell_rc = grid.get(x, y).unwrap();
|
||||
let cell = &*grid.get(x, y).unwrap();
|
||||
let cell_value = &*cell.value.borrow();
|
||||
|
||||
match cell_value {
|
||||
CellValue::Unknown(possibilities) => {
|
||||
if (possibilities.len() < smallest_size) && (possibilities.len() > 0){
|
||||
smallest_size = possibilities.len();
|
||||
smallest_cell = Some(cell_rc);
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if smallest_size <= 2 {
|
||||
break 'outer; // We aren't going to get smaller
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
smallest_cell
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Code for identify_and_process_possibility_groups (it uses it's own structs)
|
||||
mod process_possibility_groups {
|
||||
use crate::grid::{Line, CellValue};
|
||||
use crate::grid::{Section, CellValue};
|
||||
use std::collections::HashSet;
|
||||
use std::rc::Rc;
|
||||
|
||||
|
@ -196,17 +185,17 @@ mod process_possibility_groups {
|
|||
|
||||
// See if there's a set of cells with possibilities that exclude those possibilities from other cells.
|
||||
// Runs recursively on each group to identify all groups in case there's more than 2.
|
||||
pub fn identify_and_process_possibility_groups(line: &Line) -> bool{
|
||||
pub fn identify_and_process_possibility_groups(line: &Section) -> bool{
|
||||
unsafe {
|
||||
if super::DEBUG {
|
||||
println!("Looking for possibility groups on line {:?} {}", line.line_type, line.index);
|
||||
println!("Looking for possibility groups on line {:?} {}", line.section_type, line.index);
|
||||
}
|
||||
}
|
||||
|
||||
bisect_possibility_groups(line, vec![0, 1, 2, 3, 4, 5, 6, 7, 8])
|
||||
}
|
||||
|
||||
fn bisect_possibility_groups(line: &Line, cells_of_interest: Vec<usize>) -> bool{
|
||||
fn bisect_possibility_groups(line: &Section, cells_of_interest: Vec<usize>) -> bool{
|
||||
|
||||
/*
|
||||
Algorithm -
|
||||
|
@ -382,10 +371,10 @@ mod process_possibility_groups {
|
|||
}
|
||||
|
||||
// Search for a cell with only one possibility so that we can set it to FIXED
|
||||
fn search_single_possibility(line: &Line) -> bool{
|
||||
fn search_single_possibility(line: &Section) -> bool{
|
||||
unsafe {
|
||||
if DEBUG {
|
||||
println!("search_single_possibility on line {:?} {}", line.line_type, line.index);
|
||||
println!("search_single_possibility on line {:?} {}", line.section_type, line.index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,7 +397,7 @@ fn search_single_possibility(line: &Line) -> bool{
|
|||
}
|
||||
|
||||
// Count up how many times each possibility occurs in the Line. If it only occurs once, that's a hidden single that we can set
|
||||
fn search_hidden_single(line: &Line) -> bool{
|
||||
fn search_hidden_single(line: &Section) -> bool{
|
||||
enum Count {
|
||||
None,
|
||||
One(Rc<Cell>),
|
||||
|
@ -457,7 +446,7 @@ fn search_hidden_single(line: &Line) -> bool{
|
|||
}
|
||||
|
||||
mod search_useful_constraint{
|
||||
use crate::grid::{Grid, Line, LineType, CellValue};
|
||||
use crate::grid::{Grid, Section, SectionType, CellValue};
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::cell::RefCell;
|
||||
|
||||
|
@ -480,19 +469,19 @@ mod search_useful_constraint{
|
|||
// I.e. If possibility '1' only occurs in the first row for section 0, then you can remove that possibility
|
||||
// from row 0 across the other sections. Conversely, if the possibility only occurs in the first section
|
||||
// for row 0, then you can remove the possibility from the rest of section 0.
|
||||
pub fn search_useful_constraint(grid: &Grid, line: &Line) -> bool{
|
||||
pub fn search_useful_constraint(grid: &Grid, line: &Section) -> bool{
|
||||
unsafe {
|
||||
if super::DEBUG {
|
||||
println!("Searching for a useful constraint on line {:?} {}", line.line_type, line.index);
|
||||
println!("Searching for a useful constraint on line {:?} {}", line.section_type, line.index);
|
||||
}
|
||||
}
|
||||
|
||||
let mut made_change = false;
|
||||
|
||||
let (check_row, check_column, check_section) = match line.line_type {
|
||||
LineType::Row => {(false, false, true)},
|
||||
LineType::Column => {(false, false, true)},
|
||||
LineType::Section => {(true, true, false)},
|
||||
let (check_row, check_column, check_section) = match line.section_type {
|
||||
SectionType::Row => {(false, false, true)},
|
||||
SectionType::Column => {(false, false, true)},
|
||||
SectionType::Square => {(true, true, false)},
|
||||
};
|
||||
|
||||
for possibility in 0..9 {
|
||||
|
@ -533,21 +522,21 @@ mod search_useful_constraint{
|
|||
match rows {
|
||||
PossibilityLines::Unique(index) => {
|
||||
made_change = made_change |
|
||||
remove_possibilities_line(grid.rows.get(index).unwrap(), possibility, &line.line_type, line.index);
|
||||
remove_possibilities_line(grid.rows.get(index).unwrap(), possibility, &line.section_type, line.index);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
match columns {
|
||||
PossibilityLines::Unique(index) => {
|
||||
made_change = made_change |
|
||||
remove_possibilities_line(grid.columns.get(index).unwrap(), possibility, &line.line_type, line.index);
|
||||
remove_possibilities_line(grid.columns.get(index).unwrap(), possibility, &line.section_type, line.index);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
match sections {
|
||||
PossibilityLines::Unique(index) => {
|
||||
made_change = made_change |
|
||||
remove_possibilities_line(grid.sections.get(index).unwrap(), possibility, &line.line_type, line.index);
|
||||
remove_possibilities_line(grid.sections.get(index).unwrap(), possibility, &line.section_type, line.index);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
@ -558,7 +547,7 @@ mod search_useful_constraint{
|
|||
}
|
||||
|
||||
// initial_line_type and initial_line_index are to identify the cells that should NOT have their possibilities removed
|
||||
fn remove_possibilities_line(line: &Rc<RefCell<Line>>, digit_to_remove: u8, initial_line_type: &LineType, initial_line_index: usize) -> bool {
|
||||
fn remove_possibilities_line(line: &Rc<RefCell<Section>>, digit_to_remove: u8, initial_line_type: &SectionType, initial_line_index: usize) -> bool {
|
||||
let line = &*(&**line).borrow();
|
||||
let mut made_change = false;
|
||||
|
||||
|
@ -568,9 +557,9 @@ mod search_useful_constraint{
|
|||
match value {
|
||||
CellValue::Unknown(possibilities) => {
|
||||
let parent_line = match initial_line_type {
|
||||
LineType::Row => &cell.row,
|
||||
LineType::Column => &cell.column,
|
||||
LineType::Section => &cell.section
|
||||
SectionType::Row => &cell.row,
|
||||
SectionType::Column => &cell.column,
|
||||
SectionType::Square => &cell.section
|
||||
};
|
||||
let parent_line = &*parent_line.upgrade().unwrap();
|
||||
let parent_line = &*parent_line.borrow();
|
||||
|
@ -610,7 +599,7 @@ mod search_useful_constraint{
|
|||
}
|
||||
|
||||
// We detected a useful constraint
|
||||
fn process_possibility_line(possibility_line: PossibilityLines, line: &Weak<RefCell<Line>>) -> PossibilityLines {
|
||||
fn process_possibility_line(possibility_line: PossibilityLines, line: &Weak<RefCell<Section>>) -> PossibilityLines {
|
||||
let line = line.upgrade().unwrap();
|
||||
let line = &*(&*line).borrow();
|
||||
|
||||
|
@ -630,10 +619,10 @@ mod search_useful_constraint{
|
|||
}
|
||||
|
||||
|
||||
fn solve_line(grid: &Grid, line: &Line, solve_controller: &SolveController, solve_statistics: &mut SolveStatistics){
|
||||
fn solve_line(grid: &Grid, line: &Section, solve_controller: &SolveController, solve_statistics: &mut SolveStatistics){
|
||||
unsafe {
|
||||
if DEBUG {
|
||||
println!("Solving {:?} {}", line.line_type, line.index);
|
||||
println!("Solving {:?} {}", line.section_type, line.index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -642,7 +631,7 @@ fn solve_line(grid: &Grid, line: &Line, solve_controller: &SolveController, solv
|
|||
if solve_controller.search_singles() {
|
||||
unsafe {
|
||||
if DEBUG {
|
||||
println!("Searching for singles on line {:?} of {}\n{}", line.line_type, line.index, grid);
|
||||
println!("Searching for singles on line {:?} of {}\n{}", line.section_type, line.index, grid);
|
||||
}
|
||||
}
|
||||
if search_single_possibility(line) {
|
||||
|
@ -653,7 +642,7 @@ fn solve_line(grid: &Grid, line: &Line, solve_controller: &SolveController, solv
|
|||
if solve_controller.search_hidden_singles() {
|
||||
unsafe {
|
||||
if DEBUG {
|
||||
println!("Searching for hidden singles on line {:?} of {}\n{}", line.line_type, line.index, grid);
|
||||
println!("Searching for hidden singles on line {:?} of {}\n{}", line.section_type, line.index, grid);
|
||||
}
|
||||
}
|
||||
if search_hidden_single(line) {
|
||||
|
@ -664,7 +653,7 @@ fn solve_line(grid: &Grid, line: &Line, solve_controller: &SolveController, solv
|
|||
if solve_controller.find_possibility_groups() {
|
||||
unsafe {
|
||||
if DEBUG {
|
||||
println!("Searching for possibility groups on line {:?} of {}\n{}", line.line_type, line.index, grid);
|
||||
println!("Searching for possibility groups on line {:?} of {}\n{}", line.section_type, line.index, grid);
|
||||
}
|
||||
}
|
||||
if process_possibility_groups::identify_and_process_possibility_groups(line) {
|
||||
|
@ -675,7 +664,7 @@ fn solve_line(grid: &Grid, line: &Line, solve_controller: &SolveController, solv
|
|||
if solve_controller.search_useful_constraint() {
|
||||
unsafe {
|
||||
if DEBUG {
|
||||
println!("Searching for useful constraints on line {:?} of {}\n{}", line.line_type, line.index, grid);
|
||||
println!("Searching for useful constraints on line {:?} of {}\n{}", line.section_type, line.index, grid);
|
||||
}
|
||||
}
|
||||
if search_useful_constraint::search_useful_constraint(grid, line) {
|
||||
|
@ -685,6 +674,9 @@ fn solve_line(grid: &Grid, line: &Line, solve_controller: &SolveController, solv
|
|||
|
||||
}
|
||||
|
||||
/// Solves (and modifies) the input `Grid`. Returns a `SolveStatus` and `SolveStatistics`, and
|
||||
/// enables all solving strategies. If you want to specify a `SolveController` you can
|
||||
/// call `solve_grid_with_solve_controller` directly, but you also have to input an empty `SolveStatistics`.
|
||||
pub fn solve_grid(grid: &mut Grid) -> (SolveStatus, SolveStatistics) {
|
||||
// By default we enable everything
|
||||
let solve_controller = SolveController {
|
||||
|
@ -702,6 +694,7 @@ pub fn solve_grid(grid: &mut Grid) -> (SolveStatus, SolveStatistics) {
|
|||
return (solve_status, solve_statistics);
|
||||
}
|
||||
|
||||
/// Solves (and modifies) the input `Grid` & `SolveStatistics`. Returns a `SolveStatus`.
|
||||
pub fn solve_grid_with_solve_controller(grid: &mut Grid, solve_controller: &SolveController, solve_statistics: &mut SolveStatistics) -> SolveStatus{
|
||||
// Code is kind of messy so here it goes - solve_grid first tries to solve without any guesses
|
||||
// If that's not enough and a guess is required, then solve_grid_guess is called
|
||||
|
@ -725,7 +718,9 @@ pub fn solve_grid_with_solve_controller(grid: &mut Grid, solve_controller: &Solv
|
|||
return status;
|
||||
}
|
||||
|
||||
// Similar to solve_grid_with_solve_controller except that we don't modify the input Grid; we only determine SolveStatus
|
||||
/// Similar to `solve_grid_with_solve_controller` except that we don't modify the input Grid; we
|
||||
/// only determine SolveStatus. This is useful when generating puzzles where we need to know *if*
|
||||
/// a puzzle can be solved but don't want to actually solve it.
|
||||
pub fn evaluate_grid_with_solve_controller(grid: &Grid, solve_controller: &SolveController) -> (SolveStatus, SolveStatistics){
|
||||
let mut mut_grid = grid.clone();
|
||||
let mut solve_statistics = SolveStatistics::new();
|
||||
|
@ -735,7 +730,7 @@ pub fn evaluate_grid_with_solve_controller(grid: &Grid, solve_controller: &Solve
|
|||
return (solve_status, solve_statistics);
|
||||
}
|
||||
|
||||
pub fn solve_grid_no_guess(grid: &mut Grid, solve_controller: &SolveController, solve_statistics: &mut SolveStatistics) -> SolveStatus{
|
||||
fn solve_grid_no_guess(grid: &mut Grid, solve_controller: &SolveController, solve_statistics: &mut SolveStatistics) -> SolveStatus{
|
||||
|
||||
loop {
|
||||
let mut ran_something = false;
|
||||
|
@ -801,7 +796,7 @@ pub fn solve_grid_no_guess(grid: &mut Grid, solve_controller: &SolveController,
|
|||
fn solve_grid_guess(grid: &mut Grid, solve_controller: &SolveController, solve_statistics: &mut SolveStatistics) -> SolveStatus{
|
||||
solve_statistics.increment(&SolveAction::Guess);
|
||||
|
||||
let smallest_cell = find_smallest_cell(grid);
|
||||
let smallest_cell = grid.find_smallest_cell();
|
||||
let smallest_cell = match smallest_cell {
|
||||
Some(cell) => cell,
|
||||
None => return SolveStatus::Invalid
|
||||
|
|
Loading…
Reference in a new issue