Gather data

This commit is contained in:
mike
2026-01-07 04:03:46 +01:00
parent 684ced86cf
commit 9c4c0393cf

View File

@@ -80,9 +80,10 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
int[] stack,
BitSet seen,
char[] pattern,
IntList[] intListBuffer) {
IntList[] intListBuffer,
long[] undoBuffer) {
public Context() { this(new int[256], new int[256], new int[256], new int[256], new BitSet(256), new char[32], new IntList[32]); }
public Context() { this(new int[256], new int[256], new int[256], new int[256], new BitSet(256), new char[32], new IntList[32], new long[2048]); }
}
static final ThreadLocal<Context> CTX = ThreadLocal.withInitial(Context::new);
@@ -295,6 +296,17 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
return new CandidateInfo(null, entry.words.size());
}
// Sort constraints by size to optimize intersection
for (int i = 0; i < listCount - 1; i++) {
for (int j = i + 1; j < listCount; j++) {
if (listBuffer[j].size() < listBuffer[i].size()) {
var tmp = listBuffer[i];
listBuffer[i] = listBuffer[j];
listBuffer[j] = tmp;
}
}
}
var first = listBuffer[0];
var cur = first.data();
var curLen = first.size();
@@ -322,7 +334,12 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
public static int r(long rs, int i) { return (int) ((rs >> (i << 2)) & 15); }
public static int c(long cs, int i) { return (int) ((cs >> (i << 2)) & 15); }
}
static void undoPlace(Grid grid, long[] undoBuffer, int offset, int n) {
for (var i = 0; i < n; i++) {
long v = undoBuffer[offset + i];
grid.setCharAt((int) (v >> 16) & 0xFF, (int) (v >> 8) & 0xFF, (char) (v & 0xFF));
}
}
@FunctionalInterface
interface SlotVisitor {
@@ -352,7 +369,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
n++;
rr += dr;
cc += dc;
if (n >= 12) break;
if (n >= MAX_LEN) break;
}
if (n > 0) {
visitor.visit((r << 8) | (c << 4) | d, packedRs, packedCs, n);
@@ -419,7 +436,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
n++;
rr += dr;
cc += dc;
if (n >= 12) break;
if (n >= MAX_LEN) break;
}
if (n == 0) continue;
hasSlots = true;
@@ -646,7 +663,6 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
return pop.get(0);
}
record UndoPlace(int ur, int uc, char up) { }
// ---------------- Fill (CSP) ----------------
record Undo(UndoPlace[] ur, int n) { }
@@ -692,10 +708,32 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
return cross * 10 + s.len();
}
static int placeWord(Grid grid, Slot s, Lemma w, long[] undoBuffer, int offset) {
int n = 0;
for (var i = 0; i < s.len(); i++) {
int r = s.r(i), c = s.c(i);
char cur = grid.getCharAt(r, c);
var ch = w.charAt(i);
if (cur == C_DASH) {
undoBuffer[offset + n] = ((long) r << 16) | ((long) c << 8) | (long) C_DASH;
n++;
grid.setCharAt(r, c, ch);
} else {
if (cur != ch) {
for (var j = 0; j < n; j++) {
long v = undoBuffer[offset + j];
grid.setCharAt((int) (v >> 16) & 0xFF, (int) (v >> 8) & 0xFF, (char) (v & 0xFF));
}
return -1;
}
}
}
return n;
}
/*
static Undo placeWord(Grid grid, Slot s, Lemma w) {
var ur = new UndoPlace[s.len()];
var n = 0;
for (var i = 0; i < s.len(); i++) {
int r = s.r(i), c = s.c(i);
char cur = grid.getCharAt(r, c);
@@ -713,7 +751,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
}
}
return new Undo(ur, n);
}
}*/
static void undoPlace(Grid grid, Undo u) {
for (var i = 0; i < u.n; i++) grid.setCharAt(u.ur[i]);
@@ -796,11 +834,10 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
return new Pick(best, bestInfo, false);
}
};
System.out.println("hit");
class Solver {
boolean backtrack() {
boolean backtrack(int depth) {
if (Thread.currentThread().isInterrupted()) return false;
stats.nodes++;
@@ -815,13 +852,14 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
stats.lastMRV = pick.info.count;
renderProgress.run();
var s = pick.slot;
var k = s.key();
var entry = dictIndex[s.len()];
var pat = new char[s.len()];
patternForSlot(grid, s, pat);
int patLen = patternForSlot(grid, s, pat);
int undoOffset = depth * SIZE;
if (pick.info.indices != null && pick.info.indices.length > 0) {
var idxs = pick.info.indices;
var L = idxs.length;
@@ -836,7 +874,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
if (used.get(w.index())) continue;
boolean match = true;
for (var i = 0; i < pat.length; i++) {
for (var i = 0; i < patLen; i++) {
if (pat[i] != C_DASH && pat[i] != w.charAt(i)) {
match = false;
break;
@@ -844,17 +882,17 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
}
if (!match) continue;
var undo = placeWord(grid, s, w);
if (undo == null) continue;
int nPlaced = placeWord(grid, s, w, ctx.undoBuffer, undoOffset);
if (nPlaced < 0) continue;
used.set(w.index());
assigned.put(k, w);
if (backtrack()) return true;
if (backtrack(depth+1)) return true;
assigned.remove(k);
used.set(w.index, false);
undoPlace(grid, undo);
undoPlace(grid, ctx.undoBuffer, undoOffset, nPlaced);
}
stats.backtracks++;
return false;
@@ -875,7 +913,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
if (used.get(w.index())) continue;
boolean match = true;
for (var i = 0; i < pat.length; i++) {
for (var i = 0; i < patLen; i++) {
if (pat[i] != C_DASH && pat[i] != w.charAt(i)) {
match = false;
break;
@@ -883,17 +921,17 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
}
if (!match) continue;
var undo = placeWord(grid, s, w);
if (undo == null) continue;
int nPlaced = placeWord(grid, s, w, ctx.undoBuffer, undoOffset);
if (nPlaced < 0) continue;
used.set(w.index());
assigned.put(k, w);
if (backtrack()) return true;
if (backtrack(depth+1)) return true;
assigned.remove(k);
used.set(w.index, false);
undoPlace(grid, undo);
undoPlace(grid, ctx.undoBuffer, undoOffset, nPlaced);
}
stats.backtracks++;
@@ -903,7 +941,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
// initial render (same feel)
renderProgress.run();
var ok = new Solver().backtrack();
var ok = new Solver().backtrack(0);
// final progress line
System.out.print("\r" + padRight("", 120) + "\r");
System.out.flush();