Gather data

This commit is contained in:
mike
2026-01-08 21:30:54 +01:00
parent e9978e0f4c
commit 34faf9276e

View File

@@ -121,10 +121,9 @@ public record SwedishGenerator(int[] buff) {
record Grid(byte[] g) { record Grid(byte[] g) {
public static int r(int offset) { return offset & 7; } public static int r(int offset) { return offset & 7; }
public static int c(int offset) { return offset >> 3; } public static int c(int offset) { return offset >>> 3; }
Grid deepCopyGrid() { return new Grid(g.clone()); }
static int offset(int r, int c) { return r | (c << 3); } static int offset(int r, int c) { return r | (c << 3); }
boolean isLettercell(int r, int c) { return (g[offset(r, c)] & 48) != 48; } Grid deepCopyGrid() { return new Grid(g.clone()); }
char getCharAt(int r, int c) { return (char) (g[offset(r, c)]); } char getCharAt(int r, int c) { return (char) (g[offset(r, c)]); }
int digitAt(int r, int c) { return g[offset(r, c)] - 48; } int digitAt(int r, int c) { return g[offset(r, c)] - 48; }
byte byteAt(int r, int c) { return g[offset(r, c)]; } byte byteAt(int r, int c) { return g[offset(r, c)]; }
@@ -132,6 +131,9 @@ public record SwedishGenerator(int[] buff) {
boolean isLetterAt(int r, int c) { return ((g[offset(r, c)] & 64) != 0); } boolean isLetterAt(int r, int c) { return ((g[offset(r, c)] & 64) != 0); }
boolean isDigitAt(int r, int c) { return (g[offset(r, c)] & 48) == 48; } boolean isDigitAt(int r, int c) { return (g[offset(r, c)] & 48) == 48; }
boolean isDigitAt(int index) { return (g[index] & 48) == 48; } boolean isDigitAt(int index) { return (g[index] & 48) == 48; }
static boolean isDigit(byte b) { return (b & 48) == 48; }
boolean isLettercell(int r, int c) { return (g[offset(r, c)] & 48) != 48; }
boolean isLetterAt(int index) { return (g[index] & 48) != 48; }
public double similarity(Grid b) { public double similarity(Grid b) {
var same = 0; var same = 0;
for (int i = 0; i < SIZE; i++) if (g[i] == b.g[i]) same++; for (int i = 0; i < SIZE; i++) if (g[i] == b.g[i]) same++;
@@ -327,6 +329,10 @@ public record SwedishGenerator(int[] buff) {
} }
static record Slot(int key, long rs, long cs, int len) { static record Slot(int key, long rs, long cs, int len) {
static Slot from(int key, long rs, long cs, int len) {
return new Slot(key, rs, cs, len);
}
//public int len() { return (int) (Long.highestOneBit(rs | cs) >> 2); } //public int len() { return (int) (Long.highestOneBit(rs | cs) >> 2); }
public int clueR() { return (key >> 8) & 15; } public int clueR() { return (key >> 8) & 15; }
public int clueC() { return (key >> 4) & 15; } public int clueC() { return (key >> 4) & 15; }
@@ -400,7 +406,7 @@ public record SwedishGenerator(int[] buff) {
long penalty = 0; long penalty = 0;
var clueCount = 0; var clueCount = 0;
for (var r = 0; r < R; r++) for (var c = 0; c < C; c++) if (grid.isDigitAt(r, c)) clueCount++; for (var v : grid.g) if (Grid.isDigit(v)) clueCount++;
penalty += 8L * Math.abs(clueCount - TARGET_CLUES); penalty += 8L * Math.abs(clueCount - TARGET_CLUES);
@@ -446,12 +452,13 @@ public record SwedishGenerator(int[] buff) {
} }
if (!hasSlots) return 1_000_000_000L; if (!hasSlots) return 1_000_000_000L;
int idx, h, v;
for (var r = 0; r < R; r++) for (var r = 0; r < R; r++)
for (var c = 0; c < C; c++) { for (var c = 0; c < C; c++) {
if (grid.isDigitAt(r, c)) continue; idx = Grid.offset(r, c);
int idx = Grid.offset(r, c); if (grid.isDigitAt(idx)) continue;
int h = covH[idx], v = covV[idx]; h = covH[idx];
v = covV[idx];
if (h == 0 && v == 0) penalty += 1500; if (h == 0 && v == 0) penalty += 1500;
else if (h > 0 && v > 0) { /* ok */ } else if (h + v == 1) penalty += 200; else if (h > 0 && v > 0) { /* ok */ } else if (h + v == 1) penalty += 200;
else penalty += 600; else penalty += 600;
@@ -460,49 +467,46 @@ public record SwedishGenerator(int[] buff) {
// clue clustering (8-connected) // clue clustering (8-connected)
var seen = ctx.seen; var seen = ctx.seen;
seen.clear(); seen.clear();
var stack = ctx.stack; var stack = ctx.stack;
int sp, idx; int sp, nr, nc;
long size;
for (var r = 0; r < R; r++) for (var r = 0; r < R; r++)
for (var c = 0; c < C; c++) { for (var c = 0; c < C; c++) {
idx = grid.offset(r, c); idx = Grid.offset(r, c);
if (!grid.isDigitAt(r, c) || seen.get(idx)) continue; if (seen.get(idx) || grid.isLetterAt(idx)) continue;
sp = 0; sp = 0;
stack[sp++] = idx; stack[sp++] = idx;
seen.set(idx); seen.set(idx);
var size = 0; size = 0;
while (sp > 0) { while (sp > 0) {
var p = stack[--sp]; var p = stack[--sp];
int x = p / C, y = p % C; int rr = Grid.c(p), cc = Grid.r(p);
size++; size++;
for (var d : nbrs8) { for (var d : nbrs8) {
int nx = x + d.r, ny = y + d.c; nr = rr + d.r;
if (nx < 0 || nx >= R || ny < 0 || ny >= C) continue; nc = cc + d.c;
int nidx = grid.offset(nx, ny); if (nr < 0 || nr >= R || nc < 0 || nc >= C) continue;
if (seen.get(nidx)) continue; idx = Grid.offset(nr, nc);
if (!grid.isDigitAt(nx, ny)) continue; if (seen.get(idx) || grid.isLetterAt(idx)) continue;
seen.set(nidx); seen.set(idx);
stack[sp++] = nidx; stack[sp++] = idx;
} }
} }
if (size >= 2) penalty += (long) (size - 1) * 120L; if (size >= 2) penalty += (size - 1L) * 120L;
} }
int walls, wr, wc;
// dead-end-ish letter cell (3+ walls) // dead-end-ish letter cell (3+ walls)
for (var r = 0; r < R; r++) for (var r = 0; r < R; r++)
for (var c = 0; c < C; c++) { for (var c = 0; c < C; c++) {
if (grid.isDigitAt(r, c)) continue; if (grid.isDigitAt(r, c)) continue;
var walls = 0; walls = 0;
for (var d : nbrs4) { for (var d : nbrs4) {
int rr = r + d.r, cc = c + d.c; wr = r + d.r;
if (rr < 0 || rr >= R || cc < 0 || cc >= C) { wc = c + d.c;
walls++; if (wr < 0 || wr >= R || wc < 0 || wc >= C || grid.isDigitAt(wr, wc)) walls++;
continue;
}
if (grid.isDigitAt(rr, cc)) walls++;
} }
if (walls >= 3) penalty += 400; if (walls >= 3) penalty += 400;
} }