introduce bitloops
This commit is contained in:
@@ -286,17 +286,17 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
|||||||
/// the pos will never target a clue
|
/// the pos will never target a clue
|
||||||
public byte letter32At(int pos) { return g[pos]; }
|
public byte letter32At(int pos) { return g[pos]; }
|
||||||
void setLetterLo(int idx, byte ch) {
|
void setLetterLo(int idx, byte ch) {
|
||||||
lo &= ~(1L << idx);
|
lo |= (1L << idx);
|
||||||
|
|
||||||
g[idx] = ch;
|
g[idx] = ch;
|
||||||
}
|
}
|
||||||
void setLetterHi(int idx, byte ch) {
|
void setLetterHi(int idx, byte ch) {
|
||||||
hi &= ~(1L << idx & 63);
|
hi |= (1L << (idx & 63));
|
||||||
|
|
||||||
g[idx] = ch;
|
g[idx] = ch;
|
||||||
}
|
}
|
||||||
void setLetter(int idx, byte ch) {
|
void setLetter(int idx, byte ch) {
|
||||||
if ((idx & 64)==0)
|
if ((idx & 64) == 0)
|
||||||
setLetterLo(idx, ch);
|
setLetterLo(idx, ch);
|
||||||
else
|
else
|
||||||
setLetterHi(idx, ch);
|
setLetterHi(idx, ch);
|
||||||
@@ -305,12 +305,12 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
|||||||
private void clearletterLo(int idx) {
|
private void clearletterLo(int idx) {
|
||||||
g[idx] = DASH;
|
g[idx] = DASH;
|
||||||
|
|
||||||
lo |= (1L << idx);
|
lo &= ~(1L << idx);
|
||||||
}
|
}
|
||||||
private void clearletterHi(int idx) {
|
private void clearletterHi(int idx) {
|
||||||
g[idx] = DASH;
|
g[idx] = DASH;
|
||||||
|
|
||||||
hi |= (1L << idx & 63);
|
hi &= ~(1L << (idx & 63));
|
||||||
}
|
}
|
||||||
void undoPlace(long maskLo, long maskHi) {
|
void undoPlace(long maskLo, long maskHi) {
|
||||||
for (long b = maskLo; b != 0; b &= b - 1) clearletterLo(Long.numberOfTrailingZeros(b));
|
for (long b = maskLo; b != 0; b &= b - 1) clearletterLo(Long.numberOfTrailingZeros(b));
|
||||||
@@ -747,47 +747,39 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static long patternForSlot(Grid grid, Slot s) {
|
static long patternForSlot(Grid grid, Slot s) {
|
||||||
if ((s.lo & ~grid.lo) == 0 && (s.hi & ~grid.hi) == 0) {
|
if ((s.lo & grid.lo) == 0 && (s.hi & grid.hi) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
long p = 0;
|
long p = 0;
|
||||||
if (s.increasing()) {
|
if (s.increasing()) {
|
||||||
for (long b = s.lo & ~grid.lo; b != 0; b &= b - 1) {
|
for (long b = s.lo & grid.lo; b != 0; b &= b - 1) {
|
||||||
int idx = Long.numberOfTrailingZeros(b);
|
int idx = Long.numberOfTrailingZeros(b);
|
||||||
byte val = grid.g[idx];
|
byte val = grid.g[idx];
|
||||||
if (val != DASH) {
|
|
||||||
int i = Long.bitCount(s.lo & ((1L << idx) - 1));
|
int i = Long.bitCount(s.lo & ((1L << idx) - 1));
|
||||||
p |= ((long) (i * 26 + val)) << (i << 3);
|
p |= ((long) (i * 26 + val)) << (i << 3);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
int offset = Long.bitCount(s.lo);
|
int offset = Long.bitCount(s.lo);
|
||||||
for (long b = s.hi & ~grid.hi; b != 0; b &= b - 1) {
|
for (long b = s.hi & grid.hi; b != 0; b &= b - 1) {
|
||||||
int idx = Long.numberOfTrailingZeros(b);
|
int idx = Long.numberOfTrailingZeros(b);
|
||||||
byte val = grid.g[64 | idx];
|
byte val = grid.g[64 | idx];
|
||||||
if (val != DASH) {
|
|
||||||
int i = offset + Long.bitCount(s.hi & ((1L << idx) - 1));
|
int i = offset + Long.bitCount(s.hi & ((1L << idx) - 1));
|
||||||
p |= ((long) (i * 26 + val)) << (i << 3);
|
p |= ((long) (i * 26 + val)) << (i << 3);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
int offset = Long.bitCount(s.hi);
|
int offset = Long.bitCount(s.hi);
|
||||||
for (long b = s.hi & ~grid.hi; b != 0; b &= b - 1) {
|
for (long b = s.hi & grid.hi; b != 0; b &= b - 1) {
|
||||||
int idx = Long.numberOfTrailingZeros(b);
|
int idx = Long.numberOfTrailingZeros(b);
|
||||||
byte val = grid.g[64 | idx];
|
byte val = grid.g[64 | idx];
|
||||||
if (val != DASH) {
|
|
||||||
int i = Long.bitCount(s.hi & ~((1L << idx) | ((1L << idx) - 1)));
|
int i = Long.bitCount(s.hi & ~((1L << idx) | ((1L << idx) - 1)));
|
||||||
p |= ((long) (i * 26 + val)) << (i << 3);
|
p |= ((long) (i * 26 + val)) << (i << 3);
|
||||||
}
|
}
|
||||||
}
|
for (long b = s.lo & grid.lo; b != 0; b &= b - 1) {
|
||||||
for (long b = s.lo & ~grid.lo; b != 0; b &= b - 1) {
|
|
||||||
int idx = Long.numberOfTrailingZeros(b);
|
int idx = Long.numberOfTrailingZeros(b);
|
||||||
byte val = grid.g[idx];
|
byte val = grid.g[idx];
|
||||||
if (val != DASH) {
|
|
||||||
int i = offset + Long.bitCount(s.lo & ~((1L << idx) | ((1L << idx) - 1)));
|
int i = offset + Long.bitCount(s.lo & ~((1L << idx) | ((1L << idx) - 1)));
|
||||||
p |= ((long) (i * 26 + val)) << (i << 3);
|
p |= ((long) (i * 26 + val)) << (i << 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
static int slotScore(byte[] count, Slot s) {
|
static int slotScore(byte[] count, Slot s) {
|
||||||
|
|||||||
@@ -109,6 +109,12 @@ public class MainTest {
|
|||||||
Assertions.assertEquals(LETTER_Z, grid.letter32At(OFF_2_3));
|
Assertions.assertEquals(LETTER_Z, grid.letter32At(OFF_2_3));
|
||||||
Assertions.assertEquals(DASH, grid.letter32At(OFF_1_1));
|
Assertions.assertEquals(DASH, grid.letter32At(OFF_1_1));
|
||||||
|
|
||||||
|
// Verify letter mask
|
||||||
|
Assertions.assertTrue((grid.lo & (1L << OFF_0_0)) != 0);
|
||||||
|
Assertions.assertTrue((grid.lo & (1L << OFF_2_3)) != 0);
|
||||||
|
Assertions.assertTrue((grid.lo & (1L << OFF_1_2)) != 0); // Clue also in lo
|
||||||
|
Assertions.assertTrue((grid.lo & (1L << OFF_1_1)) == 0); // Empty letter cell
|
||||||
|
|
||||||
// Test isLetterAt
|
// Test isLetterAt
|
||||||
Assertions.assertTrue(clues.notClue(OFF_0_0));
|
Assertions.assertTrue(clues.notClue(OFF_0_0));
|
||||||
Assertions.assertFalse(clues.notClue(OFF_1_2));
|
Assertions.assertFalse(clues.notClue(OFF_1_2));
|
||||||
@@ -181,8 +187,8 @@ public class MainTest {
|
|||||||
Assertions.assertTrue(filled.ok(), "Puzzle generation failed (not ok)");
|
Assertions.assertTrue(filled.ok(), "Puzzle generation failed (not ok)");
|
||||||
Assertions.assertEquals(18, filled.wordCount(), "Number of assigned words changed");
|
Assertions.assertEquals(18, filled.wordCount(), "Number of assigned words changed");
|
||||||
Assertions.assertEquals("SLEDE", Lemma.asWord(filled.clueMap()[282]));
|
Assertions.assertEquals("SLEDE", Lemma.asWord(filled.clueMap()[282]));
|
||||||
Assertions.assertEquals(74732156493031040L, filled.grid().grid().lo);
|
Assertions.assertEquals(-1L, filled.grid().grid().lo);
|
||||||
Assertions.assertEquals(193L, filled.grid().grid().hi);
|
Assertions.assertEquals(255L, filled.grid().grid().hi);
|
||||||
|
|
||||||
var aa = new PuzzleResult(new Clued(mask), filled).exportFormatFromFilled(1, new Rewards(1, 1, 1));
|
var aa = new PuzzleResult(new Clued(mask), filled).exportFormatFromFilled(1, new Rewards(1, 1, 1));
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,10 @@ public class SwedishGeneratorTest {
|
|||||||
static final byte D_BYTE_2 = CLUE_RIGHT;
|
static final byte D_BYTE_2 = CLUE_RIGHT;
|
||||||
@Test
|
@Test
|
||||||
void testPatternForSlotAllLetters() {
|
void testPatternForSlotAllLetters() {
|
||||||
var grid = new Grid(new byte[]{ LETTER_A, LETTER_B, LETTER_C }, 0, 0);
|
var grid = createEmpty();
|
||||||
|
grid.setLetter(0, LETTER_A);
|
||||||
|
grid.setLetter(1, LETTER_B);
|
||||||
|
grid.setLetter(2, LETTER_C);
|
||||||
var slot = Slot.from(18 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
var slot = Slot.from(18 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
||||||
var pattern = patternForSlot(grid, slot);
|
var pattern = patternForSlot(grid, slot);
|
||||||
|
|
||||||
@@ -86,7 +89,9 @@ public class SwedishGeneratorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testPatternForSlotMixed() {
|
void testPatternForSlotMixed() {
|
||||||
var grid = new Grid(new byte[]{ LETTER_A, DASH, LETTER_C }, 0, 0);
|
var grid = createEmpty();
|
||||||
|
grid.setLetter(0, LETTER_A);
|
||||||
|
grid.setLetter(2, LETTER_C);
|
||||||
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
||||||
var pattern = patternForSlot(grid, slot);
|
var pattern = patternForSlot(grid, slot);
|
||||||
|
|
||||||
@@ -95,7 +100,7 @@ public class SwedishGeneratorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testPatternForSlotAllDashes() {
|
void testPatternForSlotAllDashes() {
|
||||||
var grid = new Grid(new byte[]{ DASH, DASH, DASH }, 0, 0); // - - -
|
var grid = createEmpty();
|
||||||
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
||||||
var pattern = patternForSlot(grid, slot);
|
var pattern = patternForSlot(grid, slot);
|
||||||
|
|
||||||
@@ -104,7 +109,8 @@ public class SwedishGeneratorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testPatternForSlotSingleLetter() {
|
void testPatternForSlotSingleLetter() {
|
||||||
var grid = new Grid(new byte[]{ LETTER_A, DASH, DASH }, 0, 0);
|
var grid = createEmpty();
|
||||||
|
grid.setLetter(0, LETTER_A);
|
||||||
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
||||||
var pattern = patternForSlot(grid, slot);
|
var pattern = patternForSlot(grid, slot);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user