introduce bitloops

This commit is contained in:
mike
2026-01-17 18:39:19 +01:00
parent 9367833407
commit 8ff9d661e3
5 changed files with 81 additions and 96 deletions

View File

@@ -31,7 +31,7 @@ import static java.nio.charset.StandardCharsets.US_ASCII;
* java SwedishGenerator [--seed N] [--pop N] [--gens N] [--tries N] [--words word-list.txt]
*/
@SuppressWarnings("ALL")
public class SwedishGenerator {
public record SwedishGenerator() {
public static final long GT_1_OFFSET_53_BIT = 0x3E00000000000000L;
public static final long X = 0L;
@@ -160,8 +160,9 @@ public class SwedishGenerator {
for (int i = 0, bi = 0; i < len * 5; bi++, i += 5) b[bi] = (byte) (((word >>> i) & 31) | 64);
return new String(b, 0, 0, len);
}
static int unpackIndex(long w) { return (int) (w >>> 40); }
static int unpackLetters(long w) { return (int) (w & LETTER_MASK); }
static int unpackIndex(long w) { return (int) (w >>> 40); }
static int unpackShardIndex(long w) { return (int) (w >>> 43); }
static int unpackLetters(long w) { return (int) (w & LETTER_MASK); }
}
public static record Dict(DictEntry[] index, int length) { }
@@ -284,35 +285,36 @@ public class SwedishGenerator {
System.out.print("\r" + padRight(msg, 120));
System.out.flush();
}
boolean placeWord(final int key, final long lo, final long hi, final long w) {
boolean placeWordDec(final long lo, final long hi, final long w) {
int idx;
if (Slotinfo.increasing(key)) {
for (long b = lo & glo; b != X; b &= b - 1) if (g[idx = numberOfTrailingZeros(b)] != Lemma.byteAt(w, bitCount(lo & ((1L << idx) - 1)))) return false;
int bcLo = bitCount(lo);
for (long b = hi & ghi; b != X; b &= b - 1)
if (g[64 | (idx = numberOfTrailingZeros(b))] != Lemma.byteAt(w, bcLo + bitCount(hi & ((1L << idx) - 1)))) return false;
long maskLo = lo & ~glo, maskHi = hi & ~ghi;
if ((maskLo | maskHi) != X) {
for (long b = maskLo; b != X; b &= b - 1) g[idx = idx = numberOfTrailingZeros(b)] = Lemma.byteAt(w, bitCount(lo & ((1L << idx) - 1)));
for (long b = maskHi; b != X; b &= b - 1) g[64 | (idx = numberOfTrailingZeros(b))] = Lemma.byteAt(w, bcLo + bitCount(hi & ((1L << idx) - 1)));
glo |= maskLo;
ghi |= maskHi;
}
} else {
int bcHi = bitCount(hi);
for (long b = hi & ghi; b != X; b &= b - 1)
if (g[64 | (idx = numberOfTrailingZeros(b))] != Lemma.byteAt(w, bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))))) return false;
for (long b = lo & glo; b != X; b &= b - 1)
if (g[idx = numberOfTrailingZeros(b)] != Lemma.byteAt(w, bcHi + bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))))) return false;
long maskLo = lo & ~glo, maskHi = hi & ~ghi;
if ((maskLo | maskHi) != X) {
for (long b = maskHi; b != X; b &= b - 1) g[64 | (idx = numberOfTrailingZeros(b))] = Lemma.byteAt(w, bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))));
for (long b = maskLo; b != X; b &= b - 1) g[idx = numberOfTrailingZeros(b)] = Lemma.byteAt(w, bcHi + bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))));
glo |= maskLo;
ghi |= maskHi;
}
int bcHi = bitCount(hi);
for (long b = hi & ghi; b != X; b &= b - 1)
if (g[64 | (idx = numberOfTrailingZeros(b))] != Lemma.byteAt(w, bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))))) return false;
for (long b = lo & glo; b != X; b &= b - 1)
if (g[idx = numberOfTrailingZeros(b)] != Lemma.byteAt(w, bcHi + bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))))) return false;
long maskLo = lo & ~glo, maskHi = hi & ~ghi;
if ((maskLo | maskHi) != X) {
for (long b = maskHi; b != X; b &= b - 1) g[64 | (idx = numberOfTrailingZeros(b))] = Lemma.byteAt(w, bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))));
for (long b = maskLo; b != X; b &= b - 1) g[idx = numberOfTrailingZeros(b)] = Lemma.byteAt(w, bcHi + bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))));
glo |= maskLo;
ghi |= maskHi;
}
return true;
}
boolean placeWordInc(final long lo, final long hi, final long w) {
int idx;
for (long b = lo & glo; b != X; b &= b - 1) if (g[idx = numberOfTrailingZeros(b)] != Lemma.byteAt(w, bitCount(lo & ((1L << idx) - 1)))) return false;
int bcLo = bitCount(lo);
for (long b = hi & ghi; b != X; b &= b - 1)
if (g[64 | (idx = numberOfTrailingZeros(b))] != Lemma.byteAt(w, bcLo + bitCount(hi & ((1L << idx) - 1)))) return false;
long maskLo = lo & ~glo, maskHi = hi & ~ghi;
if ((maskLo | maskHi) != X) {
for (long b = maskLo; b != X; b &= b - 1) g[idx = idx = numberOfTrailingZeros(b)] = Lemma.byteAt(w, bitCount(lo & ((1L << idx) - 1)));
for (long b = maskHi; b != X; b &= b - 1) g[64 | (idx = numberOfTrailingZeros(b))] = Lemma.byteAt(w, bcLo + bitCount(hi & ((1L << idx) - 1)));
glo |= maskLo;
ghi |= maskHi;
}
return true;
}
@@ -345,21 +347,15 @@ public class SwedishGenerator {
}
var pattern = patternForSlot(glo, ghi, g, best.key, best.lo, best.hi);
var index = best.entry;
current = CARRIER;
current.slot = best;
current.count = index.length;
if (pattern == X) {
current.indices = null;
return;
}
current.indices = candidateInfoForPattern(bitset, pattern, index.posBitsets, index.numlong);
current = CARRIER;
current.slot = best;
current.count = index.length;
current.indices = pattern == X ? null : candidateInfoForPattern(bitset, pattern, index.posBitsets, index.numlong);
}
boolean backtrack(int depth) {
if (Thread.currentThread().isInterrupted()) return false;
if (Thread.currentThread().isInterrupted() || (System.currentTimeMillis() - t0) > 20_000) return false;
nodes++;
if (20_000 > 0 && (System.currentTimeMillis() - t0) > 20_000) return false;
chooseMRV();
var pick = current;
if (pick == PICK_DONE) return true;
@@ -372,7 +368,7 @@ public class SwedishGenerator {
if (!NO_LOG) renderProgress();
val s = pick.slot;
val k = s.key;
val inc = Slotinfo.increasing(s.key);
val slo = s.lo;
val shi = s.hi;
val entry = s.entry;
@@ -392,10 +388,14 @@ public class SwedishGenerator {
if (Bit1029.get(used, lemIdx)) continue;
low = glo;
top = ghi;
if (!placeWord(k, slo, shi, w)) continue;
if (inc) {
if (!placeWordInc(slo, shi, w)) continue;
} else {
if (!placeWordDec(slo, shi, w)) continue;
}
Bit1029.set(used, lemIdx);
s.assign.w = w;
s.assign.w = w;
if (backtrack(depth + 1)) return true;
s.assign.w = X;
Bit1029.clear(used, lemIdx);
@@ -417,10 +417,14 @@ public class SwedishGenerator {
if (Bit1029.get(used, lemIdx)) continue;
low = glo;
top = ghi;
if (!placeWord(k, slo, shi, w)) continue;
if (inc) {
if (!placeWordInc(slo, shi, w)) continue;
} else {
if (!placeWordDec(slo, shi, w)) continue;
}
Bit1029.set(used, lemIdx);
s.assign.w = w;
s.assign.w = w;
if (backtrack(depth + 1)) return true;
s.assign.w = X;
Bit1029.clear(used, lemIdx);