introduce bitloops

This commit is contained in:
mike
2026-01-10 07:36:26 +01:00
parent 558f0f9e0e
commit 1521e461bc
3 changed files with 22 additions and 28 deletions

View File

@@ -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());

View File

@@ -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()];

View File

@@ -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() {