introduce bitloops
This commit is contained in:
@@ -205,7 +205,6 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
|||||||
if ((idx & 2) != 0) rhi |= mask;
|
if ((idx & 2) != 0) rhi |= mask;
|
||||||
else rhi &= ~mask;
|
else rhi &= ~mask;
|
||||||
}
|
}
|
||||||
int digitAtLo(int idx) { return (int) ((((rlo >>> idx) & 1L) << 1) | ((vlo >>> idx) & 1L)); }
|
|
||||||
void clearClueLo(long mask) {
|
void clearClueLo(long mask) {
|
||||||
lo &= mask;
|
lo &= mask;
|
||||||
vlo &= mask;
|
vlo &= mask;
|
||||||
@@ -229,7 +228,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
|||||||
return (Long.bitCount(matchLo & MASK_LO) + Long.bitCount(matchHi & MASK_HI)) / SIZED;
|
return (Long.bitCount(matchLo & MASK_LO) + Long.bitCount(matchHi & MASK_HI)) / SIZED;
|
||||||
}
|
}
|
||||||
public Grid toGrid() { return new Grid(new byte[SIZE], lo, hi); }
|
public Grid toGrid() { return new Grid(new byte[SIZE], lo, hi); }
|
||||||
public void forEachSlot(SwedishGenerator.SlotVisitor visitor) {
|
public void forEachSlot(SlotVisitor visitor) {
|
||||||
for (var l = lo & ~rlo & vlo; l != X; l &= l - 1) processSlot(this, visitor, Slot.packSlotKey(Long.numberOfTrailingZeros(l), 1));
|
for (var l = lo & ~rlo & vlo; l != X; l &= l - 1) processSlot(this, visitor, Slot.packSlotKey(Long.numberOfTrailingZeros(l), 1));
|
||||||
for (var l = lo & ~rlo & ~vlo; l != X; l &= l - 1) processSlot(this, visitor, Slot.packSlotKey(Long.numberOfTrailingZeros(l), 0));
|
for (var l = lo & ~rlo & ~vlo; l != X; l &= l - 1) processSlot(this, visitor, Slot.packSlotKey(Long.numberOfTrailingZeros(l), 0));
|
||||||
for (var l = lo & rlo & ~vlo; l != X; l &= l - 1) processSlotRev(this, visitor, Slot.packSlotKey(Long.numberOfTrailingZeros(l), 2));
|
for (var l = lo & rlo & ~vlo; l != X; l &= l - 1) processSlotRev(this, visitor, Slot.packSlotKey(Long.numberOfTrailingZeros(l), 2));
|
||||||
@@ -277,7 +276,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
|||||||
static String[] clue(long w) { return CsvIndexService.clues(unpackIndex(w)); }
|
static String[] clue(long w) { return CsvIndexService.clues(unpackIndex(w)); }
|
||||||
static int simpel(long w) { return CsvIndexService.simpel(unpackIndex(w)); }
|
static int simpel(long w) { return CsvIndexService.simpel(unpackIndex(w)); }
|
||||||
static int length(long word) { return ((63 - Long.numberOfLeadingZeros(word & LETTER_MASK)) / 5) + 1; }
|
static int length(long word) { return ((63 - Long.numberOfLeadingZeros(word & LETTER_MASK)) / 5) + 1; }
|
||||||
static ThreadLocal<byte[]> BYTES = ThreadLocal.withInitial(() -> new byte[SwedishGenerator.MAX_WORD_LENGTH]);
|
static ThreadLocal<byte[]> BYTES = ThreadLocal.withInitial(() -> new byte[MAX_WORD_LENGTH]);
|
||||||
public static String asWord(long word) {
|
public static String asWord(long word) {
|
||||||
val len = Lemma.length(word);
|
val len = Lemma.length(word);
|
||||||
var b = BYTES.get();//new byte[Lemma.length(word)];
|
var b = BYTES.get();//new byte[Lemma.length(word)];
|
||||||
@@ -370,7 +369,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
|||||||
|
|
||||||
visitor.visit(key, rayLo, rayHi);
|
visitor.visit(key, rayLo, rayHi);
|
||||||
}
|
}
|
||||||
private static void processSlot(Clues c, SwedishGenerator.SlotVisitor visitor, int key) {
|
private static void processSlot(Clues c, SlotVisitor visitor, int key) {
|
||||||
long rayLo = PATH_LO[key];
|
long rayLo = PATH_LO[key];
|
||||||
long rayHi = PATH_HI[key];
|
long rayHi = PATH_HI[key];
|
||||||
long hitsLo = rayLo & c.lo;
|
long hitsLo = rayLo & c.lo;
|
||||||
@@ -589,10 +588,9 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
|||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
static boolean isLo(int n) { return (n & 64) == 0; }
|
static boolean isLo(int n) { return (n & 64) == 0; }
|
||||||
Clues mutate(SwedishGenerator.Clues c) {
|
Clues mutate(Clues c) {
|
||||||
int ri;
|
|
||||||
var bytes = MUTATE_RI[rng.randint0_SIZE()];
|
var bytes = MUTATE_RI[rng.randint0_SIZE()];
|
||||||
for (var k = 0; k < 4; k++) {
|
for (int k = 0, ri; k < 4; k++) {
|
||||||
ri = bytes[rng.randint0_624()];
|
ri = bytes[rng.randint0_624()];
|
||||||
if (isLo(ri)) {
|
if (isLo(ri)) {
|
||||||
if (!c.cluelessLo(ri)) {
|
if (!c.cluelessLo(ri)) {
|
||||||
@@ -631,22 +629,18 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
|||||||
(a.rlo & ~maskLo) | (other.rlo & maskLo),
|
(a.rlo & ~maskLo) | (other.rlo & maskLo),
|
||||||
(a.rhi & ~maskHi) | (other.rhi & maskHi));
|
(a.rhi & ~maskHi) | (other.rhi & maskHi));
|
||||||
|
|
||||||
// for (var lo = c.lo; lo != X; lo &= lo - 1L) clearCluesLo(c, Long.numberOfTrailingZeros(lo));
|
for (var l = c.lo & ~c.rlo & ~c.vlo; l != X; l &= l - 1) clearCluesLo(c, Long.numberOfTrailingZeros(l), 0);
|
||||||
// for (var hi = c.hi; hi != X; hi &= hi - 1L) clearCluesHi(c, Long.numberOfTrailingZeros(hi));
|
for (var l = c.lo & ~c.rlo & c.vlo; l != X; l &= l - 1) clearCluesLo(c, Long.numberOfTrailingZeros(l), 1);
|
||||||
|
for (var l = c.lo & c.rlo & ~c.vlo; l != X; l &= l - 1) clearCluesLo(c, Long.numberOfTrailingZeros(l), 2);
|
||||||
for (var l = c.lo & ~c.rlo & ~c.vlo ; l != X; l &= l - 1) clearCluesLo(c,Long.numberOfTrailingZeros(l), 0);
|
for (var l = c.lo & c.rlo & c.vlo; l != X; l &= l - 1) clearCluesLo(c, Long.numberOfTrailingZeros(l), 3);
|
||||||
for (var l = c.lo & ~c.rlo & c.vlo ; l != X; l &= l - 1) clearCluesLo(c,Long.numberOfTrailingZeros(l), 1);
|
for (var h = c.hi & ~c.rhi & ~c.vhi; h != X; h &= h - 1) clearCluesHi(c, Long.numberOfTrailingZeros(h), 0);
|
||||||
for (var l = c.lo & c.rlo & ~c.vlo ; l != X; l &= l - 1) clearCluesLo(c,Long.numberOfTrailingZeros(l), 2);
|
for (var h = c.hi & ~c.rhi & c.vhi; h != X; h &= h - 1) clearCluesHi(c, Long.numberOfTrailingZeros(h), 1);
|
||||||
for (var l = c.lo & c.rlo & c.vlo ; l != X; l &= l - 1) clearCluesLo(c,Long.numberOfTrailingZeros(l), 3);
|
for (var h = c.hi & c.rhi & ~c.vhi; h != X; h &= h - 1) clearCluesHi(c, (Long.numberOfTrailingZeros(h)), 2);
|
||||||
for (var h = c.hi & ~c.rhi & ~c.vhi ; h != X; h &= h - 1) clearCluesHi(c, Long.numberOfTrailingZeros(h), 0);
|
for (var h = c.hi & c.rhi & ~c.vhi; h != X; h &= h - 1) clearCluesHi(c, (Long.numberOfTrailingZeros(h)), 3);
|
||||||
for (var h = c.hi & ~c.rhi & c.vhi ; h != X; h &= h - 1) clearCluesHi(c, Long.numberOfTrailingZeros(h), 1);
|
|
||||||
for (var h = c.hi & c.rhi & ~c.vhi ; h != X; h &= h - 1) clearCluesHi(c,( Long.numberOfTrailingZeros(h)), 2);
|
|
||||||
for (var h = c.hi & c.rhi & ~c.vhi ; h != X; h &= h - 1) clearCluesHi(c,( Long.numberOfTrailingZeros(h)), 3);
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
public static void clearCluesLo(Clues out, int idx) { if (!out.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotKey(idx, out.digitAtLo(idx))])) out.clearClueLo(~(1L << idx)); }
|
public static void clearCluesLo(Clues out, int idx, int d) { if (!out.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotKey(idx, d)])) out.clearClueLo(~(1L << idx)); }
|
||||||
public static void clearCluesLo(Clues out, int idx,int d) { if (!out.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotKey(idx, d)])) out.clearClueLo(~(1L << idx)); }
|
public static void clearCluesHi(Clues out, int idx, int d) { if (!out.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotKey(64 | idx, d)])) out.clearClueHi(~(1L << idx)); }
|
||||||
public static void clearCluesHi(Clues out, int idx,int d) { if (!out.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotKey(64 | idx, d)])) out.clearClueHi(~(1L << idx)); }
|
|
||||||
|
|
||||||
Clues hillclimb(Clues start, int clue_size, int limit) {
|
Clues hillclimb(Clues start, int clue_size, int limit) {
|
||||||
var best = start;
|
var best = start;
|
||||||
@@ -891,7 +885,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public static SwedishGenerator.FillResult fillMask(Rng rng, Slot[] slots, Grid mask) {
|
public static FillResult fillMask(Rng rng, Slot[] slots, Grid mask) {
|
||||||
val multiThreaded = Thread.currentThread().getName().contains("pool");
|
val multiThreaded = Thread.currentThread().getName().contains("pool");
|
||||||
val NO_LOG = (!Main.VERBOSE || multiThreaded);
|
val NO_LOG = (!Main.VERBOSE || multiThreaded);
|
||||||
val grid = mask;
|
val grid = mask;
|
||||||
@@ -909,7 +903,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
|||||||
|
|
||||||
class Solver {
|
class Solver {
|
||||||
|
|
||||||
private final SwedishGenerator.Pick CARRIER = new Pick(null, null, 0);
|
private final Pick CARRIER = new Pick(null, null, 0);
|
||||||
long nodes;
|
long nodes;
|
||||||
long backtracks;
|
long backtracks;
|
||||||
int lastMRV;
|
int lastMRV;
|
||||||
@@ -1064,7 +1058,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
|||||||
// final progress line
|
// final progress line
|
||||||
|
|
||||||
var res = new FillResult(ok, new Gridded(grid), assigned,
|
var res = new FillResult(ok, new Gridded(grid), assigned,
|
||||||
new SwedishGenerator.FillStats(solver.nodes, solver.backtracks, (System.currentTimeMillis() - t0) / 1000.0, solver.lastMRV));
|
new FillStats(solver.nodes, solver.backtracks, (System.currentTimeMillis() - t0) / 1000.0, solver.lastMRV));
|
||||||
if (!multiThreaded) {
|
if (!multiThreaded) {
|
||||||
System.out.print("\r" + Strings.padRight("", 120) + "\r");
|
System.out.print("\r" + Strings.padRight("", 120) + "\r");
|
||||||
System.out.flush();
|
System.out.flush();
|
||||||
|
|||||||
Reference in New Issue
Block a user