introduce bitloops

This commit is contained in:
mike
2026-01-14 12:45:08 +01:00
parent dfb4679da8
commit ecf4ae913e

View File

@@ -129,7 +129,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
if (ok) { if (ok) {
int k = 0; int k = 0;
for (var n = 1; n < clueMap.length; n++) { for (var n = 1; n < clueMap.length; n++) {
if (clueMap[n] != 0L) { if (clueMap[n] != X) {
k++; k++;
stats.simplicity += Lemma.simpel(clueMap[n]); stats.simplicity += Lemma.simpel(clueMap[n]);
} }
@@ -140,7 +140,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
public int wordCount() { public int wordCount() {
int k = 0; int k = 0;
for (var n = 1; n < clueMap.length; n++) { for (var n = 1; n < clueMap.length; n++) {
if (clueMap[n] != 0L) { if (clueMap[n] != X) {
k++; k++;
} }
} }
@@ -422,12 +422,12 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
} }
} else { } else {
// first clue is highest index among hits (hi first, then lo) // first clue is highest index among hits (hi first, then lo)
if (hitsHi != 0) { if (hitsHi != X) {
int msb = 63 - Long.numberOfLeadingZeros(hitsHi); int msb = 63 - Long.numberOfLeadingZeros(hitsHi);
long stop = 1L << msb; long stop = 1L << msb;
rayHi &= ~((stop << 1) - 1); // keep bits > stop rayHi &= ~((stop << 1) - 1); // keep bits > stop
rayLo = 0; // lo indices are below stop rayLo = 0; // lo indices are below stop
} else if (hitsLo != 0) { } else if (hitsLo != X) {
int msb = 63 - Long.numberOfLeadingZeros(hitsLo); int msb = 63 - Long.numberOfLeadingZeros(hitsLo);
long stop = 1L << msb; long stop = 1L << msb;
rayLo &= ~((stop << 1) - 1); rayLo &= ~((stop << 1) - 1);
@@ -468,21 +468,21 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
long rLo = PATH_LO[key], rHi = PATH_HI[key]; long rLo = PATH_LO[key], rHi = PATH_HI[key];
long hLo = rLo & lo_cl, hHi = rHi & hi_cl; long hLo = rLo & lo_cl, hHi = rHi & hi_cl;
if (Slot.increasing(key)) { if (Slot.increasing(key)) {
if (hLo != 0) { if (hLo != X) {
rLo &= ((1L << Long.numberOfTrailingZeros(hLo)) - 1); rLo &= ((1L << Long.numberOfTrailingZeros(hLo)) - 1);
rHi = 0; rHi = 0;
} else if (hHi != 0) { rHi &= ((1L << Long.numberOfTrailingZeros(hHi)) - 1); } } else if (hHi != 0) { rHi &= ((1L << Long.numberOfTrailingZeros(hHi)) - 1); }
} else { } else {
if (hHi != 0) { if (hHi != X) {
int msb = 63 - Long.numberOfLeadingZeros(hHi); int msb = 63 - Long.numberOfLeadingZeros(hHi);
rHi &= ~((1L << msb << 1) - 1); rHi &= ~((1L << msb << 1) - 1);
rLo = 0; rLo = 0;
} else if (hLo != 0) { } else if (hLo != X) {
int msb = 63 - Long.numberOfLeadingZeros(hLo); int msb = 63 - Long.numberOfLeadingZeros(hLo);
rLo &= ~((1L << msb << 1) - 1); rLo &= ~((1L << msb << 1) - 1);
} }
} }
if ((rLo | rHi) != 0L) { if ((rLo | rHi) != X) {
hasSlots = true; hasSlots = true;
if (Slot.horiz(key)) { if (Slot.horiz(key)) {
cHLo |= rLo; cHLo |= rLo;
@@ -499,7 +499,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
} }
if (!hasSlots) return 1_000_000_000L; if (!hasSlots) return 1_000_000_000L;
long seenLo = 0L, seenHi = 0L; long seenLo = X, seenHi = X;
// loop over beide helften // loop over beide helften
for (int base = 0; base <= 64; base += 64) { for (int base = 0; base <= 64; base += 64) {
@@ -507,7 +507,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
long seenMask = (base == 0) ? seenLo : seenHi; long seenMask = (base == 0) ? seenLo : seenHi;
// "unseen clues" in deze helft // "unseen clues" in deze helft
for (long bits = clueMask & ~seenMask; bits != 0L; bits &= bits - 1) { for (long bits = clueMask & ~seenMask; bits != X; bits &= bits - 1) {
int clueIdx = base | Long.numberOfTrailingZeros(bits); int clueIdx = base | Long.numberOfTrailingZeros(bits);
// start nieuwe component // start nieuwe component
@@ -533,7 +533,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
nHi &= hi_cl & ~seenHi; nHi &= hi_cl & ~seenHi;
// push lo-neighbors // push lo-neighbors
while (nLo != 0L) { while (nLo != X) {
long lsb = nLo & -nLo; long lsb = nLo & -nLo;
int nidx = Long.numberOfTrailingZeros(nLo); // 0..63 int nidx = Long.numberOfTrailingZeros(nLo); // 0..63
seenLo |= lsb; seenLo |= lsb;
@@ -544,7 +544,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
} }
// push hi-neighbors // push hi-neighbors
while (nHi != 0L) { while (nHi != X) {
long lsb = nHi & -nHi; long lsb = nHi & -nHi;
int nidx = 64 | Long.numberOfTrailingZeros(nHi); // 64..127 int nidx = 64 | Long.numberOfTrailingZeros(nHi); // 64..127
seenHi |= lsb; seenHi |= lsb;
@@ -728,19 +728,19 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
static long patternForSlot(Grid grid, final int key, final long lo, final long hi) { static long patternForSlot(Grid grid, final int key, final long lo, final long hi) {
final long glo = grid.lo, ghi = grid.hi; final long glo = grid.lo, ghi = grid.hi;
if ((lo & glo) == 0 && (hi & ghi) == 0) { if ((lo & glo) == X && (hi & ghi) == X) {
return 0; return 0;
} }
long p = 0; long p = 0;
if (Slot.increasing(key)) { if (Slot.increasing(key)) {
for (long b = lo & glo; b != 0; b &= b - 1) { for (long b = lo & glo; b != X; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b); int idx = Long.numberOfTrailingZeros(b);
byte val = grid.g[idx]; byte val = grid.g[idx];
int i = Long.bitCount(lo & ((1L << idx) - 1)); int i = Long.bitCount(lo & ((1L << idx) - 1));
p |= ((long) (i * 26 + val)) << (i << 3); p |= ((long) (i * 26 + val)) << (i << 3);
} }
int offset = Long.bitCount(lo); int offset = Long.bitCount(lo);
for (long b = hi & ghi; b != 0; b &= b - 1) { for (long b = hi & ghi; b != X; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b); int idx = Long.numberOfTrailingZeros(b);
byte val = grid.g[64 | idx]; byte val = grid.g[64 | idx];
int i = offset + Long.bitCount(hi & ((1L << idx) - 1)); int i = offset + Long.bitCount(hi & ((1L << idx) - 1));
@@ -748,13 +748,13 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
} }
} else { } else {
int offset = Long.bitCount(hi); int offset = Long.bitCount(hi);
for (long b = hi & ghi; b != 0; b &= b - 1) { for (long b = hi & ghi; b != X; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b); int idx = Long.numberOfTrailingZeros(b);
byte val = grid.g[64 | idx]; byte val = grid.g[64 | idx];
int i = Long.bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))); int i = Long.bitCount(hi & ~((1L << idx) | ((1L << idx) - 1)));
p |= ((long) (i * 26 + val)) << (i << 3); p |= ((long) (i * 26 + val)) << (i << 3);
} }
for (long b = lo & glo; b != 0; b &= b - 1) { for (long b = lo & glo; b != X; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b); int idx = Long.numberOfTrailingZeros(b);
byte val = grid.g[idx]; byte val = grid.g[idx];
int i = offset + Long.bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))); int i = offset + Long.bitCount(lo & ~((1L << idx) | ((1L << idx) - 1)));
@@ -765,8 +765,8 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
} }
static int slotScore(byte[] count, long lo, long hi) { static int slotScore(byte[] count, long lo, long hi) {
int cross = 0; int cross = 0;
for (long b = lo; b != 0; b &= b - 1) cross += (count[Long.numberOfTrailingZeros(b)] - 1); for (long b = lo; b != X; b &= b - 1) cross += (count[Long.numberOfTrailingZeros(b)] - 1);
for (long b = hi; b != 0; b &= b - 1) cross += (count[64 | Long.numberOfTrailingZeros(b)] - 1); for (long b = hi; b != X; b &= b - 1) cross += (count[64 | Long.numberOfTrailingZeros(b)] - 1);
return cross * 10 + Slot.length(lo, hi); return cross * 10 + Slot.length(lo, hi);
} }
static boolean placeWord(Grid grid, final int key, final long lo, final long hi, final long w) { static boolean placeWord(Grid grid, final int key, final long lo, final long hi, final long w) {
@@ -777,18 +777,18 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
if (grid.g[idx] != Lemma.byteAt(w, Long.bitCount(lo & ((1L << idx) - 1)))) return false; if (grid.g[idx] != Lemma.byteAt(w, Long.bitCount(lo & ((1L << idx) - 1)))) return false;
} }
int bcLo = Long.bitCount(lo); int bcLo = Long.bitCount(lo);
for (long b = hi & ghi; b != 0; b &= b - 1) { for (long b = hi & ghi; b != X; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b); int idx = Long.numberOfTrailingZeros(b);
if (grid.g[64 | idx] != Lemma.byteAt(w, bcLo + Long.bitCount(hi & ((1L << idx) - 1)))) return false; if (grid.g[64 | idx] != Lemma.byteAt(w, bcLo + Long.bitCount(hi & ((1L << idx) - 1)))) return false;
} }
long maskLo = lo & ~glo, maskHi = hi & ~ghi; long maskLo = lo & ~glo, maskHi = hi & ~ghi;
if ((maskLo | maskHi) != 0) { if ((maskLo | maskHi) != X) {
for (long b = maskLo; b != 0; b &= b - 1) { for (long b = maskLo; b != X; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b); int idx = Long.numberOfTrailingZeros(b);
grid.g[idx] = Lemma.byteAt(w, Long.bitCount(lo & ((1L << idx) - 1))); grid.g[idx] = Lemma.byteAt(w, Long.bitCount(lo & ((1L << idx) - 1)));
} }
for (long b = maskHi; b != 0; b &= b - 1) { for (long b = maskHi; b != X; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b); int idx = Long.numberOfTrailingZeros(b);
grid.g[64 | idx] = Lemma.byteAt(w, bcLo + Long.bitCount(hi & ((1L << idx) - 1))); grid.g[64 | idx] = Lemma.byteAt(w, bcLo + Long.bitCount(hi & ((1L << idx) - 1)));
} }
@@ -797,22 +797,22 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
} }
} else { } else {
int bcHi = Long.bitCount(hi); int bcHi = Long.bitCount(hi);
for (long b = hi & ghi; b != 0; b &= b - 1) { for (long b = hi & ghi; b != X; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b); int idx = Long.numberOfTrailingZeros(b);
if (grid.g[64 | idx] != Lemma.byteAt(w, Long.bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))))) return false; if (grid.g[64 | idx] != Lemma.byteAt(w, Long.bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))))) return false;
} }
for (long b = lo & glo; b != 0; b &= b - 1) { for (long b = lo & glo; b != X; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b); int idx = Long.numberOfTrailingZeros(b);
if (grid.g[idx] != Lemma.byteAt(w, bcHi + Long.bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))))) return false; if (grid.g[idx] != Lemma.byteAt(w, bcHi + Long.bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))))) return false;
} }
long maskLo = lo & ~glo, maskHi = hi & ~ghi; long maskLo = lo & ~glo, maskHi = hi & ~ghi;
if ((maskLo | maskHi) != 0) { if ((maskLo | maskHi) != X) {
for (long b = maskHi; b != 0; b &= b - 1) { for (long b = maskHi; b != 0; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b); int idx = Long.numberOfTrailingZeros(b);
grid.g[64 | idx] = Lemma.byteAt(w, Long.bitCount(hi & ~((1L << idx) | ((1L << idx) - 1)))); grid.g[64 | idx] = Lemma.byteAt(w, Long.bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))));
} }
for (long b = maskLo; b != 0; b &= b - 1) { for (long b = maskLo; b != X; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b); int idx = Long.numberOfTrailingZeros(b);
grid.g[idx] = Lemma.byteAt(w, bcHi + Long.bitCount(lo & ~((1L << idx) | ((1L << idx) - 1)))); grid.g[idx] = Lemma.byteAt(w, bcHi + Long.bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))));
} }
@@ -826,7 +826,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
static int[] candidateInfoForPattern(long[] res, long pattern, long[][] posBitsets, int numLongs) { static int[] candidateInfoForPattern(long[] res, long pattern, long[][] posBitsets, int numLongs) {
boolean first = true; boolean first = true;
for (long p = pattern; p != 0; ) { for (long p = pattern; p != X; ) {
int combined = (int) (p & 0xFF); int combined = (int) (p & 0xFF);
if (combined != 0) { if (combined != 0) {
long[] bs = posBitsets[combined - 1]; long[] bs = posBitsets[combined - 1];
@@ -849,7 +849,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
int ki = 0; int ki = 0;
for (int k = 0; k < numLongs; k++) { for (int k = 0; k < numLongs; k++) {
long w = res[k]; long w = res[k];
while (w != 0) { while (w != X) {
int t = Long.numberOfTrailingZeros(w); int t = Long.numberOfTrailingZeros(w);
indices[ki++] = (k << 6) | t; indices[ki++] = (k << 6) | t;
w &= w - 1; w &= w - 1;
@@ -862,7 +862,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
static int candidateCountForPattern(final long[] res, final long pattern, final long[][] posBitsets, final int numLongs) { static int candidateCountForPattern(final long[] res, final long pattern, final long[][] posBitsets, final int numLongs) {
boolean first = true; boolean first = true;
for (long p = pattern; p != 0; ) { for (long p = pattern; p != X; ) {
int combined = (int) (p & 0xFF); int combined = (int) (p & 0xFF);
if (combined != 0) { if (combined != 0) {
long[] bs = posBitsets[combined - 1]; long[] bs = posBitsets[combined - 1];
@@ -886,8 +886,8 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
static void scoreSlots(int[] slotScores, Slot[] slots) { static void scoreSlots(int[] slotScores, Slot[] slots) {
val count = new byte[SIZE]; val count = new byte[SIZE];
for (var s : slots) { for (var s : slots) {
for (long b = s.lo; b != 0; b &= b - 1) count[Long.numberOfTrailingZeros(b)]++; for (long b = s.lo; b != X; b &= b - 1) count[Long.numberOfTrailingZeros(b)]++;
for (long b = s.hi; b != 0; b &= b - 1) count[64 | Long.numberOfTrailingZeros(b)]++; for (long b = s.hi; b != X; b &= b - 1) count[64 | Long.numberOfTrailingZeros(b)]++;
} }
for (int i = 0; i < slots.length; i++) { for (int i = 0; i < slots.length; i++) {
var slot = slots[i]; var slot = slots[i];