introduce bitloops
This commit is contained in:
@@ -108,12 +108,12 @@ public record SwedishGenerator(Rng rng) {
|
||||
|
||||
public static record FillResult(boolean ok,
|
||||
Gridded grid,
|
||||
Map<Integer, Lemma> clueMap,
|
||||
Map<Integer, Long> clueMap,
|
||||
FillStats stats) {
|
||||
|
||||
public void calcSimpel() {
|
||||
if (ok) {
|
||||
clueMap.forEach((k, v) -> stats.simplicity += v.simpel());
|
||||
clueMap.forEach((k, v) -> stats.simplicity += Lemma.simpel(v));
|
||||
stats.simplicity = clueMap.isEmpty() ? 0 : stats.simplicity / clueMap.size();
|
||||
}
|
||||
}
|
||||
@@ -243,7 +243,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
}
|
||||
}
|
||||
|
||||
static record DictEntry(Lemma[] words, long[][] posBitsets) { }
|
||||
static record DictEntry(long[] words, long[][] posBitsets) { }
|
||||
|
||||
public static record Lemma(long word) {
|
||||
|
||||
@@ -261,13 +261,15 @@ public record SwedishGenerator(Rng rng) {
|
||||
}
|
||||
public Lemma(int index, String word) { this(pack(index, word.getBytes(US_ASCII))); }
|
||||
public Lemma(String word) { this(LEMMA_COUNTER++, word); }
|
||||
byte byteAt(int idx) { return (byte) ((word >>> (idx * 5)) & 0b11111 | B64); }// word[]; }
|
||||
byte byteAt(int idx) { return Lemma.byteAt(word, idx); }// word[]; }
|
||||
static byte byteAt(long word, int idx) { return (byte) ((word >>> (idx * 5)) & 0b11111 | B64); }// word[]; }
|
||||
int intAt(int idx) { return (int) (((word >>> (idx * 5))) & 0b11111); }// word[]; }
|
||||
@Override public int hashCode() { return unpackIndex(word); }
|
||||
@Override public boolean equals(Object o) { return (o == this) || (o instanceof Lemma l && l.word == word); }
|
||||
String[] clue() { return CsvIndexService.clues(unpackIndex(word)); }
|
||||
int simpel() { return CsvIndexService.simpel(unpackIndex(word)); }
|
||||
int length() {
|
||||
static String[] clue(long w) { return CsvIndexService.clues(unpackIndex(w)); }
|
||||
static int simpel(long w) { return CsvIndexService.simpel(unpackIndex(w)); }
|
||||
int length() { return Lemma.length(word); }
|
||||
static int length(long word) {
|
||||
if (word == 0) return 0;
|
||||
int highestBit = 63 - Long.numberOfLeadingZeros(word & LETTER_MASK);
|
||||
return (highestBit / 5) + 1;
|
||||
@@ -277,9 +279,9 @@ public record SwedishGenerator(Rng rng) {
|
||||
int highestBit = 63 - Long.numberOfLeadingZeros(p & LETTER_MASK); // 0-based
|
||||
return (highestBit / 5) + 1;
|
||||
}
|
||||
public String asWord() {
|
||||
var b = new byte[length()];
|
||||
for (var i = 0; i < length(); i++) b[i] = (byte) ((word >>> (i * 5)) & 0b11111 | B64);
|
||||
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);
|
||||
return new String(b, US_ASCII);
|
||||
}
|
||||
static int unpackIndex(long w) {
|
||||
@@ -312,7 +314,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
}
|
||||
for (int i = MIN_LEN; i < index.length; i++) if (index[i].words().size() <= 0) throw new RuntimeException("No words for length " + i);
|
||||
this(Arrays.stream(index).map(i -> {
|
||||
var words = i.words().toArray(Lemma[]::new);
|
||||
var words = i.words().stream().mapToLong(ww -> ww.word).toArray();
|
||||
int numWords = words.length;
|
||||
int numLongs = (numWords + 63) >>> 6;
|
||||
var bitsets = new long[i.pos().length * 26][numLongs];
|
||||
@@ -677,13 +679,13 @@ public record SwedishGenerator(Rng rng) {
|
||||
for (int i = 0; i < len; i++) cross += (count[s.pos(i)] - 1);
|
||||
return cross * 10 + len;
|
||||
}
|
||||
static boolean placeWord(Grid grid, Slot s, Lemma w, int[] undoBuffer, int offset) {
|
||||
static boolean placeWord(Grid grid, Slot s, long w, int[] undoBuffer, int offset) {
|
||||
int mask = 0;
|
||||
byte cur, ch;
|
||||
for (int i = 0, leng = s.len(), idx; i < leng; i++) {
|
||||
idx = s.pos(i);
|
||||
cur = grid.byteAt(idx);
|
||||
ch = w.byteAt(i);
|
||||
ch = Lemma.byteAt(w, i);
|
||||
if (cur == DASH) {
|
||||
mask |= (1 << i);
|
||||
grid.setByteAt(idx, ch);
|
||||
@@ -778,9 +780,9 @@ public record SwedishGenerator(Rng rng) {
|
||||
val used = new Bit1029();
|
||||
// val assigned = new HashMap<Integer, Lemma>();
|
||||
|
||||
Lemma[] assigned = new Lemma[BIGG];
|
||||
val ctx = CTX.get();
|
||||
val count = ctx.cellCount;
|
||||
long[] assigned = new long[BIGG];
|
||||
val ctx = CTX.get();
|
||||
val count = ctx.cellCount;
|
||||
Arrays.fill(count, 0, SIZE, 0);
|
||||
|
||||
val slots = extractSlots(grid);
|
||||
@@ -803,7 +805,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
lastLog = (now);
|
||||
var done = 0;
|
||||
for (var lemma : assigned) {
|
||||
if (lemma != null) done++;
|
||||
if (lemma != X) done++;
|
||||
}
|
||||
var pct = (TOTAL == 0) ? 100 : (int) Math.floor((done / (double) TOTAL) * 100);
|
||||
var filled = Math.min(BAR_LEN, (int) Math.floor((pct / 100.0) * BAR_LEN));
|
||||
@@ -824,7 +826,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
int bestScore = -1;
|
||||
for (int i = 0, n = slots.size(); i < n; i++) {
|
||||
var s = slots.get(i);
|
||||
if (assigned[s.key()] != null) continue;
|
||||
if (assigned[s.key()] != X) continue;
|
||||
var entry = dictIndex[s.len()];
|
||||
if (entry == null) return PICK_NOT_DONE;
|
||||
ctx.pattern = patternForSlot(grid, s);
|
||||
@@ -880,7 +882,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
int idxInArray = (int) (r * r * r * L);
|
||||
var idx = idxs[idxInArray];
|
||||
var w = entry.words[idx];
|
||||
var lemIdx = Lemma.unpackIndex(w.word);
|
||||
var lemIdx = Lemma.unpackIndex(w);
|
||||
if (used.get(lemIdx)) continue;
|
||||
|
||||
if (!placeWord(grid, s, w, ctx.undo, depth)) continue;
|
||||
@@ -890,7 +892,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
|
||||
if (backtrack(depth + 1)) return true;
|
||||
|
||||
assigned[k] = null;
|
||||
assigned[k] = X;
|
||||
used.clear(lemIdx);
|
||||
s.undoPlace(grid, ctx.undo[depth]);
|
||||
}
|
||||
@@ -909,7 +911,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
double r = rng.nextFloat();
|
||||
int idxInArray = (int) (r * r * r * N);
|
||||
var w = entry.words[idxInArray];
|
||||
var lemIdx = Lemma.unpackIndex(w.word);
|
||||
var lemIdx = Lemma.unpackIndex(w);
|
||||
if (used.get(lemIdx)) continue;
|
||||
|
||||
if (!placeWord(grid, s, w, ctx.undo, depth)) continue;
|
||||
@@ -919,7 +921,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
|
||||
if (backtrack(depth + 1)) return true;
|
||||
|
||||
assigned[k] = null;
|
||||
assigned[k] = X;
|
||||
used.clear(lemIdx);
|
||||
s.undoPlace(grid, ctx.undo[depth]);
|
||||
}
|
||||
@@ -940,9 +942,9 @@ public record SwedishGenerator(Rng rng) {
|
||||
}
|
||||
|
||||
stats.seconds = (System.currentTimeMillis() - t0) / 1000.0;
|
||||
Map<Integer, Lemma> lemmaMap = new HashMap<>();
|
||||
Map<Integer, Long> lemmaMap = new HashMap<>();
|
||||
for (var i = 0; i < assigned.length; i++) {
|
||||
if (assigned[i] != null) {
|
||||
if (assigned[i] != X) {
|
||||
lemmaMap.put(i, assigned[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user