introduce bitloops
This commit is contained in:
@@ -57,6 +57,8 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
static final int SIZE = C * R;// ~18
|
||||
static final int SIZE_MIN_1 = SIZE - 1;// ~18
|
||||
static final double SIZED = (double) SIZE;// ~18
|
||||
static final long MASK_LO = (SIZE >= 64) ? -1L : (1L << SIZE) - 1;
|
||||
static final long MASK_HI = (SIZE <= 64) ? 0L : (SIZE >= 128 ? -1L : (1L << (SIZE - 64)) - 1);
|
||||
static final int TARGET_CLUES = SIZE >>> 2;
|
||||
static final int MAX_WORD_LENGTH = C <= R ? C : R;
|
||||
static final int MAX_WORD_LENGTH_PLUS_ONE = MAX_WORD_LENGTH + 1;
|
||||
@@ -249,15 +251,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
long matchLo = (~(lo ^ b.lo)) & (~lo | (~(vlo ^ b.vlo) & ~(rlo ^ b.rlo)));
|
||||
long matchHi = (~(hi ^ b.hi)) & (~hi | (~(vhi ^ b.vhi) & ~(rhi ^ b.rhi)));
|
||||
|
||||
long maskLo = (SIZE >= 64) ? -1L : (1L << SIZE) - 1;
|
||||
long maskHi = (SIZE <= 64) ? 0L : (1L << (SIZE - 64)) - 1;
|
||||
|
||||
return (Long.bitCount(matchLo & maskLo) + Long.bitCount(matchHi & maskHi)) / SIZED;
|
||||
|
||||
|
||||
/* var same = 0;
|
||||
for (int i = 0; i < SIZE; i++) if (digitAt(i) == b.digitAt(i)) same++;
|
||||
return same / SIZED;*/
|
||||
return (Long.bitCount(matchLo & MASK_LO) + Long.bitCount(matchHi & MASK_HI)) / SIZED;
|
||||
}
|
||||
public Grid toGrid() { return new Grid(new byte[SIZE], lo, hi); }
|
||||
public void forEachSlot(SlotVisitor visitor) {
|
||||
@@ -452,49 +446,78 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
long penalty = (((long) Math.abs(grid.clueCount() - TARGET_CLUES)) * 16000L);
|
||||
boolean hasSlots = false;
|
||||
|
||||
for (int i = 0; i < 65; i += 64) {
|
||||
for (long bits = (i == 0 ? lo_cl : hi_cl); bits != X; bits &= bits - 1) {
|
||||
int clueIdx = i | Long.numberOfTrailingZeros(bits);
|
||||
int key = Slot.packSlotDir(clueIdx, grid.digitAt(clueIdx));
|
||||
/// long clueBits = (i == 0 ? lo_cl : hi_cl);
|
||||
/// long vBits = (i == 0 ? grid.vlo : grid.vhi);
|
||||
/// long rBits = (i == 0 ? grid.rlo : grid.rhi);
|
||||
/// for (long bits = clueBits; bits != X; bits &= bits - 1) {
|
||||
/// long lsb = bits & -bits;
|
||||
/// int clueIdx = i | Long.numberOfTrailingZeros(lsb);
|
||||
/// int v = (vBits & lsb) != 0 ? 1 : 0;
|
||||
/// int r = (rBits & lsb) != 0 ? 1 : 0;
|
||||
/// int key = Slot.packSlotDir(clueIdx, (r << 1) | v);
|
||||
long rLo = PATH_LO[key], rHi = PATH_HI[key];
|
||||
long hLo = rLo & lo_cl, hHi = rHi & hi_cl;
|
||||
if (Slot.increasing(key)) {
|
||||
if (hLo != X) {
|
||||
rLo &= ((1L << Long.numberOfTrailingZeros(hLo)) - 1);
|
||||
rHi = 0;
|
||||
} else if (hHi != X) { rHi &= ((1L << Long.numberOfTrailingZeros(hHi)) - 1); }
|
||||
} else {
|
||||
if (hHi != X) {
|
||||
int msb = 63 - Long.numberOfLeadingZeros(hHi);
|
||||
rHi &= ~((1L << msb << 1) - 1);
|
||||
rLo = 0;
|
||||
} else if (hLo != X) {
|
||||
int msb = 63 - Long.numberOfLeadingZeros(hLo);
|
||||
rLo &= ~((1L << msb << 1) - 1);
|
||||
}
|
||||
for (long bits = lo_cl; bits != X; bits &= bits - 1) {
|
||||
long lsb = bits & -bits;
|
||||
int clueIdx = Long.numberOfTrailingZeros(lsb);
|
||||
int v = (grid.vlo & lsb) != 0 ? 1 : 0;
|
||||
int r = (grid.rlo & lsb) != 0 ? 1 : 0;
|
||||
int key = Slot.packSlotDir(clueIdx, (r << 1) | v);
|
||||
long rLo = PATH_LO[key], rHi = PATH_HI[key];
|
||||
long hLo = rLo & lo_cl, hHi = rHi & hi_cl;
|
||||
if (Slot.increasing(key)) {
|
||||
if (hLo != X) {
|
||||
rLo &= ((1L << Long.numberOfTrailingZeros(hLo)) - 1);
|
||||
rHi = 0;
|
||||
} else if (hHi != X) { rHi &= ((1L << Long.numberOfTrailingZeros(hHi)) - 1); }
|
||||
} else {
|
||||
if (hHi != X) {
|
||||
int msb = 63 - Long.numberOfLeadingZeros(hHi);
|
||||
rHi &= ~((1L << msb << 1) - 1);
|
||||
rLo = 0;
|
||||
} else if (hLo != X) {
|
||||
int msb = 63 - Long.numberOfLeadingZeros(hLo);
|
||||
rLo &= ~((1L << msb << 1) - 1);
|
||||
}
|
||||
if ((rLo | rHi) != X) {
|
||||
hasSlots = true;
|
||||
if (Slot.horiz(key)) {
|
||||
cHLo |= rLo;
|
||||
cHHi |= rHi;
|
||||
} else {
|
||||
cVLo |= rLo;
|
||||
cVHi |= rHi;
|
||||
}
|
||||
if ((Long.bitCount(rLo) + Long.bitCount(rHi)) < MIN_LEN) penalty += 8000;
|
||||
}
|
||||
if ((rLo | rHi) != X) {
|
||||
hasSlots = true;
|
||||
if (Slot.horiz(key)) {
|
||||
cHLo |= rLo;
|
||||
cHHi |= rHi;
|
||||
} else {
|
||||
penalty += 25000;
|
||||
cVLo |= rLo;
|
||||
cVHi |= rHi;
|
||||
}
|
||||
if ((Long.bitCount(rLo) + Long.bitCount(rHi)) < MIN_LEN) penalty += 8000;
|
||||
} else {
|
||||
penalty += 25000;
|
||||
}
|
||||
}
|
||||
for (long bits = hi_cl; bits != X; bits &= bits - 1) {
|
||||
long lsb = bits & -bits;
|
||||
int clueIdx = Long.numberOfTrailingZeros(lsb);
|
||||
int v = (grid.vhi & lsb) != 0 ? 1 : 0;
|
||||
int r = (grid.rhi & lsb) != 0 ? 1 : 0;
|
||||
int key = Slot.packSlotDir(64 | clueIdx, (r << 1) | v);
|
||||
long rLo = PATH_LO[key], rHi = PATH_HI[key];
|
||||
long hLo = rLo & lo_cl, hHi = rHi & hi_cl;
|
||||
if (Slot.increasing(key)) {
|
||||
if (hLo != X) {
|
||||
rLo &= ((1L << Long.numberOfTrailingZeros(hLo)) - 1);
|
||||
rHi = 0;
|
||||
} else if (hHi != X) { rHi &= ((1L << Long.numberOfTrailingZeros(hHi)) - 1); }
|
||||
} else {
|
||||
if (hHi != X) {
|
||||
int msb = 63 - Long.numberOfLeadingZeros(hHi);
|
||||
rHi &= ~((1L << msb << 1) - 1);
|
||||
rLo = 0;
|
||||
} else if (hLo != X) {
|
||||
int msb = 63 - Long.numberOfLeadingZeros(hLo);
|
||||
rLo &= ~((1L << msb << 1) - 1);
|
||||
}
|
||||
}
|
||||
if ((rLo | rHi) != X) {
|
||||
hasSlots = true;
|
||||
if (Slot.horiz(key)) {
|
||||
cHLo |= rLo;
|
||||
cHHi |= rHi;
|
||||
} else {
|
||||
cVLo |= rLo;
|
||||
cVHi |= rHi;
|
||||
}
|
||||
if ((Long.bitCount(rLo) + Long.bitCount(rHi)) < MIN_LEN) penalty += 8000;
|
||||
} else {
|
||||
penalty += 25000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,35 +637,21 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
var nc = Math.cos(theta);
|
||||
var nr = Math.sin(theta);
|
||||
|
||||
long maskLo = 0, maskHi = 0;
|
||||
for (var rci : IT) {
|
||||
int i = rci.i();
|
||||
if ((rci.cross_r()) * nc + (rci.cross_c()) * nr < 0) {
|
||||
var ch = other.digitAt(i);
|
||||
if (out.digitAt(i) != ch) {
|
||||
if (other.isClue(i)) {
|
||||
out.setClue(i, ch);
|
||||
} else {
|
||||
out.clearClue(i);
|
||||
}
|
||||
}
|
||||
int i = rci.i();
|
||||
if ((i & 64) == 0) maskLo |= (1L << i);
|
||||
else maskHi |= (1L << (i - 64));
|
||||
}
|
||||
}
|
||||
|
||||
// long maskLo = 0, maskHi = 0;
|
||||
// for (var rci : IT) {
|
||||
// if ((rci.cross_r()) * nc + (rci.cross_c()) * nr < 0) {
|
||||
// int i = rci.i();
|
||||
// if (i < 64) maskLo |= (1L << i);
|
||||
// else maskHi |= (1L << (i - 64));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// out.lo = (out.lo & ~maskLo) | (other.lo & maskLo);
|
||||
// out.hi = (out.hi & ~maskHi) | (other.hi & maskHi);
|
||||
// out.vlo = (out.vlo & ~maskLo) | (other.vlo & maskLo);
|
||||
// out.vhi = (out.vhi & ~maskHi) | (other.vhi & maskHi);
|
||||
// out.rlo = (out.rlo & ~maskLo) | (other.rlo & maskLo);
|
||||
// out.rhi = (out.rhi & ~maskHi) | (other.rhi & maskHi);
|
||||
out.lo = (out.lo & ~maskLo) | (other.lo & maskLo);
|
||||
out.hi = (out.hi & ~maskHi) | (other.hi & maskHi);
|
||||
out.vlo = (out.vlo & ~maskLo) | (other.vlo & maskLo);
|
||||
out.vhi = (out.vhi & ~maskHi) | (other.vhi & maskHi);
|
||||
out.rlo = (out.rlo & ~maskLo) | (other.rlo & maskLo);
|
||||
out.rhi = (out.rhi & ~maskHi) | (other.rhi & maskHi);
|
||||
|
||||
for (var lo = out.lo; lo != X; lo &= lo - 1L) clearClues(out, Long.numberOfTrailingZeros(lo));
|
||||
for (var hi = out.hi; hi != X; hi &= hi - 1L) clearClues(out, 64 | Long.numberOfTrailingZeros(hi));
|
||||
|
||||
@@ -162,14 +162,14 @@ public class MainTest {
|
||||
var mask = swe.generateMask(opts.pop, opts.gens, Math.max(opts.pop, (int) Math.floor(opts.pop * 1.5)));
|
||||
val clued = new Clued(mask);
|
||||
val test = clued.gridToString();
|
||||
val RESULT = " 3 300\n" +
|
||||
" 1 \n" +
|
||||
" 1 \n" +
|
||||
" 3 0 \n" +
|
||||
" 31 \n" +
|
||||
" 1 \n" +
|
||||
" 1 2\n" +
|
||||
"21 22 3";
|
||||
val RESULT = "001 \n" +
|
||||
" 3 3\n" +
|
||||
" 3\n" +
|
||||
" 3\n" +
|
||||
" 21 1 \n" +
|
||||
" 3 \n" +
|
||||
"221 1 \n" +
|
||||
"1 22";
|
||||
|
||||
Assertions.assertEquals(18, clued.clueCount(), "Found seed changed");
|
||||
Assertions.assertEquals(RESULT, test, "Found seed changed");
|
||||
|
||||
Reference in New Issue
Block a user