introduce bitloops

This commit is contained in:
mike
2026-01-17 04:57:42 +01:00
parent 3bd7a0f958
commit 0c56fafeaa
7 changed files with 128 additions and 110 deletions

View File

@@ -91,25 +91,11 @@ public class SwedishGenerator {
@Accessors(fluent = true)
public static final class FillStats {
final public double seconds;
final public int lastMRV;
public double simplicity;
public double simplicity;
}
public static record FillResult(boolean ok, long nodes, long backtracks, @Delegate FillStats stats) {
public static record FillResult(boolean ok, long nodes, long backtracks, int lastMRV, long elapsed, @Delegate FillStats stats) {
static public long calcSimpel(Slotinfo[] slots) {
int k = 0;
long simpel = 0L;
for (var n = 1; n < slots.length; n++) {
if (slots[n].assign.w != X) {
k++;
simpel += Lemma.simpel(slots[n].assign.w);
}
}
simpel = k == 0 ? 0 : simpel / k;
return simpel;
}
}
public static final class Rng {
@@ -161,8 +147,6 @@ public class SwedishGenerator {
}
static public long from(int index, String word) { return pack(index, word.getBytes(US_ASCII)); }
static byte byteAt(long word, int idx) { return (byte) ((word >>> (idx * 5)) & 0b11111); }
static String[] clue(long w) { return CsvIndexService.clues(unpackIndex(w)); }
static int simpel(long w) { return CsvIndexService.simpel(unpackIndex(w)); }
static int length(long word) { return ((63 - numberOfLeadingZeros(word & LETTER_MASK)) / 5) + 1; }
static ThreadLocal<byte[]> BYTES = ThreadLocal.withInitial(() -> new byte[MAX_WORD_LENGTH]);
public static String asWord(long word) {
@@ -225,59 +209,6 @@ public class SwedishGenerator {
}
return p;
}
public static boolean placeWord(final Grid grid, final byte[] g, final int key, final long lo, final long hi, final long w) {
final long glo = grid.lo, ghi = grid.hi;
if (Slotinfo.increasing(key)) {
for (long b = lo & glo; b != X; b &= b - 1) {
int idx = numberOfTrailingZeros(b);
if (g[idx] != Lemma.byteAt(w, bitCount(lo & ((1L << idx) - 1)))) return false;
}
int bcLo = bitCount(lo);
for (long b = hi & ghi; b != X; b &= b - 1) {
int idx = numberOfTrailingZeros(b);
if (g[64 | idx] != 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) {
int idx = numberOfTrailingZeros(b);
g[idx] = Lemma.byteAt(w, bitCount(lo & ((1L << idx) - 1)));
}
for (long b = maskHi; b != X; b &= b - 1) {
int idx = numberOfTrailingZeros(b);
g[64 | idx] = Lemma.byteAt(w, bcLo + bitCount(hi & ((1L << idx) - 1)));
}
grid.lo |= maskLo;
grid.hi |= maskHi;
}
} else {
int bcHi = bitCount(hi);
for (long b = hi & ghi; b != X; b &= b - 1) {
int idx = numberOfTrailingZeros(b);
if (g[64 | idx] != Lemma.byteAt(w, bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))))) return false;
}
for (long b = lo & glo; b != X; b &= b - 1) {
int idx = numberOfTrailingZeros(b);
if (g[idx] != 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) {
int idx = numberOfTrailingZeros(b);
g[64 | idx] = Lemma.byteAt(w, bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))));
}
for (long b = maskLo; b != X; b &= b - 1) {
int idx = numberOfTrailingZeros(b);
g[idx] = Lemma.byteAt(w, bcHi + bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))));
}
grid.lo |= maskLo;
grid.hi |= maskHi;
}
}
return true;
}
/// pattern cannot be X
public static int[] candidateInfoForPattern(long[] res, long pattern, long[][] posBitsets, int numLongs) {
@@ -503,6 +434,6 @@ public class SwedishGenerator {
grid.lo = solver.glo;
grid.hi = solver.ghi;
return new FillResult(ok, solver.nodes, solver.backtracks, new FillStats((System.currentTimeMillis() - t0) / 1000.0, solver.lastMRV));
return new FillResult(ok, solver.nodes, solver.backtracks, solver.lastMRV, System.currentTimeMillis() - t0, new FillStats());
}
}