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 = C * R;// ~18
|
||||||
static final int SIZE_MIN_1 = SIZE - 1;// ~18
|
static final int SIZE_MIN_1 = SIZE - 1;// ~18
|
||||||
static final double SIZED = (double) SIZE;// ~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 TARGET_CLUES = SIZE >>> 2;
|
||||||
static final int MAX_WORD_LENGTH = C <= R ? C : R;
|
static final int MAX_WORD_LENGTH = C <= R ? C : R;
|
||||||
static final int MAX_WORD_LENGTH_PLUS_ONE = MAX_WORD_LENGTH + 1;
|
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 matchLo = (~(lo ^ b.lo)) & (~lo | (~(vlo ^ b.vlo) & ~(rlo ^ b.rlo)));
|
||||||
long matchHi = (~(hi ^ b.hi)) & (~hi | (~(vhi ^ b.vhi) & ~(rhi ^ b.rhi)));
|
long matchHi = (~(hi ^ b.hi)) & (~hi | (~(vhi ^ b.vhi) & ~(rhi ^ b.rhi)));
|
||||||
|
|
||||||
long maskLo = (SIZE >= 64) ? -1L : (1L << SIZE) - 1;
|
return (Long.bitCount(matchLo & MASK_LO) + Long.bitCount(matchHi & MASK_HI)) / SIZED;
|
||||||
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;*/
|
|
||||||
}
|
}
|
||||||
public Grid toGrid() { return new Grid(new byte[SIZE], lo, hi); }
|
public Grid toGrid() { return new Grid(new byte[SIZE], lo, hi); }
|
||||||
public void forEachSlot(SlotVisitor visitor) {
|
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);
|
long penalty = (((long) Math.abs(grid.clueCount() - TARGET_CLUES)) * 16000L);
|
||||||
boolean hasSlots = false;
|
boolean hasSlots = false;
|
||||||
|
|
||||||
for (int i = 0; i < 65; i += 64) {
|
for (long bits = lo_cl; bits != X; bits &= bits - 1) {
|
||||||
for (long bits = (i == 0 ? lo_cl : hi_cl); bits != X; bits &= bits - 1) {
|
long lsb = bits & -bits;
|
||||||
int clueIdx = i | Long.numberOfTrailingZeros(bits);
|
int clueIdx = Long.numberOfTrailingZeros(lsb);
|
||||||
int key = Slot.packSlotDir(clueIdx, grid.digitAt(clueIdx));
|
int v = (grid.vlo & lsb) != 0 ? 1 : 0;
|
||||||
/// long clueBits = (i == 0 ? lo_cl : hi_cl);
|
int r = (grid.rlo & lsb) != 0 ? 1 : 0;
|
||||||
/// long vBits = (i == 0 ? grid.vlo : grid.vhi);
|
int key = Slot.packSlotDir(clueIdx, (r << 1) | v);
|
||||||
/// long rBits = (i == 0 ? grid.rlo : grid.rhi);
|
long rLo = PATH_LO[key], rHi = PATH_HI[key];
|
||||||
/// for (long bits = clueBits; bits != X; bits &= bits - 1) {
|
long hLo = rLo & lo_cl, hHi = rHi & hi_cl;
|
||||||
/// long lsb = bits & -bits;
|
if (Slot.increasing(key)) {
|
||||||
/// int clueIdx = i | Long.numberOfTrailingZeros(lsb);
|
if (hLo != X) {
|
||||||
/// int v = (vBits & lsb) != 0 ? 1 : 0;
|
rLo &= ((1L << Long.numberOfTrailingZeros(hLo)) - 1);
|
||||||
/// int r = (rBits & lsb) != 0 ? 1 : 0;
|
rHi = 0;
|
||||||
/// int key = Slot.packSlotDir(clueIdx, (r << 1) | v);
|
} else if (hHi != X) { rHi &= ((1L << Long.numberOfTrailingZeros(hHi)) - 1); }
|
||||||
long rLo = PATH_LO[key], rHi = PATH_HI[key];
|
} else {
|
||||||
long hLo = rLo & lo_cl, hHi = rHi & hi_cl;
|
if (hHi != X) {
|
||||||
if (Slot.increasing(key)) {
|
int msb = 63 - Long.numberOfLeadingZeros(hHi);
|
||||||
if (hLo != X) {
|
rHi &= ~((1L << msb << 1) - 1);
|
||||||
rLo &= ((1L << Long.numberOfTrailingZeros(hLo)) - 1);
|
rLo = 0;
|
||||||
rHi = 0;
|
} else if (hLo != X) {
|
||||||
} else if (hHi != X) { rHi &= ((1L << Long.numberOfTrailingZeros(hHi)) - 1); }
|
int msb = 63 - Long.numberOfLeadingZeros(hLo);
|
||||||
} else {
|
rLo &= ~((1L << msb << 1) - 1);
|
||||||
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 ((rLo | rHi) != X) {
|
||||||
if (Slot.horiz(key)) {
|
hasSlots = true;
|
||||||
cHLo |= rLo;
|
if (Slot.horiz(key)) {
|
||||||
cHHi |= rHi;
|
cHLo |= rLo;
|
||||||
} else {
|
cHHi |= rHi;
|
||||||
cVLo |= rLo;
|
|
||||||
cVHi |= rHi;
|
|
||||||
}
|
|
||||||
if ((Long.bitCount(rLo) + Long.bitCount(rHi)) < MIN_LEN) penalty += 8000;
|
|
||||||
} else {
|
} 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 nc = Math.cos(theta);
|
||||||
var nr = Math.sin(theta);
|
var nr = Math.sin(theta);
|
||||||
|
|
||||||
|
long maskLo = 0, maskHi = 0;
|
||||||
for (var rci : IT) {
|
for (var rci : IT) {
|
||||||
int i = rci.i();
|
|
||||||
if ((rci.cross_r()) * nc + (rci.cross_c()) * nr < 0) {
|
if ((rci.cross_r()) * nc + (rci.cross_c()) * nr < 0) {
|
||||||
var ch = other.digitAt(i);
|
int i = rci.i();
|
||||||
if (out.digitAt(i) != ch) {
|
if ((i & 64) == 0) maskLo |= (1L << i);
|
||||||
if (other.isClue(i)) {
|
else maskHi |= (1L << (i - 64));
|
||||||
out.setClue(i, ch);
|
|
||||||
} else {
|
|
||||||
out.clearClue(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// long maskLo = 0, maskHi = 0;
|
out.lo = (out.lo & ~maskLo) | (other.lo & maskLo);
|
||||||
// for (var rci : IT) {
|
out.hi = (out.hi & ~maskHi) | (other.hi & maskHi);
|
||||||
// if ((rci.cross_r()) * nc + (rci.cross_c()) * nr < 0) {
|
out.vlo = (out.vlo & ~maskLo) | (other.vlo & maskLo);
|
||||||
// int i = rci.i();
|
out.vhi = (out.vhi & ~maskHi) | (other.vhi & maskHi);
|
||||||
// if (i < 64) maskLo |= (1L << i);
|
out.rlo = (out.rlo & ~maskLo) | (other.rlo & maskLo);
|
||||||
// else maskHi |= (1L << (i - 64));
|
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 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));
|
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)));
|
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 clued = new Clued(mask);
|
||||||
val test = clued.gridToString();
|
val test = clued.gridToString();
|
||||||
val RESULT = " 3 300\n" +
|
val RESULT = "001 \n" +
|
||||||
" 1 \n" +
|
" 3 3\n" +
|
||||||
" 1 \n" +
|
" 3\n" +
|
||||||
" 3 0 \n" +
|
" 3\n" +
|
||||||
" 31 \n" +
|
" 21 1 \n" +
|
||||||
" 1 \n" +
|
" 3 \n" +
|
||||||
" 1 2\n" +
|
"221 1 \n" +
|
||||||
"21 22 3";
|
"1 22";
|
||||||
|
|
||||||
Assertions.assertEquals(18, clued.clueCount(), "Found seed changed");
|
Assertions.assertEquals(18, clued.clueCount(), "Found seed changed");
|
||||||
Assertions.assertEquals(RESULT, test, "Found seed changed");
|
Assertions.assertEquals(RESULT, test, "Found seed changed");
|
||||||
|
|||||||
Reference in New Issue
Block a user