introduce bitloops
This commit is contained in:
@@ -30,39 +30,45 @@ public final class Masker {
|
||||
public boolean isValid(Clues c, int minLen) {
|
||||
return findOffendingClue(c, minLen) == -1;
|
||||
}
|
||||
|
||||
|
||||
public int findOffendingClue(Clues grid, int minLen) {
|
||||
if (((grid.xlo & grid.rlo) & grid.lo) != X) return numberOfTrailingZeros((grid.xlo & grid.rlo) & grid.lo);
|
||||
if (((grid.xhi & grid.rhi) & grid.hi) != X) return 64 | numberOfTrailingZeros((grid.xhi & grid.rhi) & grid.hi);
|
||||
|
||||
|
||||
int num = 0;
|
||||
for (long bits = grid.lo; bits != X; bits &= bits - 1) activeCIdx[num++] = numberOfTrailingZeros(bits);
|
||||
for (long bits = grid.hi; bits != X; bits &= bits - 1) activeCIdx[num++] = 64 | numberOfTrailingZeros(bits);
|
||||
|
||||
|
||||
if (num == 0) return -1;
|
||||
|
||||
|
||||
int start = rng.randint0_SIZE() % num;
|
||||
int n = 0;
|
||||
int n = 0;
|
||||
for (int i = 0; i < num; i++) {
|
||||
int idx = activeCIdx[(start + i) % num];
|
||||
int dir = grid.getDir(idx);
|
||||
int key = Slot.packSlotKey(idx, dir);
|
||||
int idx = activeCIdx[(start + i) % num];
|
||||
int dir = grid.getDir(idx);
|
||||
int key = Slot.packSlotKey(idx, dir);
|
||||
long sLo = PATH_LO[key], sHi = PATH_HI[key];
|
||||
long hLo = sLo & grid.lo, hHi = sHi & grid.hi;
|
||||
if (Slotinfo.increasing(key)) {
|
||||
if (hLo != X) { sLo &= (1L << numberOfTrailingZeros(hLo)) - 1; sHi = 0; }
|
||||
else if (hHi != X) { sHi &= (1L << numberOfTrailingZeros(hHi)) - 1; }
|
||||
if (hLo != X) {
|
||||
sLo &= (1L << numberOfTrailingZeros(hLo)) - 1;
|
||||
sHi = 0;
|
||||
} else if (hHi != X) { sHi &= (1L << numberOfTrailingZeros(hHi)) - 1; }
|
||||
} else {
|
||||
if (hHi != X) { sHi &= -(1L << (63 - numberOfLeadingZeros(hHi)) << 1); sLo = 0; }
|
||||
else if (hLo != X) { sLo &= -(1L << (63 - numberOfLeadingZeros(hLo)) << 1); }
|
||||
if (hHi != X) {
|
||||
sHi &= -(1L << (63 - numberOfLeadingZeros(hHi)) << 1);
|
||||
sLo = 0;
|
||||
} else if (hLo != X) { sLo &= -(1L << (63 - numberOfLeadingZeros(hLo)) << 1); }
|
||||
}
|
||||
if (bitCount(sLo) + bitCount(sHi) < minLen) return idx;
|
||||
for (int j = 0; j < n; j++) if (bitCount(sLo & activeSLo[j]) + bitCount(sHi & activeSHi[j]) > 1) return idx;
|
||||
activeSLo[n] = sLo; activeSHi[n] = sHi; n++;
|
||||
activeSLo[n] = sLo;
|
||||
activeSHi[n] = sHi;
|
||||
n++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
public void cleanup(Clues c, int minLen) {
|
||||
int guard = 0;
|
||||
while (guard++ < 50) {
|
||||
@@ -255,12 +261,12 @@ public final class Masker {
|
||||
int msb = 63 - numberOfLeadingZeros(hLo);
|
||||
rLo &= -(1L << msb << 1);
|
||||
}
|
||||
|
||||
|
||||
activeCIdx[numClues] = 64 | clueIdx;
|
||||
activeSLo[numClues] = rLo;
|
||||
activeSHi[numClues] = rHi;
|
||||
numClues++;
|
||||
|
||||
|
||||
if ((rLo | rHi) != X) {
|
||||
hasSlots = true;
|
||||
if (Slot.horiz(key)) {
|
||||
@@ -281,7 +287,7 @@ public final class Masker {
|
||||
}
|
||||
|
||||
if (!hasSlots) return 1_000_000_000L;
|
||||
|
||||
|
||||
int[] rCount = new int[8];
|
||||
int[] cCount = new int[9];
|
||||
for (int i = 0; i < numClues; i++) {
|
||||
@@ -315,16 +321,15 @@ public final class Masker {
|
||||
}
|
||||
|
||||
if (numClues > 0) {
|
||||
int maxReached = 0;
|
||||
int maxReached = 0;
|
||||
long totalReachedLo = 0, totalReachedHi = 0;
|
||||
for (int i = 0; i < numClues; i++) {
|
||||
if (i < 64) { if ((totalReachedLo & (1L << i)) != 0) continue; }
|
||||
else { if ((totalReachedHi & (1L << (i - 64))) != 0) continue; }
|
||||
|
||||
if (i < 64) { if ((totalReachedLo & (1L << i)) != 0) continue; } else { if ((totalReachedHi & (1L << (i - 64))) != 0) continue; }
|
||||
|
||||
long currentReachedLo = (i < 64) ? (1L << i) : 0;
|
||||
long currentReachedHi = (i >= 64) ? (1L << (i - 64)) : 0;
|
||||
stack[0] = i;
|
||||
int sp = 1;
|
||||
int sp = 1;
|
||||
int count = 0;
|
||||
while (sp > 0) {
|
||||
int cur = stack[--sp];
|
||||
@@ -334,16 +339,16 @@ public final class Masker {
|
||||
while (nLo != 0) {
|
||||
long lsb = nLo & -nLo;
|
||||
int idx = numberOfTrailingZeros(lsb);
|
||||
currentReachedLo |= lsb;
|
||||
currentReachedLo |= lsb;
|
||||
stack[sp++] = idx;
|
||||
nLo &= ~lsb;
|
||||
nLo &= ~lsb;
|
||||
}
|
||||
while (nHi != 0) {
|
||||
long lsb = nHi & -nHi;
|
||||
int idx = 64 | numberOfTrailingZeros(lsb);
|
||||
currentReachedHi |= lsb;
|
||||
currentReachedHi |= lsb;
|
||||
stack[sp++] = idx;
|
||||
nHi &= ~lsb;
|
||||
nHi &= ~lsb;
|
||||
}
|
||||
}
|
||||
if (count > maxReached) maxReached = count;
|
||||
@@ -355,7 +360,7 @@ public final class Masker {
|
||||
penalty += 20000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (long bits = ~lo_cl & MASK_LO; bits != X; bits &= bits - 1) {
|
||||
int clueIdx = numberOfTrailingZeros(bits);
|
||||
var rci = IT[clueIdx];
|
||||
@@ -377,19 +382,19 @@ public final class Masker {
|
||||
else if (h && v) { /* ok */ } else if (((h ? cHHi2 : cVHi2) & (1L << clueIdx)) != X) penalty += 1000;
|
||||
else penalty += 1000;
|
||||
}
|
||||
|
||||
long nclLo = ~lo_cl & MASK_LO;
|
||||
long nclHi = ~hi_cl & MASK_HI;
|
||||
|
||||
long nclLo = ~lo_cl & MASK_LO;
|
||||
long nclHi = ~hi_cl & MASK_HI;
|
||||
long hNbrLo = (nclLo >> 8) | (nclLo << 8) | (nclHi << 56);
|
||||
long hNbrHi = (nclHi >> 8) | (nclLo >> 56);
|
||||
long vNbrLo = ((nclLo & ~0x0101010101010101L) >> 1) | ((nclLo & ~0x8080808080808080L) << 1);
|
||||
long vNbrHi = ((nclHi & ~0x01L) >> 1) | ((nclHi & ~0x80L) << 1);
|
||||
|
||||
penalty += bitCount(nclLo & ~cHLo & hNbrLo) * 800;
|
||||
penalty += bitCount(nclLo & ~cVLo & vNbrLo) * 800;
|
||||
penalty += bitCount(nclHi & ~cHHi & hNbrHi) * 800;
|
||||
penalty += bitCount(nclHi & ~cVHi & vNbrHi) * 800;
|
||||
|
||||
|
||||
//penalty += bitCount(nclLo & ~cHLo & hNbrLo) * 800;
|
||||
//penalty += bitCount(nclLo & ~cVLo & vNbrLo) * 800;
|
||||
//penalty += bitCount(nclHi & ~cHHi & hNbrHi) * 800;
|
||||
//penalty += bitCount(nclHi & ~cVHi & vNbrHi) * 800;
|
||||
|
||||
return penalty;
|
||||
}
|
||||
|
||||
@@ -424,7 +429,7 @@ public final class Masker {
|
||||
|
||||
public Clues mutate(Clues c) {
|
||||
var bytes = MUTATE_RI[rng.randint0_SIZE()];
|
||||
for (int k = 0, ri; k < 4; k++) {
|
||||
for (int k = 0, ri; k < 6; k++) {
|
||||
ri = bytes[rng.randint0_624()];
|
||||
if (c.notClue(ri)) { // ADD
|
||||
byte d = rng.randomClueDir();
|
||||
@@ -433,17 +438,31 @@ public final class Masker {
|
||||
if (isLo(ri)) {
|
||||
c.setClueLo(1L << ri, d);
|
||||
if (!isValid(c, MIN_LEN)) c.clearClueLo(~(1L << ri));
|
||||
else continue;
|
||||
} else {
|
||||
c.setClueHi(1L << (ri & 63), d);
|
||||
if (!isValid(c, MIN_LEN)) c.clearClueHi(~(1L << (ri & 63)));
|
||||
else continue;
|
||||
}
|
||||
}
|
||||
} else { // HAS CLUE
|
||||
var op = rng.randomClueDir();
|
||||
if (op < 2) { // REMOVE
|
||||
if (isLo(ri)) c.clearClueLo(~(1L << ri));
|
||||
else c.clearClueHi(~(1L << (ri & 63)));
|
||||
} else if (op < 5) { // CHANGE DIRECTION
|
||||
byte oldD = c.getDir(ri);
|
||||
if (isLo(ri)) {
|
||||
c.clearClueLo(~(1L << ri));
|
||||
if (!isValid(c, MIN_LEN)) c.setClueLo(1L << ri, oldD);
|
||||
else continue;
|
||||
} else {
|
||||
c.clearClueHi(~(1L << (ri & 63)));
|
||||
if (!isValid(c, MIN_LEN)) c.setClueHi(1L << (ri & 63), oldD);
|
||||
else continue;
|
||||
}
|
||||
|
||||
/* if (isLo(ri)) c.clearClueLo(~(1L << ri));
|
||||
else c.clearClueHi(~(1L << (ri & 63)));*/
|
||||
}
|
||||
if (op < 4) { // CHANGE DIRECTION
|
||||
byte d = rng.randomClueDir();
|
||||
int key = Slot.packSlotKey(ri, d);
|
||||
if (c.hasRoomForClue(key)) {
|
||||
@@ -451,28 +470,29 @@ public final class Masker {
|
||||
if (isLo(ri)) {
|
||||
c.setClueLo(1L << ri, d);
|
||||
if (!isValid(c, MIN_LEN)) c.setClueLo(1L << ri, oldD);
|
||||
else continue;
|
||||
} else {
|
||||
c.setClueHi(1L << (ri & 63), d);
|
||||
if (!isValid(c, MIN_LEN)) c.setClueHi(1L << (ri & 63), oldD);
|
||||
else continue;
|
||||
}
|
||||
}
|
||||
} else { // MOVE
|
||||
int nri = bytes[rng.randint0_624()];
|
||||
if (c.notClue(nri)) {
|
||||
byte d = c.getDir(ri);
|
||||
int nkey = Slot.packSlotKey(nri, d);
|
||||
if (c.hasRoomForClue(nkey)) {
|
||||
if (isLo(ri)) c.clearClueLo(~(1L << ri));
|
||||
else c.clearClueHi(~(1L << (ri & 63)));
|
||||
if (isLo(nri)) c.setClueLo(1L << nri, d);
|
||||
else c.setClueHi(1L << (nri & 63), d);
|
||||
if (!isValid(c, MIN_LEN)) {
|
||||
if (isLo(nri)) c.clearClueLo(~(1L << nri));
|
||||
else c.clearClueHi(~(1L << (nri & 63)));
|
||||
if (isLo(ri)) c.setClueLo(1L << ri, d);
|
||||
else c.setClueHi(1L << (ri & 63), d);
|
||||
}
|
||||
}
|
||||
} // MOVE
|
||||
int nri = bytes[rng.randint0_624()];
|
||||
if (c.notClue(nri)) {
|
||||
byte d = c.getDir(ri);
|
||||
int nkey = Slot.packSlotKey(nri, d);
|
||||
if (c.hasRoomForClue(nkey)) {
|
||||
if (isLo(ri)) c.clearClueLo(~(1L << ri));
|
||||
else c.clearClueHi(~(1L << (ri & 63)));
|
||||
if (isLo(nri)) c.setClueLo(1L << nri, d);
|
||||
else c.setClueHi(1L << (nri & 63), d);
|
||||
if (!isValid(c, MIN_LEN)) {
|
||||
if (isLo(nri)) c.clearClueLo(~(1L << nri));
|
||||
else c.clearClueHi(~(1L << (nri & 63)));
|
||||
if (isLo(ri)) c.setClueLo(1L << ri, d);
|
||||
else c.setClueHi(1L << (ri & 63), d);
|
||||
} else continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -669,38 +689,50 @@ public final class Masker {
|
||||
if (((xhi & rhi) & hi) != X) return 64 | numberOfTrailingZeros((xhi & rhi) & hi);
|
||||
int n = 0;
|
||||
for (long bits = lo; bits != X; bits &= bits - 1) {
|
||||
int idx = numberOfTrailingZeros(bits);
|
||||
int dir = getDir(idx);
|
||||
int key = Slot.packSlotKey(idx, dir);
|
||||
int idx = numberOfTrailingZeros(bits);
|
||||
int dir = getDir(idx);
|
||||
int key = Slot.packSlotKey(idx, dir);
|
||||
long sLo = PATH_LO[key], sHi = PATH_HI[key];
|
||||
long hLo = sLo & lo, hHi = sHi & hi;
|
||||
if (Slotinfo.increasing(key)) {
|
||||
if (hLo != X) { sLo &= (1L << numberOfTrailingZeros(hLo)) - 1; sHi = 0; }
|
||||
else if (hHi != X) { sHi &= (1L << numberOfTrailingZeros(hHi)) - 1; }
|
||||
if (hLo != X) {
|
||||
sLo &= (1L << numberOfTrailingZeros(hLo)) - 1;
|
||||
sHi = 0;
|
||||
} else if (hHi != X) { sHi &= (1L << numberOfTrailingZeros(hHi)) - 1; }
|
||||
} else {
|
||||
if (hHi != X) { sHi &= -(1L << (63 - numberOfLeadingZeros(hHi)) << 1); sLo = 0; }
|
||||
else if (hLo != X) { sLo &= -(1L << (63 - numberOfLeadingZeros(hLo)) << 1); }
|
||||
if (hHi != X) {
|
||||
sHi &= -(1L << (63 - numberOfLeadingZeros(hHi)) << 1);
|
||||
sLo = 0;
|
||||
} else if (hLo != X) { sLo &= -(1L << (63 - numberOfLeadingZeros(hLo)) << 1); }
|
||||
}
|
||||
if (bitCount(sLo) + bitCount(sHi) < minLen) return idx;
|
||||
for (int i = 0; i < n; i++) if (bitCount(sLo & slo[i]) + bitCount(sHi & shi[i]) > 1) return idx;
|
||||
slo[n] = sLo; shi[n] = sHi; n++;
|
||||
slo[n] = sLo;
|
||||
shi[n] = sHi;
|
||||
n++;
|
||||
}
|
||||
for (long bits = hi; bits != X; bits &= bits - 1) {
|
||||
int idx = 64 | numberOfTrailingZeros(bits);
|
||||
int dir = getDir(idx);
|
||||
int key = Slot.packSlotKey(idx, dir);
|
||||
int idx = 64 | numberOfTrailingZeros(bits);
|
||||
int dir = getDir(idx);
|
||||
int key = Slot.packSlotKey(idx, dir);
|
||||
long sLo = PATH_LO[key], sHi = PATH_HI[key];
|
||||
long hLo = sLo & lo, hHi = sHi & hi;
|
||||
if (Slotinfo.increasing(key)) {
|
||||
if (hLo != X) { sLo &= (1L << numberOfTrailingZeros(hLo)) - 1; sHi = 0; }
|
||||
else if (hHi != X) { sHi &= (1L << numberOfTrailingZeros(hHi)) - 1; }
|
||||
if (hLo != X) {
|
||||
sLo &= (1L << numberOfTrailingZeros(hLo)) - 1;
|
||||
sHi = 0;
|
||||
} else if (hHi != X) { sHi &= (1L << numberOfTrailingZeros(hHi)) - 1; }
|
||||
} else {
|
||||
if (hHi != X) { sHi &= -(1L << (63 - numberOfLeadingZeros(hHi)) << 1); sLo = 0; }
|
||||
else if (hLo != X) { sLo &= -(1L << (63 - numberOfLeadingZeros(hLo)) << 1); }
|
||||
if (hHi != X) {
|
||||
sHi &= -(1L << (63 - numberOfLeadingZeros(hHi)) << 1);
|
||||
sLo = 0;
|
||||
} else if (hLo != X) { sLo &= -(1L << (63 - numberOfLeadingZeros(hLo)) << 1); }
|
||||
}
|
||||
if (bitCount(sLo) + bitCount(sHi) < minLen) return idx;
|
||||
for (int i = 0; i < n; i++) if (bitCount(sLo & slo[i]) + bitCount(sHi & shi[i]) > 1) return idx;
|
||||
slo[n] = sLo; shi[n] = sHi; n++;
|
||||
slo[n] = sLo;
|
||||
shi[n] = sHi;
|
||||
n++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user