introduce bitloops
This commit is contained in:
@@ -70,6 +70,8 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
static final int[][] MUTATE_RI = new int[SIZE][625];
|
static final int[][] MUTATE_RI = new int[SIZE][625];
|
||||||
static final long[] NBR8_PACKED_LO = Neighbors9x8.NBR8_PACKED_LO;
|
static final long[] NBR8_PACKED_LO = Neighbors9x8.NBR8_PACKED_LO;
|
||||||
static final long[] NBR8_PACKED_HI = Neighbors9x8.NBR8_PACKED_HI;
|
static final long[] NBR8_PACKED_HI = Neighbors9x8.NBR8_PACKED_HI;
|
||||||
|
static final long[] PATH_LO = Neighbors9x8.PATH_LO;
|
||||||
|
static final long[] PATH_HI = Neighbors9x8.PATH_HI;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
for (int i = 0; i < SIZE; i++) {
|
for (int i = 0; i < SIZE; i++) {
|
||||||
@@ -305,10 +307,10 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static record Slot(int key, long packedPos) {
|
static record Slot(int key, long packedPos, long packedPoslo, long packedPoshi) {
|
||||||
|
|
||||||
static final int BIT_FOR_DIR = 3;
|
static final int BIT_FOR_DIR = 3;
|
||||||
static Slot from(int key, long packedPos, int len) { return new Slot(key, packedPos | ((long) len << 56)); }
|
static Slot from(int key, long packedPos, int len) { return new Slot(key, packedPos | ((long) len << 56), 0L, 0L); }
|
||||||
void undoPlace(Grid grid, int mask) { for (int i = 0, len = len(); i < len; i++) if ((mask & (1L << i)) != 0) grid.clearletter(pos(i)); }
|
void undoPlace(Grid grid, int mask) { for (int i = 0, len = len(); i < len; i++) if ((mask & (1L << i)) != 0) grid.clearletter(pos(i)); }
|
||||||
public int len() { return (int) (packedPos >>> 56); }
|
public int len() { return (int) (packedPos >>> 56); }
|
||||||
public int clueR() { return Grid.r((key >>> BIT_FOR_DIR)); }
|
public int clueR() { return Grid.r((key >>> BIT_FOR_DIR)); }
|
||||||
@@ -322,6 +324,56 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
public static int packSlotDir(int idx, int d) { return (idx << BIT_FOR_DIR) | d; }
|
public static int packSlotDir(int idx, int d) { return (idx << BIT_FOR_DIR) | d; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SlotVisitor2 {
|
||||||
|
|
||||||
|
void visitMasks(int slotDir, long loMask, long hiMask);
|
||||||
|
}
|
||||||
|
private static void processSlot(Grid grid, SlotVisitor2 visitor, int idx) {
|
||||||
|
int d = grid.digitAt(idx); // 1..4
|
||||||
|
int di = d - 1; // 0..3
|
||||||
|
int key = (idx << 2) | di;
|
||||||
|
|
||||||
|
long rayLo = PATH_LO[key];
|
||||||
|
long rayHi = PATH_HI[key];
|
||||||
|
|
||||||
|
// only consider clue cells
|
||||||
|
long hitsLo = rayLo & grid.lo;
|
||||||
|
long hitsHi = rayHi & grid.hi;
|
||||||
|
|
||||||
|
// slice ray to stop before first clue, depending on direction monotonicity
|
||||||
|
// right/down => increasing indices; up/left => decreasing indices
|
||||||
|
boolean increasing = (d == 2 || d == 3);
|
||||||
|
|
||||||
|
if (increasing) {
|
||||||
|
// first clue is lowest index among hits (lo first, then hi)
|
||||||
|
if (hitsLo != 0) {
|
||||||
|
long stop = 1L << Long.numberOfTrailingZeros(hitsLo);
|
||||||
|
rayLo &= (stop - 1);
|
||||||
|
rayHi = 0; // any hi is beyond the stop
|
||||||
|
} else if (hitsHi != 0) {
|
||||||
|
long stop = 1L << Long.numberOfTrailingZeros(hitsHi);
|
||||||
|
// keep all lo (lo indices are < any hi index), but cut hi below stop
|
||||||
|
rayHi &= (stop - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// first clue is highest index among hits (hi first, then lo)
|
||||||
|
if (hitsHi != 0) {
|
||||||
|
int msb = 63 - Long.numberOfLeadingZeros(hitsHi);
|
||||||
|
long stop = 1L << msb;
|
||||||
|
rayHi &= ~((stop << 1) - 1); // keep bits > stop
|
||||||
|
rayLo = 0; // lo indices are below stop
|
||||||
|
} else if (hitsLo != 0) {
|
||||||
|
int msb = 63 - Long.numberOfLeadingZeros(hitsLo);
|
||||||
|
long stop = 1L << msb;
|
||||||
|
rayLo &= ~((stop << 1) - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rayLo | rayHi) != 0) {
|
||||||
|
visitor.visitMasks(Slot.packSlotDir(idx, d), rayLo, rayHi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void processSlot(Grid grid, SlotVisitor visitor, int idx) {
|
private static void processSlot(Grid grid, SlotVisitor visitor, int idx) {
|
||||||
var d = grid.digitAt(idx);
|
var d = grid.digitAt(idx);
|
||||||
var packed = OFFSETS_D_IDX[(d - 1) | (idx << 2)];
|
var packed = OFFSETS_D_IDX[(d - 1) | (idx << 2)];
|
||||||
@@ -587,8 +639,6 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
var x = pop.get(i);
|
var x = pop.get(i);
|
||||||
if (x.fit() < best.fit()) best = x;
|
if (x.fit() < best.fit()) best = x;
|
||||||
}
|
}
|
||||||
//pop.sort(Comparator.comparingLong(GridAndFit::fit));
|
|
||||||
//return pop.get(0).grid;
|
|
||||||
return best.grid;
|
return best.grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user