introduce bitloops
This commit is contained in:
@@ -57,7 +57,6 @@ public record SwedishGenerator(Rng rng) {
|
||||
static final double SIZED = (double) SIZE;// ~18
|
||||
static final int TARGET_CLUES = SIZE >> 2;
|
||||
static final int MAX_WORD_LENGTH = C <= R ? C : R;
|
||||
static final int MAX_WORD_LENGTH7 = MAX_WORD_LENGTH * 7;
|
||||
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;
|
||||
@@ -123,8 +122,8 @@ public record SwedishGenerator(Rng rng) {
|
||||
|
||||
static final class Context {
|
||||
|
||||
final int[] covH = new int[SIZE];
|
||||
final int[] covV = new int[SIZE];
|
||||
final Bit covH2 = new Bit();
|
||||
final Bit covV2 = new Bit();
|
||||
final int[] cellCount = new int[SIZE];
|
||||
final int[] stack = new int[SIZE];
|
||||
final Bit seen = new Bit();
|
||||
@@ -188,35 +187,32 @@ public record SwedishGenerator(Rng rng) {
|
||||
void setByteAt(int idx, byte ch) { g[idx] = ch; }
|
||||
void setClue(int idx, byte ch) {
|
||||
g[idx] = ch;
|
||||
if (idx < 64) lo |= (1L << idx);
|
||||
if ((idx & 64) == 0) lo |= (1L << idx);
|
||||
else hi |= (1L << (idx & 63));
|
||||
}
|
||||
void clearletter(int idx) { g[idx] = DASH; }
|
||||
void clearClue(int idx) {
|
||||
g[idx] = DASH;
|
||||
if (idx < 64) lo &= ~(1L << idx);
|
||||
if ((idx & 64) == 0) lo &= ~(1L << idx);
|
||||
else hi &= ~(1L << (idx & 63));
|
||||
}
|
||||
static boolean isDigit(byte b) { return (b & B48) == B48; }
|
||||
boolean isDigitAt(int index) { return isDigit(g[index]); }
|
||||
boolean isClue(long index) {
|
||||
if (index < 64) return ((lo >> index) & 1L) != X;
|
||||
if ((index & 64) == 0) return ((lo >> index) & 1L) != X;
|
||||
return ((hi >> (index & 63)) & 1L) != X;
|
||||
}
|
||||
boolean isClue(int index) {
|
||||
if (index < 64) return ((lo >> index) & 1L) != 0;
|
||||
if ((index & 64) == 0) return ((lo >> index) & 1L) != 0;
|
||||
return ((hi >> (index & 63)) & 1L) != 0;
|
||||
}
|
||||
boolean notClue(long index) {
|
||||
if (index < 64) return ((lo >> index) & 1L) == X;
|
||||
return ((hi >> (index & 63)) & 1L) == X;
|
||||
}
|
||||
boolean notClue(int index) {
|
||||
if (index < 64) return ((lo >> index) & 1L) == X;
|
||||
if ((index & 64) == 0) return ((lo >> index) & 1L) == X;
|
||||
return ((hi >> (index & 63)) & 1L) == X;
|
||||
}
|
||||
boolean notClue(int index) { return ((index & 64) == 0) ? ((lo >> index) & 1L) == X : ((hi >> (index & 63)) & 1L) == X; }
|
||||
boolean clueless(int idx) {
|
||||
if (idx < 64) {
|
||||
if ((idx & 64) == 0) {
|
||||
val test = (1L << idx);
|
||||
if ((test & lo) == X) return false;
|
||||
g[idx] = DASH;
|
||||
@@ -257,6 +253,9 @@ public record SwedishGenerator(Rng rng) {
|
||||
public static record Lemma(int index, long word, byte len) {
|
||||
|
||||
static int LEMMA_COUNTER = 0;
|
||||
static long pack(String word) {
|
||||
return pack(word.getBytes(US_ASCII));
|
||||
}
|
||||
static long pack(byte[] b) {
|
||||
long w = 0;
|
||||
for (var i = 0; i < b.length; i++) w |= ((long) b[i] & ~64) << (i * 5);
|
||||
@@ -394,7 +393,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
long packed = nbrs16.path()[clueIdx];
|
||||
int n = (int) (packed >>> 56) * 7, k, idx;
|
||||
var horiz = Slot.horiz(d) ? covH : covV;
|
||||
for (k = 0; k < n && k < MAX_WORD_LENGTH7; k += 7) {
|
||||
for (k = 0; k < n; k += 7) {
|
||||
idx = (int) ((packed >>> (k)) & 0x7F);
|
||||
if (grid.isClue(idx)) break;
|
||||
horiz[idx] += 1;
|
||||
@@ -408,10 +407,12 @@ public record SwedishGenerator(Rng rng) {
|
||||
|
||||
long maskFitness(Grid grid) {
|
||||
var ctx = CTX.get();
|
||||
var covH = ctx.covH;
|
||||
var covV = ctx.covV;
|
||||
Arrays.fill(covH, 0, SIZE, 0);
|
||||
Arrays.fill(covV, 0, SIZE, 0);
|
||||
var covH = ctx.covH2;
|
||||
var covV = ctx.covV2;
|
||||
covH.clear();
|
||||
covV.clear();
|
||||
/*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)) * 16000L);
|
||||
boolean hasSlots = false;
|
||||
@@ -424,10 +425,10 @@ public record SwedishGenerator(Rng rng) {
|
||||
long packed = nbrs16.path()[clueIdx];
|
||||
int n = (int) (packed >>> 56) * 7, k, idx;
|
||||
var horiz = Slot.horiz(d) ? covH : covV;
|
||||
for (k = 0; k < n && k < MAX_WORD_LENGTH7; k += 7) {
|
||||
for (k = 0; k < n; k += 7) {
|
||||
idx = (int) ((packed >>> (k)) & 0x7F);
|
||||
if (grid.isClue(idx)) break;
|
||||
horiz[idx] += 1;
|
||||
horiz.set(idx);
|
||||
}
|
||||
if (k > 0) {
|
||||
hasSlots = true;
|
||||
@@ -470,10 +471,10 @@ public record SwedishGenerator(Rng rng) {
|
||||
int clueIdx = i + Long.numberOfTrailingZeros(bits);
|
||||
var rci = IT[clueIdx];
|
||||
if ((4 - rci.nbrCount()) + Long.bitCount(rci.n1() & lo_cl) + Long.bitCount(rci.n2() & hi_cl) >= 3) penalty += 400;
|
||||
var h = covH[clueIdx];
|
||||
var v = covV[clueIdx];
|
||||
if (h == 0 && v == 0) penalty += 1500;
|
||||
else if (h > 0 && v > 0) { /* ok */ } else if (h + v == 1) penalty += 200;
|
||||
var h = covH.get(clueIdx);
|
||||
var v = covV.get(clueIdx);
|
||||
if (!h && !v) penalty += 1500;
|
||||
else if (h && v) { /* ok */ } else if (h | v) penalty += 200;
|
||||
else penalty += 600;
|
||||
}
|
||||
}
|
||||
@@ -523,10 +524,10 @@ public record SwedishGenerator(Rng rng) {
|
||||
if (out.g[i] != ch) {
|
||||
out.g[i] = ch;
|
||||
if (Grid.isDigit(ch)) {
|
||||
if (i < 64) bo0 |= (1L << i);
|
||||
if ((i & 64) == 0) bo0 |= (1L << i);
|
||||
else bo1 |= (1L << (i & 63));
|
||||
} else {
|
||||
if (i < 64) bo0 &= ~(1L << i);
|
||||
if ((i & 64) == 0) bo0 &= ~(1L << i);
|
||||
else bo1 &= ~(1L << (i & 63));
|
||||
}
|
||||
}
|
||||
@@ -615,6 +616,11 @@ public record SwedishGenerator(Rng rng) {
|
||||
//return pop.get(0).grid;
|
||||
return best.grid;
|
||||
}
|
||||
static int usedCharsInPattern(long p) {
|
||||
if (p == 0) return 0;
|
||||
int highestBit = 63 - Long.numberOfLeadingZeros(p); // 0-based
|
||||
return (highestBit / 5) + 1;
|
||||
}
|
||||
static long patternForSlot(Grid grid, Slot s) {
|
||||
long p = 0;
|
||||
for (int i = 0, len = s.len(); i < len; i++) {
|
||||
@@ -654,23 +660,27 @@ public record SwedishGenerator(Rng rng) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static CandidateInfo candidateInfoForPattern(Context ctx, DictEntry entry, int len) {
|
||||
static CandidateInfo candidateInfoForPattern(Context ctx, DictEntry entry, int lenb) {
|
||||
var pattern = ctx.pattern;
|
||||
var listBuffer = ctx.intListBuffer;
|
||||
var listCount = 0;
|
||||
IntList tmp;
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (pattern == X) {
|
||||
return new CandidateInfo(null, entry.words.length);
|
||||
}
|
||||
/*if (usedCharsInPattern(pattern) > len) {
|
||||
var abc = usedCharsInPattern(pattern);
|
||||
System.out.println(abc);
|
||||
}*/
|
||||
for (int i = 0, len = usedCharsInPattern(pattern); i < len; i++) {
|
||||
int val = (int) ((pattern >>> (i * 5)) & 31);
|
||||
if (val != 0) {
|
||||
listBuffer[listCount++] = entry.pos[i][val - 1];
|
||||
} else {
|
||||
//System.out.println("?");
|
||||
}
|
||||
}
|
||||
|
||||
if (listCount == 0) {
|
||||
//return CANDIDATES[entry.words.length];
|
||||
return new CandidateInfo(null, entry.words.length);
|
||||
}
|
||||
|
||||
// Sort constraints by size to optimize intersection
|
||||
for (var i = 0; i < listCount - 1; i++) {
|
||||
for (var j = i + 1; j < listCount; j++) {
|
||||
|
||||
Reference in New Issue
Block a user