introduce bitloops
This commit is contained in:
@@ -27,8 +27,6 @@ import static java.nio.charset.StandardCharsets.*;
|
||||
* A) generate randoms for and idx and direction (clue together)
|
||||
* B) convert IDX_PATH_0_BASE into bit-pattern (i think) Length should not be checked, just left empty if not good.
|
||||
* C) store more information in the byte[] even consider the long[] or try sqeeze the 288 options (clue) in a byte.
|
||||
* D) separate clue into three long pairs of hi and lo, (v,h,r) so we do not store the clue anymore in the grid array at all
|
||||
* E) store letter-set also in a long pair so we can use it in path determinations
|
||||
* F) pre-determine random clue arrangements, so they do not involve impossible clue's such as bottom at last or the line before that and such to all sides
|
||||
* G) Check 3wall, the current implementation may be faster, but the accuracy is lower, degrade performance on the filler
|
||||
*/
|
||||
@@ -391,11 +389,8 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
static Slot from(int key, long lo, long hi) { return new Slot(key, lo, hi); }
|
||||
|
||||
public int length() { return Long.bitCount(lo) + Long.bitCount(hi); }
|
||||
public int clueIndex() { return clueIndex(key); }
|
||||
public static int clueIndex(int key) { return key >>> BIT_FOR_DIR; }
|
||||
public static int dir(int key) { return key & 3; }
|
||||
public boolean horiz() { return horiz(key); }
|
||||
public boolean increasing() { return (key & 2) == 0; }
|
||||
public static boolean increasing(int dir) { return (dir & 2) == 0; }
|
||||
public IntStream walk() { return Gridded.walk((byte) key, lo, hi); }
|
||||
public static boolean horiz(int d) { return (d & 1) != 0; }
|
||||
|
||||
@@ -90,10 +90,10 @@ public class MainTest {
|
||||
}
|
||||
@Test
|
||||
public void testHoriz() {
|
||||
assertTrue(Slot.from(1, 0L, 0L).horiz()); // Right
|
||||
assertTrue(Slot.from(3, 0L, 0L).horiz()); // Left
|
||||
assertFalse(Slot.from(0, 0L, 0L).horiz()); // Down
|
||||
assertFalse(Slot.from(2, 0L, 0L).horiz()); // Up
|
||||
assertTrue(Slot.horiz(1)); // Right
|
||||
assertTrue(Slot.horiz(3)); // Left
|
||||
assertFalse(Slot.horiz(0)); // Down
|
||||
assertFalse(Slot.horiz(2)); // Up
|
||||
}
|
||||
@Test
|
||||
public void testGridBasics() {
|
||||
|
||||
@@ -3,6 +3,7 @@ package puzzle;
|
||||
import lombok.val;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import puzzle.Export.Gridded;
|
||||
import puzzle.Export.IntListDTO;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
@@ -81,9 +82,8 @@ public class SwedishGeneratorTest {
|
||||
grid.setLetterLo(0, LETTER_A);
|
||||
grid.setLetterLo(1, LETTER_B);
|
||||
grid.setLetterLo(2, LETTER_C);
|
||||
var slot = Slot.from(18 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
||||
var pattern = patternForSlot(grid, slot.key(), slot.lo(), slot.hi());
|
||||
|
||||
var key = 18 << Slot.BIT_FOR_DIR | (CLUE_RIGHT);
|
||||
var pattern = patternForSlot(grid, key, 7L, 0L);
|
||||
assertEquals(1L | (28L << 8) | (55L << 16), pattern);
|
||||
}
|
||||
|
||||
@@ -92,18 +92,16 @@ public class SwedishGeneratorTest {
|
||||
var grid = createEmpty();
|
||||
grid.setLetterLo(OFF_0_0, LETTER_A);
|
||||
grid.setLetterLo(2, LETTER_C);
|
||||
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
||||
var pattern = patternForSlot(grid, slot.key(), slot.lo(), slot.hi());
|
||||
|
||||
assertEquals(1L | (0L << 8) | (55L << 16), pattern);
|
||||
var key = 1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT);
|
||||
var pattern = patternForSlot(grid, key, 7L, 0L);
|
||||
assertEquals(1L | (0L) | (55L << 16), pattern);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPatternForSlotAllDashes() {
|
||||
var grid = createEmpty();
|
||||
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
||||
var pattern = patternForSlot(grid, slot.key(), slot.lo(), slot.hi());
|
||||
|
||||
var key = 1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT);
|
||||
var pattern = patternForSlot(grid, key, 7L, 0L);
|
||||
assertEquals(0L, pattern);
|
||||
}
|
||||
|
||||
@@ -111,9 +109,8 @@ public class SwedishGeneratorTest {
|
||||
void testPatternForSlotSingleLetter() {
|
||||
var grid = createEmpty();
|
||||
grid.setLetterLo(OFF_0_0, LETTER_A);
|
||||
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
||||
var pattern = patternForSlot(grid, slot.key(), slot.lo(), slot.hi());
|
||||
|
||||
var key = 1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT);
|
||||
var pattern = patternForSlot(grid, key, 7L, 0L);
|
||||
assertEquals(1L, pattern);
|
||||
}
|
||||
@Test
|
||||
@@ -191,12 +188,11 @@ public class SwedishGeneratorTest {
|
||||
// pos 2: (4, 5)
|
||||
lo |= 1L << OFF_4_5;
|
||||
|
||||
var s = Slot.from(key, lo, 0L);
|
||||
System.out.println("[DEBUG_LOG] s.dir() = " + Slot.dir(s.key()));
|
||||
assertEquals(OFF_2_3, s.clueIndex());
|
||||
assertEquals(CLUE_DOWN, Slot.dir(s.key()));
|
||||
assertFalse(s.horiz());
|
||||
var cells = s.walk().toArray();
|
||||
System.out.println("[DEBUG_LOG] s.dir() = " + Slot.dir(key));
|
||||
assertEquals(OFF_2_3, Slot.clueIndex(key));
|
||||
assertEquals(CLUE_DOWN, Slot.dir(key));
|
||||
assertFalse(Slot.horiz(key));
|
||||
var cells = Gridded.walk((byte) key, lo, 0L).toArray();
|
||||
assertEquals(2, SwedishGenerator.IT[cells[0]].r());
|
||||
assertEquals(3, SwedishGenerator.IT[cells[1]].r());
|
||||
assertEquals(4, SwedishGenerator.IT[cells[2]].r());
|
||||
@@ -290,7 +286,7 @@ public class SwedishGeneratorTest {
|
||||
var s = slots[0];
|
||||
|
||||
assertTrue(s.length() >= 2);
|
||||
assertEquals(OFF_0_0, s.clueIndex());
|
||||
assertEquals(OFF_0_0, Slot.clueIndex(s.key()));
|
||||
assertEquals(CLUE_RIGHT, Slot.dir(s.key()));
|
||||
}
|
||||
|
||||
@@ -332,21 +328,21 @@ public class SwedishGeneratorTest {
|
||||
// Slot at OFF_0_0 length 3, horizontal (right)
|
||||
var key = (OFF_0_0 << Slot.BIT_FOR_DIR) | (CLUE_RIGHT);
|
||||
var lo = (1L << OFF_0_0) | (1L << OFF_0_1) | (1L << OFF_0_2);
|
||||
var s = Slot.from(key, lo, 0L);
|
||||
val hi = 0L;
|
||||
var w1 = ABC;
|
||||
|
||||
// 1. Successful placement in empty grid
|
||||
assertTrue(placeWord(grid, s.key(), s.lo(), s.hi(), w1));
|
||||
assertTrue(placeWord(grid, key, lo, hi, w1));
|
||||
assertEquals(LETTER_A, grid.letter32At(OFF_0_0));
|
||||
assertEquals(LETTER_B, grid.letter32At(OFF_0_1));
|
||||
assertEquals(LETTER_C, grid.letter32At(OFF_0_2));
|
||||
|
||||
// 2. Successful placement with partial overlap (same characters)
|
||||
assertTrue(placeWord(grid, s.key(), s.lo(), s.hi(), w1));
|
||||
assertTrue(placeWord(grid, key, lo, hi, w1));
|
||||
|
||||
// 3. Conflict: place "ABD" where "ABC" is
|
||||
var w2 = ABD;
|
||||
assertFalse(placeWord(grid, s.key(), s.lo(), s.hi(), w2));
|
||||
assertFalse(placeWord(grid, key, lo, hi, w2));
|
||||
// Verify grid is unchanged (still "ABC")
|
||||
assertEquals(LETTER_A, grid.letter32At(OFF_0_0));
|
||||
assertEquals(LETTER_B, grid.letter32At(OFF_0_1));
|
||||
@@ -355,7 +351,7 @@ public class SwedishGeneratorTest {
|
||||
// 4. Partial placement then conflict (rollback)
|
||||
grid = createEmpty();
|
||||
grid.setLetterLo(OFF_0_2, LETTER_X); // Conflict at the end
|
||||
assertFalse(placeWord(grid, s.key(), s.lo(), s.hi(), w1));
|
||||
assertFalse(placeWord(grid, key, lo, hi, w1));
|
||||
// Verify grid is still empty (except for 'X')
|
||||
assertFalse(grid.lisLetterAtLo(OFF_0_0));
|
||||
assertFalse(grid.lisLetterAtLo(OFF_0_1));
|
||||
@@ -368,11 +364,10 @@ public class SwedishGeneratorTest {
|
||||
// Slot at 0,1 length 2
|
||||
var key = (OFF_0_0 << Slot.BIT_FOR_DIR) | (CLUE_RIGHT);
|
||||
var lo = (1L << OFF_0_1) | (1L << OFF_0_2);
|
||||
var s = Slot.from(key, lo, 0L);
|
||||
var w = AZ;
|
||||
val low = grid.lo;
|
||||
val top = grid.hi;
|
||||
var placed = placeWord(grid, s.key(), s.lo(), s.hi(), w);
|
||||
var placed = placeWord(grid, key, lo, 0L, w);
|
||||
assertTrue(placed);
|
||||
assertEquals(LETTER_A, grid.letter32At(OFF_0_1));
|
||||
assertEquals(LETTER_Z, grid.letter32At(OFF_0_2));
|
||||
@@ -392,25 +387,21 @@ public class SwedishGeneratorTest {
|
||||
assertTrue(Slot.increasing(CLUE_DOWN)); // Down
|
||||
assertFalse(Slot.increasing(CLUE_UP)); // Up
|
||||
|
||||
var sInc = Slot.from((0) | CLUE_RIGHT, 1L, 0L);
|
||||
assertTrue(Slot.increasing(sInc.key()));
|
||||
var sDec = Slot.from((0) | CLUE_LEFT, 1L, 0L);
|
||||
assertFalse(Slot.increasing(sDec.key()));
|
||||
assertTrue(Slot.increasing((0) | CLUE_RIGHT));
|
||||
assertFalse(Slot.increasing((0) | CLUE_LEFT));
|
||||
|
||||
// 2. Test slotScore
|
||||
val counts = new byte[SIZE];
|
||||
counts[1] = 2;
|
||||
counts[2] = 3;
|
||||
var dict = new Dict(WORDS);
|
||||
var entry5 = dict.index()[5];
|
||||
var sScore = Slot.from(0, (1L << 1) | (1L << 2), 0L);
|
||||
// cross = (counts[1]-1) + (counts[2]-1) = 1 + 2 = 3
|
||||
// score = 3 * 10 + len(2) = 32
|
||||
assertEquals(32, slotScore(counts, sScore));
|
||||
|
||||
// 3. Test candidateCountForPattern
|
||||
|
||||
var dict = new Dict(WORDS);
|
||||
var entry5 = dict.index()[5];
|
||||
|
||||
var ctx = Context.get();
|
||||
var pattern = packPattern("APP");
|
||||
assertEquals(2, candidateCountForPattern(ctx.bitset(), pattern, entry5.posBitsets(), entry5.numlong()));
|
||||
|
||||
Reference in New Issue
Block a user