diff --git a/src/main/java/puzzle/Main.java b/src/main/java/puzzle/Main.java index 18dbacf..118a2c5 100644 --- a/src/main/java/puzzle/Main.java +++ b/src/main/java/puzzle/Main.java @@ -41,7 +41,7 @@ public class Main { public int seed = (int) (System.nanoTime() ^ System.currentTimeMillis()); public int pop = 18; - public int gens = 2000; + public int gens = 1000; public String wordsPath = "nl_score_hints_v3.csv"; public double minSimplicity = 0; // 0 means no limit public int threads = Math.max(1, Runtime.getRuntime().availableProcessors()); diff --git a/src/main/java/puzzle/SwedishGenerator.java b/src/main/java/puzzle/SwedishGenerator.java index 1198405..5295936 100644 --- a/src/main/java/puzzle/SwedishGenerator.java +++ b/src/main/java/puzzle/SwedishGenerator.java @@ -170,9 +170,15 @@ public record SwedishGenerator(Rng rng) { boolean isDigitAt(int index) { return isDigit(g[index]); } boolean isClue(int index) { if (index < 64) { - return (bo[0] >> index & 1L) != 0; + return ((bo[0] >> index) & 1L) != 0; } - return (bo[1] >> (index & 63) & 1L) != 0; + return ((bo[1] >> (index & 63)) & 1L) != 0; + } + boolean notClue(int index) { + if (index < 64) { + return ((bo[0] >> index) & 1L) == 0L; + } + return ((bo[1] >> (index & 63)) & 1L) == 0L; } boolean clueless(int idx) { if (idx < 64) { @@ -394,7 +400,7 @@ public record SwedishGenerator(Rng rng) { boolean hasSlots = false; long lo_cl = grid.bo[0], hi_cl = grid.bo[1]; - while (lo_cl != 0) { + while (lo_cl != 0L) { int clueIdx = Long.numberOfTrailingZeros(lo_cl); lo_cl &= (lo_cl - 1); var d = grid.digitAt(clueIdx); @@ -411,7 +417,7 @@ public record SwedishGenerator(Rng rng) { hasSlots = true; if (k < MIN_LEN) penalty[0] += 8000; } - while (hi_cl != 0) { + while (hi_cl != 0L) { int clueIdx = 64 + Long.numberOfTrailingZeros(hi_cl); hi_cl &= (hi_cl - 1); var d = grid.digitAt(clueIdx); @@ -444,46 +450,34 @@ public record SwedishGenerator(Rng rng) { var size = 0; while (sp > 0) { - var p = stack[--sp]; - int rr = Grid.c(p), cc = Grid.r(p); + var p = stack[--sp]; size++; - long packed = Neighbors9x8.NBR8_PACKED[Grid.offset(rr, cc)]; + long packed = Neighbors9x8.NBR8_PACKED[p]; int n = (int) (packed >>> 56); for (int k = 0; k < n; k++) { int nidx = (int) ((packed >>> (k * 7)) & 0x7F); - - if (seen.get(nidx) || grid.isLetterAt(nidx)) continue; + if (seen.get(nidx) || grid.notClue(nidx)) continue; seen.set(nidx); stack[sp++] = nidx; } - /* for (var d : nbrs8) { - var nr = rr + d.r(); - var nc = cc + d.c(); - if (nr < 0 || nr >= R || nc < 0 || nc >= C) continue; - var nidx = Grid.offset(nr, nc); - if (seen.get(nidx) || grid.isLetterAt(nidx)) continue; - seen.set(nidx); - stack[sp++] = nidx; - } */ } - if (size >= 2) penalty[0] += (size - 1L) * 120L; }); // dead-end-ish letter cell (3+ walls) int walls, wc, wr; - /*for (var rci : IT) { + /* for (var rci : IT) { if (grid.isDigitAt(rci.i())) continue; walls = 0; for (var d : nbrs4) { wr = rci.r() + d.r(); wc = rci.c() + d.c(); - if (wr < 0 || wr >= R || wc < 0 || wc >= C || grid.isDigitAt(wr, wc)) walls++; + if (wr < 0 || wr >= R || wc < 0 || wc >= C || grid.isDigitAt(Grid.offset(wr, wc))) walls++; } if (walls >= 3) penalty[0] += 400; }*/ int h, v; for (var rci : IT) { - if (grid.isDigitAt(rci.i())) continue; + if (grid.isClue(rci.i())) continue; if ((4 - rci.nbrCount()) + Long.bitCount(rci.n1() & grid.bo[0]) + Long.bitCount(rci.n2() & grid.bo[1]) >= 3) penalty[0] += 400; h = covH[rci.i()]; v = covV[rci.i()]; diff --git a/src/test/java/puzzle/MainTest.java b/src/test/java/puzzle/MainTest.java index 65c63c3..b1ec0af 100644 --- a/src/test/java/puzzle/MainTest.java +++ b/src/test/java/puzzle/MainTest.java @@ -132,7 +132,7 @@ public class MainTest { public void testAttempt() { // Arrange var opts = new Main.Opts(); - opts.seed = 12347; + opts.seed = 12348; opts.pop = 4; // Tiny population opts.gens = 20; // Very few generations opts.minSimplicity = 0; @@ -165,10 +165,10 @@ public class MainTest { Assertions.assertTrue(res.filled().ok(), "Puzzle generation failed (not ok)"); // Regression baseline for seed search starting at 12347, pop 4, gens 20 - Assertions.assertEquals(12347, foundSeed, "Found seed changed"); - Assertions.assertEquals(24, res.filled().clueMap().size(), "Number of assigned words changed"); - Assertions.assertEquals(735.7083333333334, res.filled().stats().simplicity, 1e-9, "Simplicity value changed"); - Assertions.assertArrayEquals(new byte[]{ 'E', 'B', 'B', 'E', 'N' }, res.filled().clueMap().get(515).word()); + Assertions.assertEquals(12348, foundSeed, "Found seed changed"); + Assertions.assertEquals(22, res.filled().clueMap().size(), "Number of assigned words changed"); + Assertions.assertEquals(767.8636363636364, res.filled().stats().simplicity, 1e-9, "Simplicity value changed"); + Assertions.assertArrayEquals(new byte[]{ 'T', 'R', 'U', 'I' }, res.filled().clueMap().get(515).word()); } @Test public void testIsLetterA() {