introduce bitloops
This commit is contained in:
@@ -395,76 +395,49 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
|
|
||||||
long maskFitness(Grid grid) {
|
long maskFitness(Grid grid) {
|
||||||
|
|
||||||
var clueCount = grid.clueCount();
|
|
||||||
long penalty = ((long) Math.abs(clueCount - TARGET_CLUES)) << 3;
|
|
||||||
|
|
||||||
var ctx = CTX.get();
|
var ctx = CTX.get();
|
||||||
var covH = ctx.covH;
|
var covH = ctx.covH;
|
||||||
var covV = ctx.covV;
|
var covV = ctx.covV;
|
||||||
Arrays.fill(covH, 0, SIZE, 0);
|
Arrays.fill(covH, 0, SIZE, 0);
|
||||||
Arrays.fill(covV, 0, SIZE, 0);
|
Arrays.fill(covV, 0, SIZE, 0);
|
||||||
|
|
||||||
boolean hasSlots = false;
|
|
||||||
long lo_cl = grid.bo[0], hi_cl = grid.bo[1];
|
long lo_cl = grid.bo[0], hi_cl = grid.bo[1];
|
||||||
while (lo_cl != 0L) {
|
|
||||||
int clueIdx = Long.numberOfTrailingZeros(lo_cl);
|
|
||||||
lo_cl &= (lo_cl - 1);
|
|
||||||
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 (k == 0) continue;
|
|
||||||
hasSlots = true;
|
|
||||||
if (k < MIN_LEN) penalty += 8000;
|
|
||||||
}
|
|
||||||
while (hi_cl != 0L) {
|
|
||||||
int clueIdx = 64 + Long.numberOfTrailingZeros(hi_cl);
|
|
||||||
hi_cl &= (hi_cl - 1);
|
|
||||||
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 (k == 0) continue;
|
|
||||||
hasSlots = true;
|
|
||||||
if (k < MIN_LEN) penalty += 8000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasSlots) return 1_000_000_000L;
|
|
||||||
|
|
||||||
// clue clustering (8-connected)
|
// clue clustering (8-connected)
|
||||||
var seen = ctx.seen;
|
var seen = ctx.seen;
|
||||||
seen.clear();
|
|
||||||
var stack = ctx.stack;
|
var stack = ctx.stack;
|
||||||
class Mask {
|
class Mask {
|
||||||
|
|
||||||
long penalty;
|
long penalty = (((long) Math.abs(grid.clueCount() - TARGET_CLUES)) << 3);
|
||||||
Mask(long pen) { this.penalty = pen; }
|
boolean hasSlots = false;
|
||||||
void clueStackPenalty(int clueIdx) {
|
void space(int clueIdx) {
|
||||||
if (seen.get(clueIdx)) ;
|
var d = grid.digitAt(clueIdx);
|
||||||
var sp = 0;
|
var nbrs16 = OFFSETS[d];
|
||||||
stack[sp++] = clueIdx;
|
long packed = nbrs16.path()[clueIdx];
|
||||||
seen.set(clueIdx);
|
int n = (int) (packed >>> 56), k, idx;
|
||||||
var size = 0;
|
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 (k == 0) return;
|
||||||
|
hasSlots = true;
|
||||||
|
if (k < MIN_LEN) penalty += 8000;
|
||||||
|
}
|
||||||
|
|
||||||
while (sp > 0) {
|
void clueStackPenalty(int clueIdx) {
|
||||||
var p = stack[--sp];
|
if (seen.get(clueIdx)) return;
|
||||||
size++;
|
int size = 0;
|
||||||
long packed = Neighbors9x8.NBR8_PACKED[p];
|
long packed;
|
||||||
int n = (int) (packed >>> 56);
|
stack[0] = clueIdx;
|
||||||
for (int k = 0; k < n; k++) {
|
seen.set(clueIdx);
|
||||||
int nidx = (int) ((packed >>> (k * 7)) & 0x7F);
|
|
||||||
|
for (int sp = 1, n, nidx, k; sp > 0; size++) {
|
||||||
|
packed = Neighbors9x8.NBR8_PACKED[stack[--sp]];
|
||||||
|
n = (int) (packed >>> 56);
|
||||||
|
for (k = 0; k < n; k++) {
|
||||||
|
nidx = (int) ((packed >>> (k * 7)) & 0x7F);
|
||||||
if (seen.get(nidx) || grid.notClue(nidx)) continue;
|
if (seen.get(nidx) || grid.notClue(nidx)) continue;
|
||||||
seen.set(nidx);
|
seen.set(nidx);
|
||||||
stack[sp++] = nidx;
|
stack[sp++] = nidx;
|
||||||
@@ -473,7 +446,7 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
if (size >= 2) this.penalty += ((size - 1L) * 120L);
|
if (size >= 2) this.penalty += ((size - 1L) * 120L);
|
||||||
}
|
}
|
||||||
void wall(rci rci) {
|
void wall(rci rci) {
|
||||||
if ((4 - rci.nbrCount()) + Long.bitCount(rci.n1() & grid.bo[0]) + Long.bitCount(rci.n2() & grid.bo[1]) >= 3) this.penalty += 400;
|
if ((4 - rci.nbrCount()) + Long.bitCount(rci.n1() & lo_cl) + Long.bitCount(rci.n2() & hi_cl) >= 3) this.penalty += 400;
|
||||||
var h = covH[rci.i()];
|
var h = covH[rci.i()];
|
||||||
var v = covV[rci.i()];
|
var v = covV[rci.i()];
|
||||||
if (h == 0 && v == 0) this.penalty += 1500;
|
if (h == 0 && v == 0) this.penalty += 1500;
|
||||||
@@ -482,12 +455,19 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
val mask = new Mask(penalty);
|
val space = new Mask();
|
||||||
for (var lo = grid.bo[0]; lo != 0; lo &= lo - 1) mask.clueStackPenalty(Long.numberOfTrailingZeros(lo));
|
for (var lo = lo_cl; lo != 0L; lo &= lo - 1) space.space(Long.numberOfTrailingZeros(lo));
|
||||||
for (var hi = grid.bo[1]; hi != 0; hi &= hi - 1) mask.clueStackPenalty(64 + Long.numberOfTrailingZeros(hi));
|
for (var hi = hi_cl; hi != 0L; hi &= hi - 1) space.space(64 + Long.numberOfTrailingZeros(hi));
|
||||||
|
if (!space.hasSlots) return 1_000_000_000L;
|
||||||
|
seen.clear();
|
||||||
|
for (var lo = lo_cl; lo != 0L; lo &= lo - 1) space.clueStackPenalty(Long.numberOfTrailingZeros(lo));
|
||||||
|
for (var hi = hi_cl; hi != 0L; hi &= hi - 1) space.clueStackPenalty(64 + Long.numberOfTrailingZeros(hi));
|
||||||
|
for (var lo = ~lo_cl; lo != 0L; lo &= lo - 1) space.wall(IT[Long.numberOfTrailingZeros(lo)]);
|
||||||
|
for (var hi = ~hi_cl & 0xFFL; hi != 0L; hi &= hi - 1) space.wall(IT[64 + Long.numberOfTrailingZeros(hi)]);
|
||||||
|
|
||||||
|
//for (var rci : IT) if (grid.notClue(rci.i())) space.wall(rci);
|
||||||
// dead-end-ish letter cell (3+ walls)
|
// dead-end-ish letter cell (3+ walls)
|
||||||
int walls, wc, wr;
|
// int walls, wc, wr;
|
||||||
/* for (var rci : IT) {
|
/* for (var rci : IT) {
|
||||||
if (grid.isDigitAt(rci.i())) continue;
|
if (grid.isDigitAt(rci.i())) continue;
|
||||||
walls = 0;
|
walls = 0;
|
||||||
@@ -498,8 +478,8 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
}
|
}
|
||||||
if (walls >= 3) penalty[0] += 400;
|
if (walls >= 3) penalty[0] += 400;
|
||||||
}*/
|
}*/
|
||||||
for (var rci : IT) if (grid.notClue(rci.i())) mask.wall(rci);
|
|
||||||
return mask.penalty;
|
return space.penalty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid randomMask() {
|
Grid randomMask() {
|
||||||
|
|||||||
Reference in New Issue
Block a user