introduce bitloops
This commit is contained in:
@@ -447,36 +447,12 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
var seen = ctx.seen;
|
var seen = ctx.seen;
|
||||||
seen.clear();
|
seen.clear();
|
||||||
var stack = ctx.stack;
|
var stack = ctx.stack;
|
||||||
|
class Mask {
|
||||||
|
|
||||||
for (var lo = grid.bo[0]; lo != 0; lo &= lo - 1) penalty += clueStackPenalty(seen, stack, grid, Long.numberOfTrailingZeros(lo));
|
long penalty;
|
||||||
for (var hi = grid.bo[1]; hi != 0; hi &= hi - 1) penalty += clueStackPenalty(seen, stack, grid, 64 + Long.numberOfTrailingZeros(hi));
|
Mask(long pen) { this.penalty = pen; }
|
||||||
|
void clueStackPenalty(int clueIdx) {
|
||||||
// dead-end-ish letter cell (3+ walls)
|
if (seen.get(clueIdx)) ;
|
||||||
int walls, wc, wr;
|
|
||||||
/* 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(Grid.offset(wr, wc))) walls++;
|
|
||||||
}
|
|
||||||
if (walls >= 3) penalty[0] += 400;
|
|
||||||
}*/
|
|
||||||
int h, v;
|
|
||||||
for (var rci : IT) {
|
|
||||||
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 += 400;
|
|
||||||
h = covH[rci.i()];
|
|
||||||
v = covV[rci.i()];
|
|
||||||
if (h == 0 && v == 0) penalty += 1500;
|
|
||||||
else if (h > 0 && v > 0) { /* ok */ } else if (h + v == 1) penalty += 200;
|
|
||||||
else penalty += 600;
|
|
||||||
}
|
|
||||||
return penalty;
|
|
||||||
}
|
|
||||||
static long clueStackPenalty(Bit seen, int[] stack, Grid grid, int clueIdx) {
|
|
||||||
if (seen.get(clueIdx)) return 0;
|
|
||||||
var sp = 0;
|
var sp = 0;
|
||||||
stack[sp++] = clueIdx;
|
stack[sp++] = clueIdx;
|
||||||
seen.set(clueIdx);
|
seen.set(clueIdx);
|
||||||
@@ -494,8 +470,38 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
stack[sp++] = nidx;
|
stack[sp++] = nidx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (size >= 2) ? (size - 1L) * 120L : 0;
|
if (size >= 2) this.penalty += ((size - 1L) * 120L);
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
var h = covH[rci.i()];
|
||||||
|
var v = covV[rci.i()];
|
||||||
|
if (h == 0 && v == 0) this.penalty += 1500;
|
||||||
|
else if (h > 0 && v > 0) { /* ok */ } else if (h + v == 1) penalty += 200;
|
||||||
|
else this.penalty += 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
val mask = new Mask(penalty);
|
||||||
|
for (var lo = grid.bo[0]; lo != 0; lo &= lo - 1) mask.clueStackPenalty(Long.numberOfTrailingZeros(lo));
|
||||||
|
for (var hi = grid.bo[1]; hi != 0; hi &= hi - 1) mask.clueStackPenalty(64 + Long.numberOfTrailingZeros(hi));
|
||||||
|
|
||||||
|
// dead-end-ish letter cell (3+ walls)
|
||||||
|
int walls, wc, wr;
|
||||||
|
/* 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(Grid.offset(wr, wc))) walls++;
|
||||||
|
}
|
||||||
|
if (walls >= 3) penalty[0] += 400;
|
||||||
|
}*/
|
||||||
|
for (var rci : IT) if (grid.notClue(rci.i())) mask.wall(rci);
|
||||||
|
return mask.penalty;
|
||||||
|
}
|
||||||
|
|
||||||
Grid randomMask() {
|
Grid randomMask() {
|
||||||
var g = Grid.createEmpty();
|
var g = Grid.createEmpty();
|
||||||
for (int placed = 0, guard = 0, idx; placed < TARGET_CLUES && guard < 4000; guard++) {
|
for (int placed = 0, guard = 0, idx; placed < TARGET_CLUES && guard < 4000; guard++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user