introduce bitloops
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user