Gather data
This commit is contained in:
@@ -188,7 +188,7 @@ public record ExportFormat() {
|
|||||||
|
|
||||||
public record WordOut(Lemma lemma, int startRow, int startCol, String direction, int arrowRow, int arrowCol, boolean isReversed, int complex) {
|
public record WordOut(Lemma lemma, int startRow, int startCol, String direction, int arrowRow, int arrowCol, boolean isReversed, int complex) {
|
||||||
|
|
||||||
public String word() { return new String(lemma().word()); }
|
public String word() { return new String(lemma().word(), java.nio.charset.StandardCharsets.US_ASCII); }
|
||||||
public ArrayList<String> clue() { return lemma.clue(); }
|
public ArrayList<String> clue() { return lemma.clue(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public record SwedishGenerator(int[] buff) {
|
|||||||
static final char C_DASH = '\0';
|
static final char C_DASH = '\0';
|
||||||
static final byte _1 = 49, _9 = 57, A = 65, Z = 90, DASH = (byte) C_DASH;
|
static final byte _1 = 49, _9 = 57, A = 65, Z = 90, DASH = (byte) C_DASH;
|
||||||
static final ThreadLocal<Context> CTX = ThreadLocal.withInitial(Context::new);
|
static final ThreadLocal<Context> CTX = ThreadLocal.withInitial(Context::new);
|
||||||
static boolean isLetter(char ch) { return ch >= 'A' && ch <= 'Z'; }
|
static boolean isLetter(byte b) { return b >= 'A' && b <= 'Z'; }
|
||||||
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)); }
|
||||||
|
|
||||||
public SwedishGenerator() { this(new int[8124]); }
|
public SwedishGenerator() { this(new int[8124]); }
|
||||||
@@ -88,15 +88,15 @@ public record SwedishGenerator(int[] buff) {
|
|||||||
int[] cellCount,
|
int[] cellCount,
|
||||||
int[] stack,
|
int[] stack,
|
||||||
Bit seen,
|
Bit seen,
|
||||||
char[] pattern,
|
byte[] pattern,
|
||||||
IntList[] intListBuffer,
|
IntList[] intListBuffer,
|
||||||
int[] undoBuffer) {
|
int[] undoBuffer) {
|
||||||
|
|
||||||
public Context() {
|
public Context() {
|
||||||
this(new int[SIZE], new int[SIZE], new int[SIZE], new int[SIZE], new Bit(), new char[MAX_WORD_LENGTH], new IntList[MAX_WORD_LENGTH],
|
this(new int[SIZE], new int[SIZE], new int[SIZE], new int[SIZE], new Bit(), new byte[MAX_WORD_LENGTH], new IntList[MAX_WORD_LENGTH],
|
||||||
new int[2048]);
|
new int[2048]);
|
||||||
}
|
}
|
||||||
void setPatter(char[] chars) { System.arraycopy(chars, 0, this.pattern, 0, chars.length); }
|
void setPatter(byte[] chars) { System.arraycopy(chars, 0, this.pattern, 0, chars.length); }
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class Rng {
|
static final class Rng {
|
||||||
@@ -131,6 +131,7 @@ public record SwedishGenerator(int[] buff) {
|
|||||||
static final byte _48 = 48;
|
static final byte _48 = 48;
|
||||||
|
|
||||||
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; }
|
||||||
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; }
|
||||||
@@ -202,15 +203,15 @@ public record SwedishGenerator(int[] buff) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static record Lemma(int index, char[] word, int simpel, ArrayList<String> clue) {
|
static record Lemma(int index, byte[] word, int simpel, ArrayList<String> clue) {
|
||||||
|
|
||||||
static int LEMMA_COUNTER = 0;
|
static int LEMMA_COUNTER = 0;
|
||||||
public Lemma(int index, String word, int simpel, String clu) {
|
public Lemma(int index, String word, int simpel, String clu) {
|
||||||
this(index, word.toCharArray(), simpel, new ArrayList<String>(10));
|
this(index, word.getBytes(StandardCharsets.US_ASCII), simpel, new ArrayList<String>(10));
|
||||||
clue.add(clu);
|
clue.add(clu);
|
||||||
}
|
}
|
||||||
public Lemma(String word, int simpel, String clue) { this(LEMMA_COUNTER++, word, simpel, clue); }
|
public Lemma(String word, int simpel, String clue) { this(LEMMA_COUNTER++, word, simpel, clue); }
|
||||||
char charAt(int idx) { return word[idx]; }
|
byte byteAt(int idx) { return word[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); }
|
||||||
}
|
}
|
||||||
@@ -237,7 +238,7 @@ public record SwedishGenerator(int[] buff) {
|
|||||||
entry.words.add(lemma);
|
entry.words.add(lemma);
|
||||||
|
|
||||||
for (var i = 0; i < L; i++) {
|
for (var i = 0; i < L; i++) {
|
||||||
var letter = lemma.charAt(i) - 'A';
|
var letter = lemma.byteAt(i) - 'A';
|
||||||
if (letter >= 0 && letter < 26) entry.pos[i][letter].add(idx);
|
if (letter >= 0 && letter < 26) entry.pos[i][letter].add(idx);
|
||||||
else throw new RuntimeException("Illegal letter: " + letter + " in word " + lemma);
|
else throw new RuntimeException("Illegal letter: " + letter + " in word " + lemma);
|
||||||
}
|
}
|
||||||
@@ -788,10 +789,10 @@ public record SwedishGenerator(int[] buff) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void patternForSlot(Grid grid, Slot s, char[] pat) {
|
static void patternForSlot(Grid grid, Slot s, byte[] pat) {
|
||||||
for (var i = 0; i < s.len(); i++) {
|
for (var i = 0; i < s.len(); i++) {
|
||||||
var ch = grid.getCharAt(s.pos(i));
|
var ch = grid.byteAt(s.pos(i));
|
||||||
pat[i] = isLetter(ch) ? ch : C_DASH;
|
pat[i] = isLetter(ch) ? ch : DASH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,12 +804,12 @@ public record SwedishGenerator(int[] buff) {
|
|||||||
static int placeWord(Grid grid, Slot s, Lemma w, int[] undoBuffer, int offset) {
|
static int placeWord(Grid grid, Slot s, Lemma w, int[] undoBuffer, int offset) {
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
for (var i = 0; i < s.len(); i++) {
|
for (var i = 0; i < s.len(); i++) {
|
||||||
int idx = s.pos(i);
|
int idx = s.pos(i);
|
||||||
char cur = grid.getCharAt(idx);
|
var cur = grid.byteAt(idx);
|
||||||
var ch = w.charAt(i);
|
var ch = w.byteAt(i);
|
||||||
if (cur == C_DASH) {
|
if (cur == C_DASH) {
|
||||||
mask |= (1 << i);
|
mask |= (1 << i);
|
||||||
grid.setCharAt(idx, ch);
|
grid.setByteAt(idx, ch);
|
||||||
} else if (cur != ch) {
|
} else if (cur != ch) {
|
||||||
for (var j = 0; j < i; j++) {
|
for (var j = 0; j < i; j++) {
|
||||||
if ((mask & (1 << j)) != 0) {
|
if ((mask & (1 << j)) != 0) {
|
||||||
@@ -922,7 +923,7 @@ public record SwedishGenerator(int[] buff) {
|
|||||||
var k = s.key();
|
var k = s.key();
|
||||||
int patLen = s.len();
|
int patLen = s.len();
|
||||||
var entry = dictIndex[patLen];
|
var entry = dictIndex[patLen];
|
||||||
var pat = new char[patLen];
|
var pat = new byte[patLen];
|
||||||
patternForSlot(grid, s, pat);
|
patternForSlot(grid, s, pat);
|
||||||
if (pick.info.indices != null && pick.info.indices.length > 0) {
|
if (pick.info.indices != null && pick.info.indices.length > 0) {
|
||||||
var idxs = pick.info.indices;
|
var idxs = pick.info.indices;
|
||||||
@@ -939,7 +940,7 @@ public record SwedishGenerator(int[] buff) {
|
|||||||
|
|
||||||
boolean match = true;
|
boolean match = true;
|
||||||
for (var i = 0; i < patLen; i++) {
|
for (var i = 0; i < patLen; i++) {
|
||||||
if (pat[i] != C_DASH && pat[i] != w.charAt(i)) {
|
if (pat[i] != DASH && pat[i] != w.byteAt(i)) {
|
||||||
match = false;
|
match = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -978,7 +979,7 @@ public record SwedishGenerator(int[] buff) {
|
|||||||
|
|
||||||
boolean match = true;
|
boolean match = true;
|
||||||
for (var i = 0; i < patLen; i++) {
|
for (var i = 0; i < patLen; i++) {
|
||||||
if (pat[i] != C_DASH && pat[i] != w.charAt(i)) {
|
if (pat[i] != C_DASH && pat[i] != w.byteAt(i)) {
|
||||||
match = false;
|
match = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static puzzle.Main.indentLines;
|
import static puzzle.Main.indentLines;
|
||||||
import static puzzle.SwedishGenerator.C_DASH;
|
import static puzzle.SwedishGenerator.C_DASH;
|
||||||
|
import static puzzle.SwedishGenerator.DASH;
|
||||||
|
|
||||||
public class MainTest {
|
public class MainTest {
|
||||||
|
|
||||||
@@ -101,7 +102,7 @@ public class MainTest {
|
|||||||
Assertions.assertEquals('A', grid.getCharAt(0, 0));
|
Assertions.assertEquals('A', grid.getCharAt(0, 0));
|
||||||
Assertions.assertEquals('5', grid.getCharAt(1, 2));
|
Assertions.assertEquals('5', grid.getCharAt(1, 2));
|
||||||
Assertions.assertEquals('Z', grid.getCharAt(2, 3));
|
Assertions.assertEquals('Z', grid.getCharAt(2, 3));
|
||||||
Assertions.assertEquals(C_DASH, grid.getCharAt(1, 1));
|
Assertions.assertEquals(DASH, grid.byteAt(1, 1));
|
||||||
|
|
||||||
// Test isLetterAt
|
// Test isLetterAt
|
||||||
Assertions.assertTrue(grid.isLetterAt(0, 0));
|
Assertions.assertTrue(grid.isLetterAt(0, 0));
|
||||||
@@ -185,29 +186,20 @@ public class MainTest {
|
|||||||
Assertions.assertEquals(12347, foundSeed, "Found seed changed");
|
Assertions.assertEquals(12347, foundSeed, "Found seed changed");
|
||||||
Assertions.assertEquals(20, res.filled().clueMap().size(), "Number of assigned words changed");
|
Assertions.assertEquals(20, res.filled().clueMap().size(), "Number of assigned words changed");
|
||||||
Assertions.assertEquals(763.8, res.filled().simplicity(), 1e-9, "Simplicity value changed");
|
Assertions.assertEquals(763.8, res.filled().simplicity(), 1e-9, "Simplicity value changed");
|
||||||
Assertions.assertArrayEquals(new char[]{ 'M', 'A', 'N', 'T', 'A' }, res.filled().clueMap().get(1377).word());
|
Assertions.assertArrayEquals(new byte[]{ 'M', 'A', 'N', 'T', 'A' }, res.filled().clueMap().get(1377).word());
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
public void testIsLetterA() {
|
public void testIsLetterA() {
|
||||||
SwedishGenerator generator = new SwedishGenerator();
|
assertTrue(SwedishGenerator.isLetter((byte) 'A'));
|
||||||
assertTrue(generator.isLetter('A'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsLetterZ() {
|
public void testIsLetterZ() {
|
||||||
SwedishGenerator generator = new SwedishGenerator();
|
assertTrue(SwedishGenerator.isLetter((byte) 'Z'));
|
||||||
assertTrue(generator.isLetter('Z'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsNotLetterLowercaseA() {
|
public void testIsNotLetterLowercaseA() {
|
||||||
SwedishGenerator generator = new SwedishGenerator();
|
assertFalse(SwedishGenerator.isLetter((byte) 'a'));
|
||||||
assertFalse(generator.isLetter('a'));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIsNotLetterSymbol() {
|
|
||||||
SwedishGenerator generator = new SwedishGenerator();
|
|
||||||
assertFalse(generator.isLetter('@'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,7 @@ package puzzle;
|
|||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import puzzle.SwedishGenerator.*;
|
import puzzle.SwedishGenerator.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.BitSet;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
@@ -16,40 +13,40 @@ public class SwedishGeneratorTest {
|
|||||||
void testPatternForSlotAllLetters() {
|
void testPatternForSlotAllLetters() {
|
||||||
var grid = new Grid(new byte[]{ 65, 66, 67 }); // A B C
|
var grid = new Grid(new byte[]{ 65, 66, 67 }); // A B C
|
||||||
var slot = Slot.from(0 << 8 | 1 << 4 | 2, ((long) 0) | ((long) 1 << 7) | ((long) 2 << 14), 3);
|
var slot = Slot.from(0 << 8 | 1 << 4 | 2, ((long) 0) | ((long) 1 << 7) | ((long) 2 << 14), 3);
|
||||||
var pattern = new char[3];
|
var pattern = new byte[3];
|
||||||
SwedishGenerator.patternForSlot(grid, slot, pattern);
|
SwedishGenerator.patternForSlot(grid, slot, pattern);
|
||||||
|
|
||||||
assertArrayEquals(new char[]{ 'A', 'B', 'C' }, pattern);
|
assertArrayEquals(new byte[]{ 'A', 'B', 'C' }, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testPatternForSlotMixed() {
|
void testPatternForSlotMixed() {
|
||||||
var grid = new Grid(new byte[]{ 65, (byte) ('0' + 1), 67 }); // A - C
|
var grid = new Grid(new byte[]{ 65, (byte) ('0' + 1), 67 }); // A - C
|
||||||
var slot = Slot.from(0 << 8 | 1 << 4 | 2, ((long) 0) | ((long) 1 << 7) | ((long) 2 << 14), 3);
|
var slot = Slot.from(0 << 8 | 1 << 4 | 2, ((long) 0) | ((long) 1 << 7) | ((long) 2 << 14), 3);
|
||||||
var pattern = new char[3];
|
var pattern = new byte[3];
|
||||||
SwedishGenerator.patternForSlot(grid, slot, pattern);
|
SwedishGenerator.patternForSlot(grid, slot, pattern);
|
||||||
|
|
||||||
assertArrayEquals(new char[]{ 'A', SwedishGenerator.C_DASH, 'C' }, pattern);
|
assertArrayEquals(new byte[]{ 'A', SwedishGenerator.DASH, 'C' }, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testPatternForSlotAllDashes() {
|
void testPatternForSlotAllDashes() {
|
||||||
var grid = new Grid(new byte[]{ (byte) ('0' + 1), (byte) ('0' + 1), (byte) ('0' + 1) }); // - - -
|
var grid = new Grid(new byte[]{ (byte) ('0' + 1), (byte) ('0' + 1), (byte) ('0' + 1) }); // - - -
|
||||||
var slot = Slot.from(0 << 8 | 1 << 4 | 2, ((long) 0) | ((long) 1 << 7) | ((long) 2 << 14), 3);
|
var slot = Slot.from(0 << 8 | 1 << 4 | 2, ((long) 0) | ((long) 1 << 7) | ((long) 2 << 14), 3);
|
||||||
var pattern = new char[3];
|
var pattern = new byte[3];
|
||||||
SwedishGenerator.patternForSlot(grid, slot, pattern);
|
SwedishGenerator.patternForSlot(grid, slot, pattern);
|
||||||
|
|
||||||
assertArrayEquals(new char[]{ SwedishGenerator.C_DASH, SwedishGenerator.C_DASH, SwedishGenerator.C_DASH }, pattern);
|
assertArrayEquals(new byte[]{ SwedishGenerator.DASH, SwedishGenerator.DASH, SwedishGenerator.DASH }, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testPatternForSlotSingleLetter() {
|
void testPatternForSlotSingleLetter() {
|
||||||
var grid = new Grid(new byte[]{ 65, (byte) ('0' + 1), (byte) ('0' + 1) }); // A - -
|
var grid = new Grid(new byte[]{ 65, (byte) ('0' + 1), (byte) ('0' + 1) }); // A - -
|
||||||
var slot = Slot.from(0 << 8 | 1 << 4 | 2, ((long) 0) | ((long) 1 << 7) | ((long) 2 << 14), 3);
|
var slot = Slot.from(0 << 8 | 1 << 4 | 2, ((long) 0) | ((long) 1 << 7) | ((long) 2 << 14), 3);
|
||||||
var pattern = new char[3];
|
var pattern = new byte[3];
|
||||||
SwedishGenerator.patternForSlot(grid, slot, pattern);
|
SwedishGenerator.patternForSlot(grid, slot, pattern);
|
||||||
|
|
||||||
assertArrayEquals(new char[]{ 'A', SwedishGenerator.C_DASH, SwedishGenerator.C_DASH }, pattern);
|
assertArrayEquals(new byte[]{ 'A', SwedishGenerator.DASH, SwedishGenerator.DASH }, pattern);
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
void testRng() {
|
void testRng() {
|
||||||
@@ -106,10 +103,10 @@ public class SwedishGeneratorTest {
|
|||||||
@Test
|
@Test
|
||||||
void testLemmaAndDict() {
|
void testLemmaAndDict() {
|
||||||
var l1 = new Lemma("APPLE", 5, "A fruit");
|
var l1 = new Lemma("APPLE", 5, "A fruit");
|
||||||
Assertions.assertArrayEquals("APPLE".toCharArray(), l1.word());
|
Assertions.assertArrayEquals("APPLE".getBytes(), l1.word());
|
||||||
assertEquals(5, l1.word().length);
|
assertEquals(5, l1.word().length);
|
||||||
assertEquals(5, l1.simpel());
|
assertEquals(5, l1.simpel());
|
||||||
assertEquals('A', l1.charAt(0));
|
assertEquals('A', l1.byteAt(0));
|
||||||
|
|
||||||
var l2 = new Lemma("AXE", 2, "A tool");
|
var l2 = new Lemma("AXE", 2, "A tool");
|
||||||
var dict = new Dict(new Lemma[]{ l1, l2 });
|
var dict = new Dict(new Lemma[]{ l1, l2 });
|
||||||
@@ -119,7 +116,7 @@ public class SwedishGeneratorTest {
|
|||||||
|
|
||||||
var entry3 = dict.index()[3];
|
var entry3 = dict.index()[3];
|
||||||
assertEquals(1, entry3.words().size());
|
assertEquals(1, entry3.words().size());
|
||||||
Assertions.assertArrayEquals("AXE".toCharArray(), entry3.words().getFirst().word());
|
Assertions.assertArrayEquals("AXE".getBytes(), entry3.words().getFirst().word());
|
||||||
|
|
||||||
// Check pos indexing
|
// Check pos indexing
|
||||||
// AXE: A at 0, X at 1, E at 2
|
// AXE: A at 0, X at 1, E at 2
|
||||||
@@ -181,7 +178,7 @@ public class SwedishGeneratorTest {
|
|||||||
|
|
||||||
// Pattern "APP--" for length 5
|
// Pattern "APP--" for length 5
|
||||||
var context = new Context();
|
var context = new Context();
|
||||||
context.setPatter(new char[]{ 'A', 'P', 'P', SwedishGenerator.C_DASH, SwedishGenerator.C_DASH });
|
context.setPatter(new byte[]{ 'A', 'P', 'P', SwedishGenerator.DASH, SwedishGenerator.DASH });
|
||||||
var info = gen.candidateInfoForPattern(context, dict.index()[5], 5);
|
var info = gen.candidateInfoForPattern(context, dict.index()[5], 5);
|
||||||
|
|
||||||
assertEquals(2, info.count());
|
assertEquals(2, info.count());
|
||||||
|
|||||||
Reference in New Issue
Block a user