introduce bitloops

This commit is contained in:
mike
2026-01-10 04:25:51 +01:00
parent b1f262ac91
commit e559040321
3 changed files with 39 additions and 64 deletions

View File

@@ -64,7 +64,7 @@
<dependency>
<groupId>mike.processor</groupId>
<artifactId>puzzle-processor</artifactId>
<version>1.1-SNAPSHOT</version>
<version>1.2-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
@@ -104,7 +104,7 @@
<path>
<groupId>mike.processor</groupId>
<artifactId>puzzle-processor</artifactId>
<version>1.1-SNAPSHOT</version>
<version>1.2-SNAPSHOT</version>
</path>
</annotationProcessorPaths>
<source>25</source>

View File

@@ -1,13 +0,0 @@
package puzzle;
/**
* Generated constants from pom.xml during build via templating-maven-plugin.
*/
public final class Config {
public static final int CLUE_SIZE = 4;
public static final int MIN_LEN = 2;
public static final int MAX_TRIES_PER_SLOT = 2000;
public static final int MAX_LEN = 8;
public static final int PUZZLE_ROWS = 8;
public static final int PUZZLE_COLS = 9;
}

View File

@@ -380,15 +380,22 @@ public record SwedishGenerator(Rng rng) {
grid.forEachSlot((key, packedPos, len) -> slots.add(Slot.from(key, packedPos, len)));
return slots;
}
boolean hasRoomForClue(Grid grid, int idx, nbrs_16 nbrs16) {
int rr = Grid.r(idx) + nbrs16.r(), cc = Grid.c(idx) + nbrs16.c();
var run = 0;
boolean hasRoomForClue(Grid grid, long packed) {
//long packed = nbrs16.path()[idx];
int n = (int) (packed >>> 56), k, idx;
for (k = 0; k < n && k < MAX_WORD_LENGTH; ) {
idx = (int) ((packed >>> (k * 7)) & 0x7F);
if (!grid.isLetterAt(idx)) break;
k++;
if (k >= MIN_LEN) return true;
}
/* int rr = Grid.r(idx) + nbrs16.r(), cc = Grid.c(idx) + nbrs16.c();
while (rr >= 0 && rr < R && cc >= 0 && cc < C && (grid.isLetterAt(rr, cc)) && run < MAX_WORD_LENGTH) {
run++;
rr += nbrs16.dr();
cc += nbrs16.dc();
if (run >= MIN_LEN) return true;
}
}*/
return false;
}
@@ -409,54 +416,36 @@ public record SwedishGenerator(Rng rng) {
while (lo_cl != 0) {
int clueIdx = Long.numberOfTrailingZeros(lo_cl);
lo_cl &= (lo_cl - 1);
var d = grid.digitAt(clueIdx);
var nbrs16 = OFFSETS[d];
int rr = Grid.r(clueIdx) + nbrs16.r(), cc = Grid.c(clueIdx) + nbrs16.c();
if (rr < 0 || rr >= R || cc < 0 || cc >= C || grid.isDigitAt(rr, cc)) continue;
long packedPos = 0;
var n = 0;
while (rr >= 0 && rr < R && cc >= 0 && cc < C && n < MAX_WORD_LENGTH) {
if (grid.isDigitAt(rr, cc)) break;
packedPos |= (long) Grid.offset(rr, cc) << (n * 7);
n++;
rr += nbrs16.dr();
cc += nbrs16.dc();
var d = grid.digitAt(clueIdx);
var nbrs16 = OFFSETS[d];
long packed = nbrs16.path()[clueIdx];
int n = (int) (packed >>> 56), k, idx;
var horiz = Slot.horiz(d) ? covH : covV;
for (k = 0; k < n && k < MAX_WORD_LENGTH; k++) {
idx = (int) ((packed >>> (k * 7)) & 0x7F);
if (grid.isClue(idx)) break;
horiz[idx] += 1;
}
if (n == 0) continue;
if (k == 0) continue;
hasSlots = true;
if (n < MIN_LEN) {
penalty[0] += 8000;
}
var horiz = Slot.horiz(d) ? covH : covV;
for (var i = 0; i < n; i++) horiz[Slot.offset(packedPos, i)] += 1;
if (k < MIN_LEN) penalty[0] += 8000;
}
while (hi_cl != 0) {
int clueIdx = 64 + Long.numberOfTrailingZeros(hi_cl);
hi_cl &= (hi_cl - 1);
var d = grid.digitAt(clueIdx);
var nbrs16 = OFFSETS[d];
int rr = Grid.r(clueIdx) + nbrs16.r(), cc = Grid.c(clueIdx) + nbrs16.c();
if (rr < 0 || rr >= R || cc < 0 || cc >= C || grid.isDigitAt(rr, cc)) continue;
long packedPos = 0;
var n = 0;
while (rr >= 0 && rr < R && cc >= 0 && cc < C && n < MAX_WORD_LENGTH) {
if (grid.isDigitAt(rr, cc)) break;
packedPos |= (long) Grid.offset(rr, cc) << (n * 7);
n++;
rr += nbrs16.dr();
cc += nbrs16.dc();
var d = grid.digitAt(clueIdx);
var nbrs16 = OFFSETS[d];
long packed = nbrs16.path()[clueIdx];
int n = (int) (packed >>> 56), k, idx;
var horiz = Slot.horiz(d) ? covH : covV;
for (k = 0; k < n && k < MAX_WORD_LENGTH; k++) {
idx = (int) ((packed >>> (k * 7)) & 0x7F);
if (grid.isClue(idx)) break;
horiz[idx] += 1;
}
if (n == 0) continue;
if (k == 0) continue;
hasSlots = true;
if (n < MIN_LEN) {
penalty[0] += 8000;
}
var horiz = Slot.horiz(d) ? covH : covV;
for (var i = 0; i < n; i++) horiz[Slot.offset(packedPos, i)] += 1;
if (k < MIN_LEN) penalty[0] += 8000;
}
if (!hasSlots) return 1_000_000_000L;
@@ -510,8 +499,7 @@ public record SwedishGenerator(Rng rng) {
h = covH[rci.i()];
v = covV[rci.i()];
if (h == 0 && v == 0) penalty[0] += 1500;
else if (h > 0 && v > 0) { /* ok */ }
else if (h + v == 1) penalty[0] += 200;
else if (h > 0 && v > 0) { /* ok */ } else if (h + v == 1) penalty[0] += 200;
else penalty[0] += 600;
}
return penalty[0];
@@ -525,7 +513,7 @@ public record SwedishGenerator(Rng rng) {
if (g.isClue(idx)) continue;
var d = OFFSETS[rng.randbyte(1, 4)];
if (hasRoomForClue(g, idx, d)) {
if (hasRoomForClue(g, d.path()[idx])) {
g.setClue(idx, d.dbyte());
placed++;
}
@@ -545,7 +533,7 @@ public record SwedishGenerator(Rng rng) {
if (!g.clueless(ri)) {
var d = OFFSETS[rng.randint(1, 4)];
if (hasRoomForClue(g, ri, d)) g.setClue(ri, d.dbyte());
if (hasRoomForClue(g, d.path()[ri])) g.setClue(ri, d.dbyte());
}
}
return g;
@@ -557,7 +545,7 @@ public record SwedishGenerator(Rng rng) {
var nr = Math.sin(theta);
for (var rci : IT) out.setAt(rci.i(), ((rci.r() - CROSS_C) * nc + (rci.c() - CROSS_R) * nr >= 0) ? a.byteAt(rci.i()) : b.byteAt(rci.i()));
for (var rci : IT) if (out.isDigitAt(rci.i()) && !hasRoomForClue(out, rci.i(), OFFSETS[out.digitAt(rci.i())])) out.clearClue(rci.i());
for (var rci : IT) if (out.isClue(rci.i()) && !hasRoomForClue(out, OFFSETS[out.digitAt(rci.i())].path()[rci.i()])) out.clearClue(rci.i());
return out;
}