Gather data

This commit is contained in:
mike
2026-01-07 02:27:35 +01:00
parent fffebed2af
commit 4593ccdc07
4 changed files with 53 additions and 58 deletions

View File

@@ -35,7 +35,7 @@ public final class ExportFormat {
var word = clueMap.get(s.key()); var word = clueMap.get(s.key());
if (word == null) continue; if (word == null) continue;
var p = extractPlacedFromSlot(puz.dict(), s, word); var p = extractPlacedFromSlot(s, word);
if (p == null) continue; if (p == null) continue;
placed.add(p); placed.add(p);
} }
@@ -116,7 +116,7 @@ public final class ExportFormat {
/** /**
* Convert a generator Slot + assigned word into a Placed object for export. * Convert a generator Slot + assigned word into a Placed object for export.
*/ */
private static Placed extractPlacedFromSlot(Dict dict, Slot s, Lemma lemma) { private static Placed extractPlacedFromSlot(Slot s, Lemma lemma) {
int r = s.clueR(); int r = s.clueR();
int c = s.clueC(); int c = s.clueC();
int d = s.dir(); int d = s.dir();

View File

@@ -114,9 +114,9 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
static int clamp(int x, int a, int b) { return Math.max(a, Math.min(b, x)); } static int clamp(int x, int a, int b) { return Math.max(a, Math.min(b, x)); }
static final record CandidateInfo(int[] indices, int count) { } static final record CandidateInfo(int[] indices, int count) { }
record Grid(byte[] g, int H, int W) { record Grid(byte[] g, int W) {
Grid deepCopyGrid() { return new Grid(g.clone(), H, W); } Grid deepCopyGrid() { return new Grid(g.clone(), W); }
private int offset(int r, int c) { return r * W + c; } private int offset(int r, int c) { return r * W + c; }
boolean isLettercell(int r, int c) { return !isDigitAt(r, c); } boolean isLettercell(int r, int c) { return !isDigitAt(r, c); }
char getCharAt(int r, int c) { return (char) (g[offset(r, c)] & 0xFF); } char getCharAt(int r, int c) { return (char) (g[offset(r, c)] & 0xFF); }
@@ -126,8 +126,11 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
void setCharAt(UndoPlace pl) { g[offset(pl.ur, pl.uc)] = (byte) pl.up; } void setCharAt(UndoPlace pl) { g[offset(pl.ur, pl.uc)] = (byte) pl.up; }
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; }
public int H() {
return g.length / W;
}
} }
Grid makeEmptyGrid() { return new Grid(new byte[SIZE], H, W); } Grid makeEmptyGrid() { return new Grid(new byte[SIZE], W); }
String gridToString(Grid g) { String gridToString(Grid g) {
var sb = new StringBuilder(); var sb = new StringBuilder();
@@ -303,22 +306,15 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
return new CandidateInfo(cur, curLen); return new CandidateInfo(cur, curLen);
} }
static record Slot(int key, long rs, long cs, int len) { static record Slot(int key, long rs, long cs ,int len) {
public Slot(int clueR, int clueC, int d, long rs, long cs, int len) { //public int len() { return (int) (Long.highestOneBit(rs | cs) >> 2); }
this((clueR << 8) | (clueC << 4) | d, rs, cs, len); public int clueR() { return (key >> 8) & 15; }
} public int clueC() { return (key >> 4) & 15; }
public int dir() { return key & 15; }
public int clueR() { return (key >> 8) & 15; } public boolean horiz() { return (dir() & 1) == 0; }
public int clueC() { return (key >> 4) & 15; } public int r(int i) { return (int) ((rs >> (i << 2)) & 15); }
public int dir() { return key & 15; } public int c(int i) { return (int) ((cs >> (i << 2)) & 15); }
public boolean horiz() {
return (dir() & 1) == 0;
/* var d = dir();
return d == 2 || d == 4;*/
}
public int r(int i) { return (int) ((rs >> (i << 2)) & 15); }
public int c(int i) { return (int) ((cs >> (i << 2)) & 15); }
} }
ArrayList<Slot> extractSlots(Grid grid) { ArrayList<Slot> extractSlots(Grid grid) {
@@ -347,8 +343,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
cc += dc; cc += dc;
if (n >= 12) break; if (n >= 12) break;
} }
slots.add(new Slot((r << 8) | (c << 4) | d, packedRs, packedCs,n ));
slots.add(new Slot(r, c, d, packedRs, packedCs, n));
} }
} }
return slots; return slots;
@@ -387,7 +382,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
Arrays.fill(covV, 0, SIZE, 0); Arrays.fill(covV, 0, SIZE, 0);
for (var s : slots) { for (var s : slots) {
if (s.len < MIN_LEN) { if (s.len() < MIN_LEN) {
penalty += 8000; penalty += 8000;
} }
/* else if (s.len > MAX_LEN) { /* else if (s.len > MAX_LEN) {
@@ -395,10 +390,10 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
throw new RuntimeException(); throw new RuntimeException();
}*/ }*/
else { else {
if (lenCounts[s.len] <= 0) penalty += 12000; if (lenCounts[s.len()] <= 0) penalty += 12000;
} }
for (var i = 0; i < s.len; i++) { for (var i = 0; i < s.len(); i++) {
int r = s.r(i), c = s.c(i); int r = s.r(i), c = s.c(i);
int idx = grid.offset(r, c); int idx = grid.offset(r, c);
if (s.horiz()) covH[idx] += 1; if (s.horiz()) covH[idx] += 1;
@@ -642,8 +637,8 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
} }
static char[] patternForSlot(Grid grid, Slot s) { static char[] patternForSlot(Grid grid, Slot s) {
var pat = new char[s.len]; var pat = new char[s.len()];
for (var i = 0; i < s.len; i++) { for (var i = 0; i < s.len(); i++) {
var ch = grid.getCharAt(s.r(i), s.c(i)); var ch = grid.getCharAt(s.r(i), s.c(i));
if (isLetter(ch)) pat[i] = ch; if (isLetter(ch)) pat[i] = ch;
} }
@@ -652,15 +647,15 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
static int slotScore(int[] cellCount, Slot s, Grid grid) { static int slotScore(int[] cellCount, Slot s, Grid grid) {
var cross = 0; var cross = 0;
for (var i = 0; i < s.len; i++) cross += (cellCount[grid.offset(s.r(i), s.c(i))] - 1); for (var i = 0; i < s.len(); i++) cross += (cellCount[grid.offset(s.r(i), s.c(i))] - 1);
return cross * 10 + s.len; return cross * 10 + s.len();
} }
static Undo placeWord(Grid grid, Slot s, Lemma w) { static Undo placeWord(Grid grid, Slot s, Lemma w) {
var ur = new UndoPlace[s.len]; var ur = new UndoPlace[s.len()];
var n = 0; var n = 0;
for (var i = 0; i < s.len; i++) { for (var i = 0; i < s.len(); i++) {
int r = s.r(i), c = s.c(i); int r = s.r(i), c = s.c(i);
char cur = grid.getCharAt(r, c); char cur = grid.getCharAt(r, c);
var ch = w.charAt(i); var ch = w.charAt(i);
@@ -695,7 +690,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
var ctx = CTX.get(); var ctx = CTX.get();
var cellCount = ctx.cellCount; var cellCount = ctx.cellCount;
Arrays.fill(cellCount, 0, SIZE, 0); Arrays.fill(cellCount, 0, SIZE, 0);
for (var s : slots) for (var i = 0; i < s.len; i++) cellCount[grid.offset(s.r(i), s.c(i))]++; for (var s : slots) for (var i = 0; i < s.len(); i++) cellCount[grid.offset(s.r(i), s.c(i))]++;
var t0 = System.currentTimeMillis(); var t0 = System.currentTimeMillis();
final var lastLog = new java.util.concurrent.atomic.AtomicLong(t0); final var lastLog = new java.util.concurrent.atomic.AtomicLong(t0);
@@ -733,7 +728,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
var k = s.key(); var k = s.key();
if (assigned.containsKey(k)) continue; if (assigned.containsKey(k)) continue;
var entry = dictIndex[s.len]; var entry = dictIndex[s.len()];
if (entry == null) { if (entry == null) {
return new Pick(null, null, false); return new Pick(null, null, false);
} }
@@ -782,7 +777,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
var s = pick.slot; var s = pick.slot;
var k = s.key(); var k = s.key();
var entry = dictIndex[s.len]; var entry = dictIndex[s.len()];
var pat = patternForSlot(grid, s); var pat = patternForSlot(grid, s);
Predicate<Lemma> tryWord = (Lemma w) -> { Predicate<Lemma> tryWord = (Lemma w) -> {

View File

@@ -22,7 +22,7 @@ public class MainTest {
@Test @Test
public void testGridBasics() { public void testGridBasics() {
var grid = new Grid(new byte[3 * 4], 3, 4); var grid = new Grid(new byte[3 * 4], 4);
// Initialize with # // Initialize with #
for (int r = 0; r < 3; r++) { for (int r = 0; r < 3; r++) {
for (int c = 0; c < 4; c++) { for (int c = 0; c < 4; c++) {
@@ -61,7 +61,7 @@ public class MainTest {
@Test @Test
public void testGridDeepCopy() { public void testGridDeepCopy() {
var grid = new Grid(new byte[2 * 2], 2, 2); var grid = new Grid(new byte[2 * 2], 2);
grid.setCharAt(0, 0, 'A'); grid.setCharAt(0, 0, 'A');
grid.setCharAt(0, 1, 'B'); grid.setCharAt(0, 1, 'B');
grid.setCharAt(1, 0, 'C'); grid.setCharAt(1, 0, 'C');
@@ -77,7 +77,7 @@ public class MainTest {
@Test @Test
public void testMini() { public void testMini() {
var grid = new Grid(new byte[3 * 3], 3, 3); var grid = new Grid(new byte[3 * 3], 3);
grid.setCharAt(1, 1, '1'); grid.setCharAt(1, 1, '1');
Assertions.assertTrue(grid.isDigitAt(1, 1)); Assertions.assertTrue(grid.isDigitAt(1, 1));
} }
@@ -102,22 +102,22 @@ public class MainTest {
// But SwedishGenerator.loadWords(path) is what we have. // But SwedishGenerator.loadWords(path) is what we have.
// Let's try to load a real one or a small subset if possible. // Let's try to load a real one or a small subset if possible.
var dict = new Dict(new Lemma[]{ var dict = new Dict(new Lemma[]{
new Lemma(0, "NU", 1, "NU"), new Lemma(0, "NU", 1, "NU"),
new Lemma(1, "ET", 2, "ET"), new Lemma(1, "ET", 2, "ET"),
new Lemma(2, "NUT", 3, "NUT"), new Lemma(2, "NUT", 3, "NUT"),
new Lemma(3, "ETE", 4, "ETE"), new Lemma(3, "ETE", 4, "ETE"),
new Lemma(4, "IK", 5, "IK"), new Lemma(4, "IK", 5, "IK"),
new Lemma(5, "IN", 6, "IN"), new Lemma(5, "IN", 6, "IN"),
new Lemma(6, "AU", 7, "AU"), new Lemma(6, "AU", 7, "AU"),
new Lemma(7, "JE", 8, "JE"), new Lemma(7, "JE", 8, "JE"),
new Lemma(8, "AI", 9, "AI"), new Lemma(8, "AI", 9, "AI"),
new Lemma(9, "NA", 10, "NA"), new Lemma(9, "NA", 10, "NA"),
new Lemma(10, "AF", 11, "AF"), new Lemma(10, "AF", 11, "AF"),
new Lemma(11, "AL", 14, "AL"), new Lemma(11, "AL", 14, "AL"),
new Lemma(12, "EA", 15, "EA"), new Lemma(12, "EA", 15, "EA"),
new Lemma(13, "AV", 18, "AV"), new Lemma(13, "AV", 18, "AV"),
new Lemma(14, "IL", 19, "IL"), new Lemma(14, "IL", 19, "IL"),
new Lemma(15, "EN", 22, "EN") new Lemma(15, "EN", 22, "EN")
}); });
// Act // Act

View File

@@ -9,10 +9,10 @@ class SlotTest {
@Test @Test
public void testHoriz() { public void testHoriz() {
assertTrue(new Slot(0, 0, 2, 0L, 0L, 5).horiz()); assertTrue(new Slot(2, 0L, 0L ,1).horiz());
assertTrue(new Slot(0, 0, 4, 0L, 0L, 5).horiz()); assertTrue(new Slot(4, 0L, 0L ,1).horiz());
assertFalse(new Slot(0, 0, 1, 0L, 3L, 5).horiz()); assertFalse(new Slot(1, 0L, 3L ,1).horiz());
assertFalse(new Slot(0, 0, 3, 0L, 3L, 5).horiz()); assertFalse(new Slot(3, 0L, 3L ,1).horiz());
assertFalse(new Slot(0, 0, 5, 0L, 3L, 5).horiz()); assertFalse(new Slot(5, 0L, 3L ,1).horiz());
} }
} }