chiark / gitweb /
Dominosa: move set analysis with doubles into Extreme.
authorSimon Tatham <anakin@pobox.com>
Sat, 13 Apr 2019 14:57:28 +0000 (15:57 +0100)
committerSimon Tatham <anakin@pobox.com>
Sat, 13 Apr 2019 14:57:28 +0000 (15:57 +0100)
This change doesn't alter the overall power of the Dominosa solver; it
just moves the boundary between Hard and Extreme so that fewer puzzles
count as Hard, and more as Extreme. Specifically, either of the two
cases of set analysis potentially involving a double domino with both
squares in the set is now classed as Extreme.

The effects on difficulty are that Hard is now easier, and Extreme is
at least easier _on average_. But the main purpose is the effect on
generation time: before this change, Dominosa Extreme was the slowest
puzzle present to generate in the whole collection, by a factor of
more than three. I think the forcing-chain deductions just didn't make
very many additional grids soluble, so that the generator had to try a
lot of candidates before finding one that could be solved using
forcing chains but not with all the other techniques put together.

dominosa.c

index 8eb05eeb2e0035a96b4e2eec168a1360c9f7ec98..c75d572722c5afb0f4b8eee661674fd58c7ebd8f 100644 (file)
@@ -1013,7 +1013,7 @@ static bool deduce_parity(struct solver_scratch *sc)
  * is small enough to let us rule out placements of those dominoes
  * elsewhere.
  */
-static bool deduce_set_simple(struct solver_scratch *sc)
+static bool deduce_set(struct solver_scratch *sc, bool doubles)
 {
     struct solver_square **sqs, **sqp, **sqe;
     int num, nsq, i, j;
@@ -1195,6 +1195,9 @@ static bool deduce_set_simple(struct solver_scratch *sc)
                 rule_out_text = "all of them elsewhere";
 #endif
             } else {
+                if (!doubles)
+                    continue;          /* not at this difficulty level */
+
                 /*
                  * But in Dominosa, there's a special case if _two_
                  * squares in this set can possibly both be covered by
@@ -1761,7 +1764,7 @@ static int run_solver(struct solver_scratch *sc, int max_diff_allowed)
         if (max_diff_allowed <= DIFF_BASIC)
             continue;
 
-        if (deduce_set_simple(sc))
+        if (deduce_set(sc, false))
             done_something = true;
         if (done_something) {
             sc->max_diff_used = max(sc->max_diff_used, DIFF_HARD);
@@ -1771,6 +1774,13 @@ static int run_solver(struct solver_scratch *sc, int max_diff_allowed)
         if (max_diff_allowed <= DIFF_HARD)
             continue;
 
+        if (deduce_set(sc, true))
+            done_something = true;
+        if (done_something) {
+            sc->max_diff_used = max(sc->max_diff_used, DIFF_EXTREME);
+            continue;
+        }
+
         if (deduce_forcing_chain(sc))
             done_something = true;
         if (done_something) {