introduce bitloops
This commit is contained in:
@@ -38,7 +38,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
|
||||
public CandidateInfo(int n) { this(null, n); }
|
||||
}
|
||||
|
||||
|
||||
// static final CandidateInfo[] CANDIDATES = IntStream.range(0, 10192 << 2).mapToObj(CandidateInfo::new).toArray(CandidateInfo[]::new);
|
||||
|
||||
//@formatter:off
|
||||
@@ -121,22 +121,20 @@ public record SwedishGenerator(Rng rng) {
|
||||
}
|
||||
}
|
||||
|
||||
static record Context(int[] covH,
|
||||
int[] covV,
|
||||
int[] cellCount,
|
||||
int[] stack,
|
||||
Bit seen,
|
||||
byte[] pattern,
|
||||
IntList[] intListBuffer,
|
||||
int[] undo,
|
||||
int[] inter1,
|
||||
int[] inter2) {
|
||||
static final class Context {
|
||||
|
||||
public Context() {
|
||||
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[160000], new int[160000]);
|
||||
}
|
||||
void setPatter(byte[] chars) { System.arraycopy(chars, 0, this.pattern, 0, chars.length); }
|
||||
final int[] covH = new int[SIZE];
|
||||
final int[] covV = new int[SIZE];
|
||||
final int[] cellCount = new int[SIZE];
|
||||
final int[] stack = new int[SIZE];
|
||||
final Bit seen = new Bit();
|
||||
long pattern;
|
||||
final IntList[] intListBuffer = new IntList[MAX_WORD_LENGTH];
|
||||
final int[] undo = new int[2048];
|
||||
final int[] inter1 = new int[160000];
|
||||
final int[] inter2 = new int[160000];
|
||||
|
||||
void setPattern(long p) { this.pattern = p; }
|
||||
}
|
||||
|
||||
static final class Rng {
|
||||
@@ -364,7 +362,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
public int dir() { return key & 7; }
|
||||
public boolean horiz() { return horiz(key); }
|
||||
public int pos(int i) { return offset(packedPos, i); }
|
||||
public static boolean horiz(int key) { return (key & 1) == 0/*((key & 15) & 1) == 0*/; }
|
||||
public static boolean horiz(int key) { return (key & 1) == 0; }
|
||||
public static int offset(long packedPos, int i) { return (int) ((packedPos >> (i * 7)) & 127); }
|
||||
public static int packSlotDir(int idx, int d) { return (idx << BIT_FOR_DIR) | d; }
|
||||
}
|
||||
@@ -415,7 +413,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
Arrays.fill(covH, 0, SIZE, 0);
|
||||
Arrays.fill(covV, 0, SIZE, 0);
|
||||
long lo_cl = grid.lo, hi_cl = grid.hi;
|
||||
long penalty = (((long) Math.abs(grid.clueCount() - TARGET_CLUES)) << 3);
|
||||
long penalty = (((long) Math.abs(grid.clueCount() - TARGET_CLUES)) * 16000L);
|
||||
boolean hasSlots = false;
|
||||
|
||||
for (int i = 0; i < 65; i += 64) {
|
||||
@@ -434,6 +432,8 @@ public record SwedishGenerator(Rng rng) {
|
||||
if (k > 0) {
|
||||
hasSlots = true;
|
||||
if (k < MIN_LEN7) penalty += 8000;
|
||||
} else {
|
||||
penalty += 25000;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -615,12 +615,15 @@ public record SwedishGenerator(Rng rng) {
|
||||
//return pop.get(0).grid;
|
||||
return best.grid;
|
||||
}
|
||||
static void patternForSlot(Grid grid, Slot s, byte[] pat) {
|
||||
byte ch;
|
||||
static long patternForSlot(Grid grid, Slot s) {
|
||||
long p = 0;
|
||||
for (int i = 0, len = s.len(); i < len; i++) {
|
||||
ch = grid.byteAt(s.pos(i));
|
||||
pat[i] = isLetter(ch) ? ch : DASH;
|
||||
byte ch = grid.byteAt(s.pos(i));
|
||||
if (isLetter(ch)) {
|
||||
p |= ((long) (ch & 31)) << (i * 5);
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static int slotScore(int[] count, Slot s) {
|
||||
@@ -656,11 +659,10 @@ public record SwedishGenerator(Rng rng) {
|
||||
var listBuffer = ctx.intListBuffer;
|
||||
var listCount = 0;
|
||||
IntList tmp;
|
||||
byte ch;
|
||||
for (var i = 0; i < len; i++) {
|
||||
ch = pattern[i];
|
||||
if (isLetter(ch)) {
|
||||
listBuffer[listCount++] = entry.pos[i][ch - 'A'];
|
||||
int val = (int) ((pattern >>> (i * 5)) & 31);
|
||||
if (val != 0) {
|
||||
listBuffer[listCount++] = entry.pos[i][val - 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,7 +756,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
if (assigned[s.key()] != null) continue;
|
||||
var entry = dictIndex[s.len()];
|
||||
if (entry == null) return PICK_NOT_DONE;
|
||||
patternForSlot(grid, s, ctx.pattern);
|
||||
ctx.pattern = patternForSlot(grid, s);
|
||||
var info = candidateInfoForPattern(ctx, entry, s.len());
|
||||
|
||||
if (info.count == 0) return PICK_NOT_DONE;
|
||||
|
||||
@@ -166,10 +166,10 @@ public class MainTest {
|
||||
|
||||
// Regression baseline for seed search starting at 12347, pop 4, gens 20
|
||||
Assertions.assertEquals(12348, foundSeed, "Found seed changed");
|
||||
Assertions.assertEquals(22, res.filled().clueMap().size(), "Number of assigned words changed");
|
||||
Assertions.assertEquals(Lemma.pack(new byte[]{ 'I', 'E', 'M', 'A', 'N', 'D', 'S' }), res.filled().clueMap().get(259).word());
|
||||
Assertions.assertEquals(648985643903632391L, res.filled().grid().grid().lo);
|
||||
Assertions.assertEquals(140L, res.filled().grid().grid().hi);
|
||||
Assertions.assertEquals(18, res.filled().clueMap().size(), "Number of assigned words changed");
|
||||
Assertions.assertEquals(Lemma.pack(new byte[]{ 'L', 'E', 'L', 'I', 'J', 'K', 'S' }), res.filled().clueMap().get(451).word());
|
||||
Assertions.assertEquals(73207692597665799L, res.filled().grid().grid().lo);
|
||||
Assertions.assertEquals(193L, res.filled().grid().grid().hi);
|
||||
}
|
||||
@Test
|
||||
public void testIsLetterA() {
|
||||
|
||||
@@ -15,40 +15,36 @@ public class SwedishGeneratorTest {
|
||||
void testPatternForSlotAllLetters() {
|
||||
var grid = new Grid(new byte[]{ 65, 66, 67 }); // A B C
|
||||
var slot = Slot.from(18, ((long) 0) | ((long) 1 << 7) | ((long) 2 << 14), 3);
|
||||
var pattern = new byte[3];
|
||||
patternForSlot(grid, slot, pattern);
|
||||
long pattern = patternForSlot(grid, slot);
|
||||
|
||||
assertArrayEquals(new byte[]{ 'A', 'B', 'C' }, pattern);
|
||||
assertEquals(1 | (2 << 5) | (3 << 10), pattern);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPatternForSlotMixed() {
|
||||
var grid = new Grid(new byte[]{ 65, DASH, 67 }); // A - C
|
||||
var slot = Slot.from(1 << 4 | 2, ((long) 0) | ((long) 1 << 7) | ((long) 2 << 14), 3);
|
||||
var pattern = new byte[3];
|
||||
patternForSlot(grid, slot, pattern);
|
||||
long pattern = patternForSlot(grid, slot);
|
||||
|
||||
assertArrayEquals(new byte[]{ 'A', DASH, 'C' }, pattern);
|
||||
assertEquals(1 | (0 << 5) | (3 << 10), pattern);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPatternForSlotAllDashes() {
|
||||
var grid = new Grid(new byte[]{ DASH, DASH, DASH }); // - - -
|
||||
var slot = Slot.from(1 << 4 | 2, ((long) 0) | ((long) 1 << 7) | ((long) 2 << 14), 3);
|
||||
var pattern = new byte[3];
|
||||
patternForSlot(grid, slot, pattern);
|
||||
long pattern = patternForSlot(grid, slot);
|
||||
|
||||
assertArrayEquals(new byte[]{ DASH, DASH, DASH }, pattern);
|
||||
assertEquals(0, pattern);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPatternForSlotSingleLetter() {
|
||||
var grid = new Grid(new byte[]{ 65, DASH, DASH }); // A - -
|
||||
var slot = Slot.from(1 << 4 | 2, ((long) 0) | ((long) 1 << 7) | ((long) 2 << 14), 3);
|
||||
var pattern = new byte[3];
|
||||
patternForSlot(grid, slot, pattern);
|
||||
long pattern = patternForSlot(grid, slot);
|
||||
|
||||
assertArrayEquals(new byte[]{ 'A', DASH, DASH }, pattern);
|
||||
assertEquals(1, pattern);
|
||||
}
|
||||
@Test
|
||||
void testRng() {
|
||||
@@ -198,7 +194,7 @@ public class SwedishGeneratorTest {
|
||||
|
||||
// Pattern "APP--" for length 5
|
||||
var context = new Context();
|
||||
context.setPatter(new byte[]{ 'A', 'P', 'P', DASH, DASH });
|
||||
context.setPattern(Lemma.pack(new byte[]{ 'A', 'P', 'P', DASH, DASH }));
|
||||
var info = candidateInfoForPattern(context, dict.index()[5], 5);
|
||||
|
||||
assertEquals(2, info.count());
|
||||
@@ -214,7 +210,7 @@ public class SwedishGeneratorTest {
|
||||
grid.setClue(0, (byte) '2');
|
||||
// This should detect a slot starting at 0,1 with length 2 (0,1 and 0,2)
|
||||
|
||||
var slots = gen.extractSlots(grid);
|
||||
var slots = extractSlots(grid);
|
||||
// Depending on MAX_WORD_LENGTH and grid size.
|
||||
// In 3x3, if we have '2' at 0,0, rr=0, cc=1.
|
||||
// while loop:
|
||||
|
||||
Reference in New Issue
Block a user