introduce bitloops

This commit is contained in:
mike
2026-01-14 07:25:46 +01:00
parent 5d34893ef1
commit c529ce90c7
7 changed files with 144 additions and 144 deletions

View File

@@ -148,14 +148,6 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
}
}
static final record Context(long[] bitset) {
public Context() { this(new long[2500]); }
private static final ThreadLocal<Context> CTX = ThreadLocal.withInitial(Context::new);
public static Context get() { return CTX.get(); }
}
static final class Rng {
@Getter private int x;
@@ -315,8 +307,6 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
static record DictEntry(long[] words, long[][] posBitsets, int length, int numlong) { }
static int LEMMA_COUNTER = 0;
public static interface Lemma {
static final long LETTER_MASK = (1L << 40) - 1; // low 40 bits
@@ -329,12 +319,12 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
for (var i = 0; i < b.length; i++) w |= ((long) b[i] & 63) << (i * 5);
return w;
}
static public long from(String word) { return pack(LEMMA_COUNTER++, word.getBytes(US_ASCII)); }
static byte byteAt(long word, int idx) { return (byte) ((word >>> (idx * 5)) & 0b11111 | B64); }// word[]; }
static int intAt(long word, int idx) { return (int) (((word >>> (idx * 5))) & 0b11111); }// word[]; }
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 - Long.numberOfLeadingZeros(word & LETTER_MASK)) / 5) + 1; }
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 | B64); }// word[]; }
static int intAt(long word, int idx) { return (int) (((word >>> (idx * 5))) & 0b11111); }// word[]; }
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 - Long.numberOfLeadingZeros(word & LETTER_MASK)) / 5) + 1; }
public static String asWord(long word) {
var b = new byte[Lemma.length(word)];
for (var i = 0; i < b.length; i++) b[i] = (byte) ((word >>> (i * 5)) & 0b11111 | B64);
@@ -851,14 +841,13 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
return true;
}
static int[] candidateInfoForPattern(long[] res, long pattern, DictEntry entry, int lenb) {
int numLongs = entry.numlong;
static int[] candidateInfoForPattern(long[] res, long pattern, long[][] posBitsets, int numLongs) {
boolean first = true;
for (long p = pattern; p != 0; ) {
int combined = (int) (p & 0xFF);
if (combined != 0) {
long[] bs = entry.posBitsets[combined - 1];
long[] bs = posBitsets[combined - 1];
if (first) {
System.arraycopy(bs, 0, res, 0, numLongs);
first = false;
@@ -888,8 +877,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
return indices;
}
static int candidateCountForPattern(final long[] res, final long pattern, final DictEntry entry, final int lenb) {
val numLongs = entry.numlong;
static int candidateCountForPattern(final long[] res, final long pattern, final DictEntry entry, final int numLongs) {
val posBitsets = entry.posBitsets;
boolean first = true;
@@ -975,7 +963,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
if (assigned[s.key] != X) continue;
var pattern = patternForSlot(grid, s);
var index = dictIndex[s.length()];
count = pattern == X ? index.length : candidateCountForPattern(bitset, pattern, index, s.length());
count = pattern == X ? index.length : candidateCountForPattern(bitset, pattern, index, index.numlong);
if (count == 0) {
current = PICK_NOT_DONE;
@@ -1004,7 +992,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
current.indices = null;
return;
}
current.indices = candidateInfoForPattern(bitset, pattern, index, best.length());
current.indices = candidateInfoForPattern(bitset, pattern, index.posBitsets, index.numlong);
}
boolean backtrack(int depth) {
if (Thread.currentThread().isInterrupted()) return false;