Gather data

This commit is contained in:
mike
2026-01-09 04:41:10 +01:00
parent e394d3aba9
commit abef2e2f0b
2 changed files with 94 additions and 72 deletions

View File

@@ -47,16 +47,29 @@ public record ExportFormat() {
} }
} }
record Bit(long[] bits) { static class Bit {
public Bit() { this(new long[2]); } long l1, l2;
static int wordIndex(int bitIndex) { return bitIndex >> 6; } public Bit() {
public boolean get(int bitIndex) { return (this.bits[wordIndex(bitIndex)] & 1L << bitIndex) != 0L; } l1 = 0L;
public void set(int bitIndex) { bits[wordIndex(bitIndex)] |= 1L << bitIndex; } l2 = 0L;
public void clear(int bitIndex) { this.bits[wordIndex(bitIndex)] &= ~(1L << bitIndex); } }
public boolean get(int bitIndex) {
if (bitIndex < 64) {
return (l1 & (1L << bitIndex)) != 0L;
}
return (l2 & (1L << (bitIndex & 63))) != 0L;
}
public void set(int bitIndex) {
if (bitIndex < 64) {
this.l1 |= 1L << bitIndex;
} else {
this.l2 |= 1L << (bitIndex & 63);
}
}
public void clear() { public void clear() {
bits[0] = 0L; l1 = 0L;
bits[1] = 0L; l2 = 0L;
} }
} }

View File

@@ -38,6 +38,18 @@ public record SwedishGenerator(int[] buff) {
} }
} }
record rci(int r, int c, int i) { }
static final rci[] IT = new rci[]{
new rci(0, 0, 0), new rci(0, 1, 8), new rci(0, 2, 16), new rci(0, 3, 24), new rci(0, 4, 32), new rci(0, 5, 40), new rci(0, 6, 48), new rci(0, 7, 56), new rci(0, 8, 64),
new rci(1, 0, 1), new rci(1, 1, 9), new rci(1, 2, 17), new rci(1, 3, 25), new rci(1, 4, 33), new rci(1, 5, 41), new rci(1, 6, 49), new rci(1, 7, 57), new rci(1, 8, 65),
new rci(2, 0, 2), new rci(2, 1, 10), new rci(2, 2, 18), new rci(2, 3, 26), new rci(2, 4, 34), new rci(2, 5, 42), new rci(2, 6, 50), new rci(2, 7, 58), new rci(2, 8, 66),
new rci(3, 0, 3), new rci(3, 1, 11), new rci(3, 2, 19), new rci(3, 3, 27), new rci(3, 4, 35), new rci(3, 5, 43), new rci(3, 6, 51), new rci(3, 7, 59), new rci(3, 8, 67),
new rci(4, 0, 4), new rci(4, 1, 12), new rci(4, 2, 20), new rci(4, 3, 28), new rci(4, 4, 36), new rci(4, 5, 44), new rci(4, 6, 52), new rci(4, 7, 60), new rci(4, 8, 68),
new rci(5, 0, 5), new rci(5, 1, 13), new rci(5, 2, 21), new rci(5, 3, 29), new rci(5, 4, 37), new rci(5, 5, 45), new rci(5, 6, 53), new rci(5, 7, 61), new rci(5, 8, 69),
new rci(6, 0, 6), new rci(6, 1, 14), new rci(6, 2, 22), new rci(6, 3, 30), new rci(6, 4, 38), new rci(6, 5, 46), new rci(6, 6, 54), new rci(6, 7, 62), new rci(6, 8, 70),
new rci(7, 0, 7), new rci(7, 1, 15), new rci(7, 2, 23), new rci(7, 3, 31), new rci(7, 4, 39), new rci(7, 5, 47), new rci(7, 6, 55), new rci(7, 7, 63), new rci(7, 8, 71),
};
static final int C = Config.PUZZLE_COLS; static final int C = Config.PUZZLE_COLS;
static final double CROSS_Y = (C - 1) / 2.0; static final double CROSS_Y = (C - 1) / 2.0;
static final int R = Config.PUZZLE_ROWS; static final int R = Config.PUZZLE_ROWS;
@@ -134,6 +146,7 @@ public record SwedishGenerator(int[] buff) {
record Grid(byte[] g) { record Grid(byte[] g) {
int digitAt(int r, int c) { return g[offset(r, c)] - 48; } int digitAt(int r, int c) { return g[offset(r, c)] - 48; }
int digitAt(int index) { return g[index] - 48; }
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; }
static int offset(int r, int c) { return r | (c << 3); } static int offset(int r, int c) { return r | (c << 3); }
@@ -409,36 +422,34 @@ public record SwedishGenerator(int[] buff) {
Arrays.fill(covV, 0, SIZE, 0); Arrays.fill(covV, 0, SIZE, 0);
boolean hasSlots = false; boolean hasSlots = false;
for (var r = 0; r < R; r++) { for (var rci : IT) {
for (var c = 0; c < C; c++) { if (!grid.isDigitAt(rci.i)) continue;
if (!grid.isDigitAt(r, c)) continue; var d = grid.digitAt(rci.i);
var d = grid.digitAt(r, c); var nbrs16 = OFFSETS[d];
var nbrs16 = OFFSETS[d]; int rr = rci.r + nbrs16.r, cc = rci.c + nbrs16.c;
int rr = r + nbrs16.r, cc = c + nbrs16.c; if (rr < 0 || rr >= R || cc < 0 || cc >= C || grid.isDigitAt(rr, cc)) continue;
if (rr < 0 || rr >= R || cc < 0 || cc >= C || grid.isDigitAt(rr, cc)) continue;
long packedPos = 0; long packedPos = 0;
var n = 0; var n = 0;
while (rr >= 0 && rr < R && cc >= 0 && cc < C && n < MAX_WORD_LENGTH) { while (rr >= 0 && rr < R && cc >= 0 && cc < C && n < MAX_WORD_LENGTH) {
if (grid.isDigitAt(rr, cc)) break; if (grid.isDigitAt(rr, cc)) break;
packedPos |= (long) Grid.offset(rr, cc) << (n * 7); packedPos |= (long) Grid.offset(rr, cc) << (n * 7);
n++; n++;
rr += nbrs16.dr; rr += nbrs16.dr;
cc += nbrs16.dc; cc += nbrs16.dc;
}
if (n == 0) continue;
hasSlots = true;
if (n < MIN_LEN) {
penalty += 8000;
} else {
if (lenCounts[n] <= 0) penalty += 12000;
}
var horiz = Slot.horiz(d) ? covH : covV;
for (var i = 0; i < n; i++) horiz[Slot.offset(packedPos, i)] += 1;
} }
if (n == 0) continue;
hasSlots = true;
if (n < MIN_LEN) {
penalty += 8000;
} else {
if (lenCounts[n] <= 0) penalty += 12000;
}
var horiz = Slot.horiz(d) ? covH : covV;
for (var i = 0; i < n; i++) horiz[Slot.offset(packedPos, i)] += 1;
} }
if (!hasSlots) return 1_000_000_000L; if (!hasSlots) return 1_000_000_000L;
@@ -458,46 +469,44 @@ public record SwedishGenerator(int[] buff) {
var stack = ctx.stack; var stack = ctx.stack;
int sp, nr, nc; int sp, nr, nc;
long size; long size;
for (var r = 0; r < R; r++) for (var rci : IT) {
for (var c = 0; c < C; c++) { idx = rci.i;
idx = Grid.offset(r, c); if (seen.get(idx) || grid.isLetterAt(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); size = 0;
size = 0;
while (sp > 0) { while (sp > 0) {
var p = stack[--sp]; var p = stack[--sp];
int rr = Grid.c(p), cc = Grid.r(p); int rr = Grid.c(p), cc = Grid.r(p);
size++; size++;
for (var d : nbrs8) { for (var d : nbrs8) {
nr = rr + d.r; nr = rr + d.r;
nc = cc + d.c; nc = cc + d.c;
if (nr < 0 || nr >= R || nc < 0 || nc >= C) continue; if (nr < 0 || nr >= R || nc < 0 || nc >= C) continue;
idx = Grid.offset(nr, nc); idx = Grid.offset(nr, nc);
if (seen.get(idx) || grid.isLetterAt(idx)) continue; if (seen.get(idx) || grid.isLetterAt(idx)) continue;
seen.set(idx); seen.set(idx);
stack[sp++] = idx; stack[sp++] = idx;
}
} }
if (size >= 2) penalty += (size - 1L) * 120L;
} }
if (size >= 2) penalty += (size - 1L) * 120L;
}
int walls, wr, wc; 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 rci : IT) {
for (var c = 0; c < C; c++) { if (grid.isDigitAt(rci.i)) continue;
if (grid.isDigitAt(r, c)) continue; walls = 0;
walls = 0; for (var d : nbrs4) {
for (var d : nbrs4) { wr = rci.r + d.r;
wr = r + d.r; wc = rci.c + d.c;
wc = c + d.c; if (wr < 0 || wr >= R || wc < 0 || wc >= C || grid.isDigitAt(wr, wc)) walls++;
if (wr < 0 || wr >= R || wc < 0 || wc >= C || grid.isDigitAt(wr, wc)) walls++;
}
if (walls >= 3) penalty += 400;
} }
if (walls >= 3) penalty += 400;
}
return penalty; return penalty;
} }