Gather data

This commit is contained in:
mike
2026-01-07 00:30:47 +01:00
parent 5c5462085c
commit 243935e73a
4 changed files with 55 additions and 67 deletions

View File

@@ -123,7 +123,7 @@ public final class ExportFormat {
List<int[]> cells = new ArrayList<>(); List<int[]> cells = new ArrayList<>();
for (int i = 0; i < s.len(); i++) { for (int i = 0; i < s.len(); i++) {
cells.add(new int[]{ s.rs()[i], s.cs()[i] }); cells.add(new int[]{ s.r(i), s.c(i) });
} }
// Canonicalize: always output right/down // Canonicalize: always output right/down

View File

@@ -160,14 +160,14 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
static record Lemma(int index, String word, int length, int simpel, ArrayList<String> clue) { static record Lemma(int index, String word, int length, int simpel, ArrayList<String> clue) {
static int LEMMA_COUNTER = 0; static int LEMMA_COUNTER = 0;
public Lemma(int index, String word, int simpel, int score, String clu) { public Lemma(int index, String word, int simpel, String clu) {
this(index, word, word.length(), simpel, new ArrayList<String>(10)); this(index, word, word.length(), simpel, new ArrayList<String>(10));
clue.add(clu); clue.add(clu);
} }
public Lemma(String word, int simpel, int score, String clue) { this(LEMMA_COUNTER++, word, simpel, score, clue); } public Lemma(String word, int simpel, String clue) { this(LEMMA_COUNTER++, word, simpel, clue); }
char charAt(int idx) { return word.charAt(idx); } char charAt(int idx) { return word.charAt(idx); }
@Override public int hashCode() { return index; } @Override public int hashCode() { return index; }
@Override public boolean equals(Object o) { return (o == this) || (o instanceof Lemma l && l.index == index); } @Override public boolean equals(Object o) { return (o == this) || (o instanceof Lemma l && l.index == index); }
} }
public static record Dict(Lemma[] wordz, public static record Dict(Lemma[] wordz,
@@ -237,7 +237,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
if (map.containsKey(s)) { if (map.containsKey(s)) {
map.get(s).clue.add(rawClue); map.get(s).clue.add(rawClue);
} else { } else {
map.put(s, new Lemma(s, simpel, score, rawClue)); map.put(s, new Lemma(s, simpel, rawClue));
} }
} }
} else { } else {
@@ -277,7 +277,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
} }
var first = lists.get(0); var first = lists.get(0);
var cur = Arrays.copyOf(first.data(), first.size()); var cur = first.data();//Arrays.copyOf(first.data(), first.size());
var curLen = cur.length; var curLen = cur.length;
for (var k = 1; k < lists.size(); k++) { for (var k = 1; k < lists.size(); k++) {
@@ -291,11 +291,14 @@ 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(String key, int clueR, int clueC, int dir, int[] rs, int[] cs, int len, boolean horiz) { static record Slot(String key, int clueR, int clueC, int dir, long rs, long cs, int len, boolean horiz) {
public Slot(int clueR, int clueC, int d, int[] rs, int[] cs) { public Slot(int clueR, int clueC, int d, long rs, long cs, int len) {
this(clueR + "," + clueC + ":" + d, clueR, clueC, d, rs, cs, rs.length, d == 2 || d == 4); this(clueR + "," + clueC + ":" + d, clueR, clueC, d, rs, cs, len, 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) {
@@ -311,21 +314,21 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
if (rr < 0 || rr >= H || cc < 0 || cc >= W) continue; if (rr < 0 || rr >= H || cc < 0 || cc >= W) continue;
if (grid.isDigitAt(rr, cc)) continue; if (grid.isDigitAt(rr, cc)) continue;
var rs = new int[MAX_LEN + 1]; long packedRs = 0;
var cs = new int[MAX_LEN + 1]; long packedCs = 0;
var n = 0; var n = 0;
while (rr >= 0 && rr < H && cc >= 0 && cc < W) { while (rr >= 0 && rr < H && cc >= 0 && cc < W) {
if (grid.isDigitAt(rr, cc)) break; if (grid.isDigitAt(rr, cc)) break;
rs[n] = rr; packedRs |= (long) rr << (n << 2);
cs[n] = cc; packedCs |= (long) cc << (n << 2);
n++; n++;
rr += dr; rr += dr;
cc += dc; cc += dc;
if (n > MAX_LEN) break; if (n >= 12) break;
} }
slots.add(new Slot(r, c, d, Arrays.copyOf(rs, n), Arrays.copyOf(cs, n))); slots.add(new Slot(r, c, d, packedRs, packedCs, n));
} }
} }
return slots; return slots;
@@ -369,7 +372,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
} }
for (var i = 0; i < s.len; i++) { for (var i = 0; i < s.len; i++) {
int r = s.rs[i], c = s.cs[i]; int r = s.r(i), c = s.c(i);
if (s.horiz) covH[r][c] += 1; if (s.horiz) covH[r][c] += 1;
else covV[r][c] += 1; else covV[r][c] += 1;
} }
@@ -609,7 +612,7 @@ 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.rs[i], s.cs[i]); var ch = grid.getCharAt(s.r(i), s.c(i));
if (isLetter(ch)) pat[i] = ch; if (isLetter(ch)) pat[i] = ch;
} }
return pat; return pat;
@@ -617,7 +620,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
static int slotScore(int[][] cellCount, Slot s) { static int slotScore(int[][] cellCount, Slot s) {
var cross = 0; var cross = 0;
for (var i = 0; i < s.len; i++) cross += (cellCount[s.rs[i]][s.cs[i]] - 1); for (var i = 0; i < s.len; i++) cross += (cellCount[s.r(i)][s.c(i)] - 1);
return cross * 10 + s.len; return cross * 10 + s.len;
} }
@@ -629,7 +632,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
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.rs[i], c = s.cs[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);
if (cur == C_DASH) { if (cur == C_DASH) {
@@ -666,7 +669,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
var assigned = new HashMap<String, Lemma>(); var assigned = new HashMap<String, Lemma>();
var cellCount = new int[H][W]; var cellCount = new int[H][W];
for (var s : slots) for (var i = 0; i < s.len; i++) cellCount[s.rs[i]][s.cs[i]]++; for (var s : slots) for (var i = 0; i < s.len; i++) cellCount[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);
@@ -764,7 +767,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN, int[] buff)
if (used.get(w.index())) return false; if (used.get(w.index())) return false;
for (var i = 0; i < pat.length; i++) { for (var i = 0; i < pat.length; i++) {
// if ((pat[i] != w.charAt(i)) != (pat[i] != C_DASH)) throw new RuntimeException("word does not match pattern"); // if ((pat[i] != w.charAt(i)) != (pat[i] != C_DASH)) throw new RuntimeException("word does not match pattern");
if (pat[i] != C_DASH && pat[i] != w.charAt(i)) return false; if (pat[i] != C_DASH && pat[i] != w.charAt(i)) return false;
} }

View File

@@ -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, 100, "NU"), new Lemma(0, "NU", 1, "NU"),
new Lemma(1, "ET", 2, 100, "ET"), new Lemma(1, "ET", 2, "ET"),
new Lemma(2, "NUT", 3, 1001, "NUT"), new Lemma(2, "NUT", 3, "NUT"),
new Lemma(3, "ETE", 4, 100, "ETE"), new Lemma(3, "ETE", 4, "ETE"),
new Lemma(4, "IK", 5, 100, "IK"), new Lemma(4, "IK", 5, "IK"),
new Lemma(5, "IN", 6, 100, "IN"), new Lemma(5, "IN", 6, "IN"),
new Lemma(6, "AU", 7, 100, "AU"), new Lemma(6, "AU", 7, "AU"),
new Lemma(7, "JE", 8, 100, "JE"), new Lemma(7, "JE", 8, "JE"),
new Lemma(8, "AI", 9, 100, "AI"), new Lemma(8, "AI", 9, "AI"),
new Lemma(9, "NA", 10, 100, "NA"), new Lemma(9, "NA", 10, "NA"),
new Lemma(10, "AF", 11, 100, "AF"), new Lemma(10, "AF", 11, "AF"),
new Lemma(11, "AL", 14, 1001, "AL"), new Lemma(11, "AL", 14, "AL"),
new Lemma(12, "EA", 15, 100, "EA"), new Lemma(12, "EA", 15, "EA"),
new Lemma(13, "AV", 18, 100, "AV"), new Lemma(13, "AV", 18, "AV"),
new Lemma(14, "IL", 19, 100, "IL"), new Lemma(14, "IL", 19, "IL"),
new Lemma(15, "EN", 22, 100, "EN") new Lemma(15, "EN", 22, "EN")
}); });
// Act // Act

View File

@@ -5,6 +5,7 @@ import puzzle.SwedishGenerator.Grid;
import puzzle.SwedishGenerator.Slot; import puzzle.SwedishGenerator.Slot;
import java.util.ArrayList; import java.util.ArrayList;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
class SwedishGeneratorTest { class SwedishGeneratorTest {
@@ -14,34 +15,18 @@ class SwedishGeneratorTest {
Grid grid = generator.makeEmptyGrid(); Grid grid = generator.makeEmptyGrid();
// Set up digits on the grid to create slots. // Set up digits on the grid to create slots.
for (int r = 0; r < 3; r++) { // '2' (right) at (0,0) -> slot at (0,1), (0,2)
for (int c = 0; c < 3; c++) { grid.setCharAt(0, 0, '2');
if ((r + c) % 2 == 0) { grid.setCharAt(0, 1, 'A');
grid.setCharAt(r, c, '1'); grid.setCharAt(0, 2, 'B');
}
}
}
// Set up letter cells around digits to form valid slots.
int[][] directions = { { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -1 }, { 0, 1 }, { 1, -1 }, { 1, 0 } };
for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) {
if (grid.isDigitAt(r, c)) {
int dr = directions[grid.digitAt(r, c)][0];
int dc = directions[grid.digitAt(r, c)][1];
int rr = r + dr;
int cc = c + dc;
if (rr >= 0 && rr < generator.H() && cc >= 0 && cc < generator.W())
grid.setCharAt(rr, cc, 'A');
}
}
}
// Check the extractSlots method.
ArrayList<Slot> slots = generator.extractSlots(grid); ArrayList<Slot> slots = generator.extractSlots(grid);
assertEquals(3, slots.size()); assertEquals(1, slots.size());
Slot s = slots.get(0);
assertEquals(2, s.len());
assertEquals(0, s.r(0));
assertEquals(1, s.c(0));
assertEquals(0, s.r(1));
assertEquals(2, s.c(1));
} }
} }