introduce bitloops
This commit is contained in:
@@ -31,10 +31,7 @@ import static java.nio.charset.StandardCharsets.*;
|
||||
@SuppressWarnings("ALL")
|
||||
public record SwedishGenerator(Rng rng) {
|
||||
|
||||
record CandidateInfo(int[] indices, int count) {
|
||||
|
||||
public CandidateInfo(int n) { this(null, n); }
|
||||
}
|
||||
record CandidateInfo(int[] indices, int count) { }
|
||||
|
||||
// static final CandidateInfo[] CANDIDATES = IntStream.range(0, 10192 << 2).mapToObj(CandidateInfo::new).toArray(CandidateInfo[]::new);
|
||||
|
||||
@@ -57,8 +54,6 @@ public record SwedishGenerator(Rng rng) {
|
||||
static final int MAX_WORD_LENGTH_PLUS_ONE = MAX_WORD_LENGTH + 1;
|
||||
static final int MIN_LEN = Config.MIN_LEN;
|
||||
static final int MIN_LEN7 = Config.MIN_LEN * 7;
|
||||
static final int CLUE_SIZE = Config.CLUE_SIZE;
|
||||
static final int SIMPLICITY_DEFAULT_SCORE = 2;
|
||||
static final int MAX_TRIES_PER_SLOT = Config.MAX_TRIES_PER_SLOT;
|
||||
static final char C_DASH = '\0';
|
||||
static final byte _1 = 49, _9 = 57, A = 65, Z = 90, DASH = (byte) C_DASH;
|
||||
@@ -70,11 +65,9 @@ public record SwedishGenerator(Rng rng) {
|
||||
static final byte B0 = (byte) 0;
|
||||
static final byte B64 = (byte) 64;
|
||||
static final byte B48 = (byte) 48;
|
||||
// Directions for '1'..'6'
|
||||
static final long[] OFFSETS_D_IDX = Neighbors9x8.OFFSET_D_IDX;
|
||||
static final nbrs_16[] OFFSETS_FOUR = Neighbors9x8.OFFSETS_FOUR;
|
||||
static final rci[] IT = Neighbors9x8.IT;
|
||||
static final long[] INBR8_PACKEDT = Neighbors9x8.NBR8_PACKED;
|
||||
static final int[][] MUTATE_RI = new int[SIZE][625];
|
||||
static final long[] NBR8_PACKED_LO = Neighbors9x8.NBR8_PACKED_LO;
|
||||
static final long[] NBR8_PACKED_HI = Neighbors9x8.NBR8_PACKED_HI;
|
||||
@@ -233,11 +226,13 @@ public record SwedishGenerator(Rng rng) {
|
||||
|
||||
static record DictEntry(long[] words, long[][] posBitsets) { }
|
||||
|
||||
public static record Lemma(long word) {
|
||||
static int LEMMA_COUNTER = 0;
|
||||
|
||||
public static interface Lemma {
|
||||
|
||||
static final long LETTER_MASK = (1L << 40) - 1; // low 40 bits
|
||||
static final long INDEX_MASK = (1L << 24) - 1; // 24 bits
|
||||
|
||||
static final long LETTER_MASK = (1L << 40) - 1; // low 40 bits
|
||||
static final long INDEX_MASK = (1L << 24) - 1; // 24 bits
|
||||
static int LEMMA_COUNTER = 0;
|
||||
static long pack(String word) { return pack(word.getBytes(US_ASCII)); }
|
||||
static long pack(int index, byte[] b) { return pack(b) | ((long) index << 40); }
|
||||
static long pack(byte[] b) {
|
||||
@@ -245,33 +240,20 @@ public record SwedishGenerator(Rng rng) {
|
||||
for (var i = 0; i < b.length; i++) w |= ((long) b[i] & ~64) << (i * 5);
|
||||
return w;
|
||||
}
|
||||
public Lemma(int index, String word) { this(pack(index, word.getBytes(US_ASCII))); }
|
||||
public Lemma(String word) { this(LEMMA_COUNTER++, word); }
|
||||
static public long from(String word) { return pack(LEMMA_COUNTER++, word.getBytes(US_ASCII)); }
|
||||
static byte byteAt(long word, int idx) { return (byte) ((word >>> (idx * 5)) & 0b11111 | B64); }// word[]; }
|
||||
static int intAt(long word, int idx) { return (int) (((word >>> (idx * 5))) & 0b11111); }// word[]; }
|
||||
static String[] clue(long w) { return CsvIndexService.clues(unpackIndex(w)); }
|
||||
static int simpel(long w) { return CsvIndexService.simpel(unpackIndex(w)); }
|
||||
static int length(long word) {
|
||||
if (word == 0) return 0;
|
||||
int highestBit = 63 - Long.numberOfLeadingZeros(word & LETTER_MASK);
|
||||
return (highestBit / 5) + 1;
|
||||
}
|
||||
static int usedCharsInPattern(long p) {
|
||||
if (p == 0) return 0;
|
||||
int highestBit = 63 - Long.numberOfLeadingZeros(p & LETTER_MASK); // 0-based
|
||||
return (highestBit / 5) + 1;
|
||||
}
|
||||
static int length(long word) { return ((63 - Long.numberOfLeadingZeros(word & LETTER_MASK)) / 5) + 1; }
|
||||
static int usedCharsInPattern(long p) { return ((63 - Long.numberOfLeadingZeros(p & LETTER_MASK)) / 5) + 1; }
|
||||
public static String asWord(long word) {
|
||||
var b = new byte[Lemma.length(word)];
|
||||
for (var i = 0; i < b.length; i++) b[i] = (byte) ((word >>> (i * 5)) & 0b11111 | B64);
|
||||
return new String(b, US_ASCII);
|
||||
}
|
||||
static int unpackIndex(long w) {
|
||||
return (int) (w >>> 40);
|
||||
}
|
||||
static int unpackLetters(long w) {
|
||||
return (int) (w & LETTER_MASK);
|
||||
}
|
||||
static int unpackIndex(long w) { return (int) (w >>> 40); }
|
||||
static int unpackLetters(long w) { return (int) (w & LETTER_MASK); }
|
||||
}
|
||||
|
||||
public static record Dict(
|
||||
|
||||
@@ -31,7 +31,7 @@ public class ExportFormatTest {
|
||||
var clueMap = new HashMap<Integer, Long>();
|
||||
// key = (cellIndex << 4) | direction
|
||||
var key = 2;
|
||||
clueMap.put(key, new Lemma("TEST").word());
|
||||
clueMap.put(key, Lemma.from("TEST"));
|
||||
|
||||
// Manually fill the grid letters for "TEST" at (0,1), (0,2), (0,3), (0,4)
|
||||
grid.setLetter(Grid.offset(0, 1), (byte) 'T');
|
||||
|
||||
@@ -101,19 +101,19 @@ public class SwedishGeneratorTest {
|
||||
|
||||
@Test
|
||||
void testLemmaAndDict() {
|
||||
var l2a = new Lemma("IN").word();
|
||||
var l4a = new Lemma("INER").word();
|
||||
var l6a = new Lemma("INEREN").word();
|
||||
var l7a = new Lemma("INERENA").word();
|
||||
var l8a = new Lemma("INERENAE").word();
|
||||
var l2a = Lemma.from("IN");
|
||||
var l4a = Lemma.from("INER");
|
||||
var l6a = Lemma.from("INEREN");
|
||||
var l7a = Lemma.from("INERENA");
|
||||
var l8a = Lemma.from("INERENAE");
|
||||
|
||||
var l1 = new Lemma("APPLE").word();
|
||||
var l1 = Lemma.from("APPLE");
|
||||
Assertions.assertEquals(Lemma.pack("APPLE".getBytes(StandardCharsets.US_ASCII)), Lemma.unpackLetters(l1));
|
||||
assertEquals(5, Lemma.length(l1));
|
||||
assertEquals((byte) 'A', Lemma.byteAt(l1, 0));
|
||||
assertEquals(1, Lemma.intAt(l1, 0));
|
||||
|
||||
var l2 = new Lemma("AXE").word();
|
||||
var l2 = Lemma.from("AXE");
|
||||
var dict = new Dict(new long[]{ l1, l2, l2a, l4a, l6a, l7a, l8a });
|
||||
|
||||
assertEquals(1, dict.index()[3].words().length);
|
||||
@@ -213,15 +213,15 @@ public class SwedishGeneratorTest {
|
||||
|
||||
@Test
|
||||
void testCandidateInfoForPattern() {
|
||||
var l0 = new Lemma("IN").word();
|
||||
var l3a = new Lemma("INE").word();
|
||||
var l4a = new Lemma("INER").word();
|
||||
var l6a = new Lemma("INEREN").word();
|
||||
var l7a = new Lemma("INERENA").word();
|
||||
var l8a = new Lemma("INERENAE").word();
|
||||
var l1 = new Lemma("APPLE").word();
|
||||
var l2 = new Lemma("APPLY").word();
|
||||
var l3 = new Lemma("BANAN").word();
|
||||
var l0 = Lemma.from("IN");
|
||||
var l3a = Lemma.from("INE");
|
||||
var l4a = Lemma.from("INER");
|
||||
var l6a = Lemma.from("INEREN");
|
||||
var l7a = Lemma.from("INERENA");
|
||||
var l8a = Lemma.from("INERENAE");
|
||||
var l1 = Lemma.from("APPLE");
|
||||
var l2 = Lemma.from("APPLY");
|
||||
var l3 = Lemma.from("BANAN");
|
||||
var dict = new Dict(new long[]{ l0, l1, l2, l3, l3a, l4a, l6a, l7a, l8a });
|
||||
|
||||
// Pattern "APP--" for length 5
|
||||
@@ -309,7 +309,7 @@ public class SwedishGeneratorTest {
|
||||
// r(i) and c(i) are used by placeWord.
|
||||
var packedPos = ((long) Grid.offset(0, 0)) | (((long) Grid.offset(0, 1)) << 7) | (((long) Grid.offset(0, 2)) << 14);
|
||||
var s = Slot.from(0, packedPos, 3);
|
||||
var w1 = new Lemma("ABC").word();
|
||||
var w1 = Lemma.from("ABC");
|
||||
var undoBuffer = new int[10];
|
||||
|
||||
// 1. Successful placement in empty grid
|
||||
@@ -324,7 +324,7 @@ public class SwedishGeneratorTest {
|
||||
assertEquals(0L, undoBuffer[1]); // 0 new characters placed
|
||||
|
||||
// 3. Conflict: place "ABD" where "ABC" is
|
||||
var w2 = new Lemma("ABD").word();
|
||||
var w2 = Lemma.from("ABD");
|
||||
assertFalse(placeWord(grid, s, w2, undoBuffer, 2));
|
||||
// Verify grid is unchanged (still "ABC")
|
||||
assertEquals('A', grid.byteAt(Grid.offset(0, 0)));
|
||||
@@ -347,7 +347,7 @@ public class SwedishGeneratorTest {
|
||||
// Slot at 0,1 length 2
|
||||
var packedPos = ((long) Grid.offset(0, 1)) | (((long) Grid.offset(0, 2)) << 7);
|
||||
var s = Slot.from((0 << 8) | (1 << 4) | 2, packedPos, 2);
|
||||
var w = new Lemma("AZ").word();
|
||||
var w = Lemma.from("AZ");
|
||||
var undoBuffer = new int[10];
|
||||
|
||||
var placed = placeWord(grid, s, w, undoBuffer, 0);
|
||||
|
||||
Reference in New Issue
Block a user