introduce bitloops
This commit is contained in:
@@ -58,7 +58,11 @@ public record Export() {
|
||||
}
|
||||
|
||||
record Gridded(@Delegate Grid grid) {
|
||||
|
||||
public boolean lisLetterAt(int pos) {
|
||||
if ((pos & 64) == 0)
|
||||
return lisLetterAtLo(pos);
|
||||
return lisLetterAtHi(pos);
|
||||
}
|
||||
public static IntStream walk(byte base, long lo, long hi) {
|
||||
if (Slot.increasing(base)) {
|
||||
return IntStream.concat(
|
||||
@@ -119,7 +123,7 @@ public record Export() {
|
||||
var offset = Grid.offset(r, c);
|
||||
if (clues.isClue(offset))
|
||||
sb.append((char) (48 | clues.digitAt(offset)));
|
||||
else if (grid.lisLetterAt(offset))
|
||||
else if (lisLetterAt(offset))
|
||||
sb.append((char) (64 | grid.letter32At(offset)));
|
||||
else
|
||||
sb.append(' ');
|
||||
@@ -144,7 +148,7 @@ public record Export() {
|
||||
var offset = Grid.offset(r, c);
|
||||
if (clues.isClue(offset)) {
|
||||
sb.append(clueChar.replace(new Cell(grid, clues, offset, clues.digitAt(offset))));
|
||||
} else if (grid.lisLetterAt(offset)) {
|
||||
} else if (lisLetterAt(offset)) {
|
||||
sb.append(NOT_CLUE_NOT_LETTER_TO(grid.letter32At(offset)));
|
||||
} else {
|
||||
sb.append(emptyFallback);
|
||||
@@ -192,7 +196,6 @@ public record Export() {
|
||||
|
||||
public record PuzzleResult(Clued mask, FillResult filled) {
|
||||
|
||||
boolean inBounds(int idx) { return idx >= 0 && idx < SwedishGenerator.SIZE; }
|
||||
Placed extractPlacedFromSlot(Slot s, long lemma) { return new Placed(lemma, s.key(), s.walk().toArray()); }
|
||||
public ExportedPuzzle exportFormatFromFilled(int difficulty, Rewards rewards) {
|
||||
var g = filled().grid();
|
||||
@@ -236,7 +239,6 @@ public record Export() {
|
||||
var letterAt = new HashMap<Integer, Character>();
|
||||
for (var p : placed) {
|
||||
for (var c : p.cells) {
|
||||
if (!inBounds(c)) throw new RuntimeException();
|
||||
if (mask.notClue(c) && g.lisLetterAt(c)) {
|
||||
letterAt.put(c, (char) (64 | g.letter32At(c)));
|
||||
}
|
||||
|
||||
@@ -277,12 +277,6 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
static int offset(int r, int c) { return r | (c << 3); }
|
||||
/// the pos will never target a clue
|
||||
public byte letter32At(int pos) { return g[pos]; }
|
||||
public boolean lisLetterAt(int pos) {
|
||||
if ((pos & 64) == 0)
|
||||
return lisLetterAtLo(pos);
|
||||
return lisLetterAtHi(pos);
|
||||
}
|
||||
|
||||
public boolean lisLetterAtLo(int pos) { return (lo & (1L << pos)) != X; }
|
||||
public boolean lisLetterAtHi(int pos) { return (hi & (1L << (pos & 63))) != X; }
|
||||
void setLetterLo(int idx, byte ch) {
|
||||
@@ -387,11 +381,11 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
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; }
|
||||
public static int packSlotDir(int idx, int d) { return (idx << BIT_FOR_DIR) | d; }
|
||||
public static int packSlotKey(int idx, int d) { return (idx << BIT_FOR_DIR) | d; }
|
||||
}
|
||||
|
||||
private static void processSlot(Clues grid, SlotVisitor visitor, int idx) {
|
||||
int key = Slot.packSlotDir(idx, grid.digitAt(idx)); // 0..3
|
||||
int key = Slot.packSlotKey(idx, grid.digitAt(idx)); // 0..3
|
||||
|
||||
long rayLo = PATH_LO[key];
|
||||
long rayHi = PATH_HI[key];
|
||||
@@ -451,7 +445,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
int clueIdx = Long.numberOfTrailingZeros(lsb);
|
||||
int v = (grid.vlo & lsb) != 0 ? 1 : 0;
|
||||
int r = (grid.rlo & lsb) != 0 ? 1 : 0;
|
||||
int key = Slot.packSlotDir(clueIdx, (r << 1) | v);
|
||||
int key = Slot.packSlotKey(clueIdx, (r << 1) | v);
|
||||
long rLo = PATH_LO[key], rHi = PATH_HI[key];
|
||||
long hLo = rLo & lo_cl, hHi = rHi & hi_cl;
|
||||
if (Slot.increasing(key)) {
|
||||
@@ -488,7 +482,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
int clueIdx = Long.numberOfTrailingZeros(lsb);
|
||||
int v = (grid.vhi & lsb) != 0 ? 1 : 0;
|
||||
int r = (grid.rhi & lsb) != 0 ? 1 : 0;
|
||||
int key = Slot.packSlotDir(64 | clueIdx, (r << 1) | v);
|
||||
int key = Slot.packSlotKey(64 | clueIdx, (r << 1) | v);
|
||||
long rLo = PATH_LO[key], rHi = PATH_HI[key];
|
||||
long hLo = rLo & lo_cl, hHi = rHi & hi_cl;
|
||||
if (Slot.increasing(key)) {
|
||||
@@ -612,7 +606,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
idx = rng.randint(0, SIZE_MIN_1);
|
||||
if (g.isClue(idx)) continue;
|
||||
var d_idx = rng.randint2bitByte();
|
||||
if (g.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotDir(idx, d_idx)])) {
|
||||
if (g.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotKey(idx, d_idx)])) {
|
||||
g.setClue(idx, d_idx);
|
||||
placed++;
|
||||
}
|
||||
@@ -626,7 +620,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
ri = bytes[rng.randint(0, 624)];
|
||||
if (!c.clueless(ri)) {
|
||||
var d_idx = rng.randint2bitByte();
|
||||
if (c.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotDir(ri, d_idx)])) c.setClue(ri, d_idx);
|
||||
if (c.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotKey(ri, d_idx)])) c.setClue(ri, d_idx);
|
||||
}
|
||||
}
|
||||
return c;
|
||||
@@ -657,7 +651,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
for (var hi = out.hi; hi != X; hi &= hi - 1L) clearClues(out, 64 | Long.numberOfTrailingZeros(hi));
|
||||
return out;
|
||||
}
|
||||
public static void clearClues(Clues out, int idx) { if (!out.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotDir(idx, out.digitAt(idx))])) out.clearClue(idx); }
|
||||
public static void clearClues(Clues out, int idx) { if (!out.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotKey(idx, out.digitAt(idx))])) out.clearClue(idx); }
|
||||
|
||||
Clues hillclimb(Clues start, int limit) {
|
||||
var best = start;
|
||||
|
||||
@@ -82,7 +82,7 @@ public class SwedishGeneratorTest {
|
||||
grid.setLetterLo(0, LETTER_A);
|
||||
grid.setLetterLo(1, LETTER_B);
|
||||
grid.setLetterLo(2, LETTER_C);
|
||||
var key = 18 << Slot.BIT_FOR_DIR | (CLUE_RIGHT);
|
||||
var key = Slot.packSlotKey(18, CLUE_RIGHT);
|
||||
var pattern = patternForSlot(grid, key, 7L, 0L);
|
||||
assertEquals(1L | (28L << 8) | (55L << 16), pattern);
|
||||
}
|
||||
@@ -92,7 +92,7 @@ public class SwedishGeneratorTest {
|
||||
var grid = createEmpty();
|
||||
grid.setLetterLo(OFF_0_0, LETTER_A);
|
||||
grid.setLetterLo(2, LETTER_C);
|
||||
var key = 1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT);
|
||||
var key = Slot.packSlotKey(1, CLUE_RIGHT);
|
||||
var pattern = patternForSlot(grid, key, 7L, 0L);
|
||||
assertEquals(1L | (0L) | (55L << 16), pattern);
|
||||
}
|
||||
@@ -100,7 +100,7 @@ public class SwedishGeneratorTest {
|
||||
@Test
|
||||
void testPatternForSlotAllDashes() {
|
||||
var grid = createEmpty();
|
||||
var key = 1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT);
|
||||
var key = Slot.packSlotKey(1 << Slot.BIT_FOR_DIR, CLUE_RIGHT);
|
||||
var pattern = patternForSlot(grid, key, 7L, 0L);
|
||||
assertEquals(0L, pattern);
|
||||
}
|
||||
@@ -109,7 +109,7 @@ public class SwedishGeneratorTest {
|
||||
void testPatternForSlotSingleLetter() {
|
||||
var grid = createEmpty();
|
||||
grid.setLetterLo(OFF_0_0, LETTER_A);
|
||||
var key = 1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT);
|
||||
var key = Slot.packSlotKey(1, CLUE_RIGHT);
|
||||
var pattern = patternForSlot(grid, key, 7L, 0L);
|
||||
assertEquals(1L, pattern);
|
||||
}
|
||||
@@ -164,12 +164,6 @@ public class SwedishGeneratorTest {
|
||||
var entry3 = dict.index()[3];
|
||||
assertEquals(1, entry3.words().length);
|
||||
assertEquals(Lemma.pack("AXE".getBytes(StandardCharsets.US_ASCII)), Lemma.unpackLetters(entry3.words()[0]));
|
||||
|
||||
// Check pos indexing
|
||||
// AXE: A at 0, X at 1, E at 2
|
||||
/* assertTrue(entry3.pos()[0][0].size() > 0);
|
||||
assertTrue(entry3.pos()[1]['X' - 'A'].size() > 0);
|
||||
assertTrue(entry3.pos()[2]['E' - 'A'].size() > 0);*/
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -178,7 +172,7 @@ public class SwedishGeneratorTest {
|
||||
// key = (r << 8) | (c << 4) | d
|
||||
var offset = OFF_2_3;
|
||||
System.out.println("[DEBUG_LOG] Grid.offset(2, 3) = " + offset);
|
||||
var key = (offset << Slot.BIT_FOR_DIR) | (CLUE_DOWN);
|
||||
var key = Slot.packSlotKey(offset, CLUE_DOWN);
|
||||
System.out.println("[DEBUG_LOG] key = " + key);
|
||||
long lo = 0;
|
||||
// pos 0: (2, 5)
|
||||
@@ -203,54 +197,6 @@ public class SwedishGeneratorTest {
|
||||
assertTrue(Slot.horiz(CLUE_RIGHT)); // right
|
||||
assertFalse(Slot.horiz(CLUE_DOWN)); // down
|
||||
}
|
||||
static int intersectSorted(int[] a, int aLen, int[] b, int bLen, int[] out) {
|
||||
if (aLen == 0 || bLen == 0) return 0;
|
||||
if (aLen < bLen >>> 4) {
|
||||
var k = 0;
|
||||
for (var i = 0; i < aLen; i++) {
|
||||
var x = a[i];
|
||||
if (Arrays.binarySearch(b, 0, bLen, x) >= 0) out[k++] = x;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
if (bLen < aLen >>> 4) {
|
||||
var k = 0;
|
||||
for (var i = 0; i < bLen; i++) {
|
||||
var y = b[i];
|
||||
if (Arrays.binarySearch(a, 0, aLen, y) >= 0) out[k++] = y;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
int i = 0, j = 0, k = 0, x, y;
|
||||
while (i < aLen && j < bLen) {
|
||||
x = a[i];
|
||||
y = b[j];
|
||||
if (x == y) {
|
||||
out[k++] = x;
|
||||
i++;
|
||||
j++;
|
||||
} else if (x < y) i++;
|
||||
else j++;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIntersectSorted() {
|
||||
var buff = new int[10];
|
||||
var a = new int[]{ 1, 3, 5, 7, 9 };
|
||||
var b = new int[]{ 2, 3, 6, 7, 10 };
|
||||
|
||||
var count = intersectSorted(a, a.length, b, b.length, buff);
|
||||
assertEquals(2, count);
|
||||
assertEquals(3, buff[0]);
|
||||
assertEquals(7, buff[1]);
|
||||
|
||||
var c = new int[]{ 1, 2, 3 };
|
||||
var d = new int[]{ 4, 5, 6 };
|
||||
count = intersectSorted(c, c.length, d, d.length, buff);
|
||||
assertEquals(0, count);
|
||||
}
|
||||
|
||||
static long packPattern(String s) {
|
||||
long p = 0;
|
||||
@@ -258,7 +204,7 @@ public class SwedishGeneratorTest {
|
||||
for (var i = 0; i < b.length; i++) {
|
||||
var val = b[i] & 31;
|
||||
if (val != 0) {
|
||||
p |= (long) (i * 26 + val) << (i << 3);
|
||||
p |= (i * 26L + val) << (i << 3);
|
||||
}
|
||||
}
|
||||
return p;
|
||||
@@ -326,7 +272,7 @@ public class SwedishGeneratorTest {
|
||||
void testPlaceWord() {
|
||||
var grid = createEmpty();
|
||||
// Slot at OFF_0_0 length 3, horizontal (right)
|
||||
var key = (OFF_0_0 << Slot.BIT_FOR_DIR) | (CLUE_RIGHT);
|
||||
var key = Slot.packSlotKey(0, CLUE_RIGHT);
|
||||
var lo = (1L << OFF_0_0) | (1L << OFF_0_1) | (1L << OFF_0_2);
|
||||
val hi = 0L;
|
||||
var w1 = ABC;
|
||||
@@ -362,7 +308,7 @@ public class SwedishGeneratorTest {
|
||||
void testBacktrackingHelpers() {
|
||||
var grid = createEmpty();
|
||||
// Slot at 0,1 length 2
|
||||
var key = (OFF_0_0 << Slot.BIT_FOR_DIR) | (CLUE_RIGHT);
|
||||
var key = Slot.packSlotKey(0, CLUE_RIGHT);
|
||||
var lo = (1L << OFF_0_1) | (1L << OFF_0_2);
|
||||
var w = AZ;
|
||||
val low = grid.lo;
|
||||
@@ -387,8 +333,8 @@ public class SwedishGeneratorTest {
|
||||
assertTrue(Slot.increasing(CLUE_DOWN)); // Down
|
||||
assertFalse(Slot.increasing(CLUE_UP)); // Up
|
||||
|
||||
assertTrue(Slot.increasing((0) | CLUE_RIGHT));
|
||||
assertFalse(Slot.increasing((0) | CLUE_LEFT));
|
||||
assertTrue(Slot.increasing(Slot.packSlotKey(0, CLUE_RIGHT)));
|
||||
assertFalse(Slot.increasing(Slot.packSlotKey(0, CLUE_LEFT)));
|
||||
|
||||
// 2. Test slotScore
|
||||
val counts = new byte[SIZE];
|
||||
|
||||
Reference in New Issue
Block a user