introduce bitloops

This commit is contained in:
mike
2026-01-14 10:24:55 +01:00
parent 69af69a8b8
commit cb2935e0f5

View File

@@ -789,61 +789,59 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
return cross * 10 + s.length();
}
static boolean placeWord(Grid grid, Slot s, long w, long[] undoBuffer, int offset) {
long maskLo = 0, maskHi = 0;
int i = 0;
if (s.increasing()) {
for (long b = s.lo; b != 0; b &= b - 1, i++) {
int idx = Long.numberOfTrailingZeros(b);
byte cur = grid.letter32At(idx), ch = Lemma.byteAt(w, i);
if (cur == DASH) {
maskLo |= (1L << idx);
grid.setLetterLo(idx, ch);
} else if (cur != ch) {
grid.undoPlace(maskLo, maskHi);
return false;
}
for (long b = s.lo & grid.lo; b != 0; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b);
if (grid.g[idx] != Lemma.byteAt(w, Long.bitCount(s.lo & ((1L << idx) - 1)))) return false;
}
for (long b = s.hi; b != 0; b &= b - 1, i++) {
int idx = 64 | Long.numberOfTrailingZeros(b);
byte cur = grid.letter32At(idx), ch = Lemma.byteAt(w, i);
if (cur == DASH) {
maskHi |= (1L << (idx & 63));
grid.setLetterHi(idx, ch);
} else if (cur != ch) {
grid.undoPlace(maskLo, maskHi);
return false;
}
int bcLo = Long.bitCount(s.lo);
for (long b = s.hi & grid.hi; b != 0; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b);
if (grid.g[64 | idx] != Lemma.byteAt(w, bcLo + Long.bitCount(s.hi & ((1L << idx) - 1)))) return false;
}
long maskLo = s.lo & ~grid.lo, maskHi = s.hi & ~grid.hi;
if ((maskLo | maskHi) != 0) {
for (long b = maskLo; b != 0; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b);
grid.g[idx] = Lemma.byteAt(w, Long.bitCount(s.lo & ((1L << idx) - 1)));
}
for (long b = maskHi; b != 0; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b);
grid.g[64 | idx] = Lemma.byteAt(w, bcLo + Long.bitCount(s.hi & ((1L << idx) - 1)));
}
grid.lo |= maskLo;
grid.hi |= maskHi;
}
undoBuffer[offset << 1] = maskLo;
undoBuffer[(offset << 1) | 1] = maskHi;
} else {
for (long b = s.hi; b != 0; i++) {
int msb = 63 - Long.numberOfLeadingZeros(b);
int idx = 64 | msb;
byte cur = grid.letter32At(idx), ch = Lemma.byteAt(w, i);
if (cur == DASH) {
maskHi |= (1L << msb);
grid.setLetterHi(idx, ch);
} else if (cur != ch) {
grid.undoPlace(maskLo, maskHi);
return false;
}
b &= ~(1L << msb);
int bcHi = Long.bitCount(s.hi);
for (long b = s.hi & grid.hi; b != 0; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b);
if (grid.g[64 | idx] != Lemma.byteAt(w, Long.bitCount(s.hi & ~((1L << idx) | ((1L << idx) - 1))))) return false;
}
for (long b = s.lo; b != 0; i++) {
int msb = 63 - Long.numberOfLeadingZeros(b);
int idx = msb;
byte cur = grid.letter32At(idx), ch = Lemma.byteAt(w, i);
if (cur == DASH) {
maskLo |= (1L << msb);
grid.setLetterLo(idx, ch);
} else if (cur != ch) {
grid.undoPlace(maskLo, maskHi);
return false;
}
b &= ~(1L << msb);
for (long b = s.lo & grid.lo; b != 0; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b);
if (grid.g[idx] != Lemma.byteAt(w, bcHi + Long.bitCount(s.lo & ~((1L << idx) | ((1L << idx) - 1))))) return false;
}
long maskLo = s.lo & ~grid.lo, maskHi = s.hi & ~grid.hi;
if ((maskLo | maskHi) != 0) {
for (long b = maskHi; b != 0; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b);
grid.g[64 | idx] = Lemma.byteAt(w, Long.bitCount(s.hi & ~((1L << idx) | ((1L << idx) - 1))));
}
for (long b = maskLo; b != 0; b &= b - 1) {
int idx = Long.numberOfTrailingZeros(b);
grid.g[idx] = Lemma.byteAt(w, bcHi + Long.bitCount(s.lo & ~((1L << idx) | ((1L << idx) - 1))));
}
grid.lo |= maskLo;
grid.hi |= maskHi;
}
undoBuffer[offset << 1] = maskLo;
undoBuffer[(offset << 1) | 1] = maskHi;
}
undoBuffer[offset << 1] = maskLo;
undoBuffer[(offset << 1) | 1] = maskHi;
return true;
}