introduce bitloops

This commit is contained in:
mike
2026-01-18 01:29:46 +01:00
parent 20617cda57
commit 112c16c525
7 changed files with 262 additions and 105 deletions

View File

@@ -2,10 +2,13 @@ package puzzle;
import lombok.AllArgsConstructor;
import lombok.val;
import puzzle.Export.Clued;
import puzzle.Export.Gridded;
import java.sql.Array;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Objects;
import java.util.stream.IntStream;
import static java.lang.Long.*;
@@ -48,8 +51,8 @@ public record Masker(Rng rng, int[] stack, Clues cache) {
long stop = 1L << msb;
rayLo &= -(stop << 1);
}
visitor.visit(key, rayLo, rayHi);
// if (Long.bitCount(rayLo) + Long.bitCount(rayHi) > 1)
visitor.visit(key, rayLo, rayHi);
}
private static void processSlot(Clues c, SlotVisitor visitor, int key) {
long rayLo = PATH_LO[key];
@@ -66,14 +69,13 @@ public record Masker(Rng rng, int[] stack, Clues cache) {
// keep all lo (lo indices are < any hi index), but cut hi below stop
rayHi &= (stop - 1);
}
visitor.visit(key, rayLo, rayHi);
// if (Long.bitCount(rayLo) + Long.bitCount(rayHi) > 1)
visitor.visit(key, rayLo, rayHi);
}
public static Slot[] extractSlots(Clues grid, DictEntry[] index) {
var slots = new Slot[grid.clueCount()];
int[] N = new int[]{ 0 };
grid.forEachSlot((key, lo, hi) -> slots[N[0]++] = Slot.from(key, lo, hi, index[Slot.length(lo, hi)]));
return slots;
var slots = new ArrayList<Slot>(grid.clueCount());
grid.forEachSlot((key, lo, hi) -> slots.add(Slot.from(key, lo, hi, Objects.requireNonNull(index[Slot.length(lo, hi)]))));
return slots.toArray(Slot[]::new);
}
public static Slotinfo[] slots(Clues mask, DictEntry[] index) {
var slots = Masker.extractSlots(mask, index);
@@ -102,6 +104,7 @@ public record Masker(Rng rng, int[] stack, Clues cache) {
public long maskFitness(final Clues grid, int clueSize) {
long cHLo = 0L, cHHi = 0L, cVLo = 0L, cVHi = 0L;
long cHLo2 = 0L, cHHi2 = 0L, cVLo2 = 0L, cVHi2 = 0L;
long lo_cl = grid.lo, hi_cl = grid.hi;
long penalty = (((long) Math.abs(grid.clueCount() - clueSize)) * 16000L);
boolean hasSlots = false;
@@ -130,9 +133,11 @@ public record Masker(Rng rng, int[] stack, Clues cache) {
if ((rLo | rHi) != X) {
hasSlots = true;
if (Slot.horiz(key)) {
cHLo2 |= (cHLo & rLo); cHHi2 |= (cHHi & rHi);
cHLo |= rLo;
cHHi |= rHi;
} else {
cVLo2 |= (cVLo & rLo); cVHi2 |= (cVHi & rHi);
cVLo |= rLo;
cVHi |= rHi;
}
@@ -163,9 +168,11 @@ public record Masker(Rng rng, int[] stack, Clues cache) {
if ((rLo | rHi) != X) {
hasSlots = true;
if (Slot.horiz(key)) {
cHLo2 |= (cHLo & rLo); cHHi2 |= (cHHi & rHi);
cHLo |= rLo;
cHHi |= rHi;
} else {
cVLo2 |= (cVLo & rLo); cVHi2 |= (cVHi & rHi);
cVLo |= rLo;
cVHi |= rHi;
}
@@ -241,8 +248,9 @@ public record Masker(Rng rng, int[] stack, Clues cache) {
boolean h = (cHLo & (1L << clueIdx)) != X;
boolean v = (cVLo & (1L << clueIdx)) != X;
if (!h && !v) penalty += 1500;
else if (h && v) { /* ok */ } else if (h | v) penalty += 200;
else penalty += 600;
else if (h && v) { /* ok */ }
else if (((h ? cHLo2 : cVLo2) & (1L << clueIdx)) != X) penalty += 600;
else penalty += 200;
}
for (long bits = ~hi_cl & MASK_HI; bits != X; bits &= bits - 1) {
int clueIdx = numberOfTrailingZeros(bits);
@@ -251,8 +259,9 @@ public record Masker(Rng rng, int[] stack, Clues cache) {
boolean h = (cHHi & (1L << clueIdx)) != X;
boolean v = (cVHi & (1L << clueIdx)) != X;
if (!h && !v) penalty += 1500;
else if (h && v) { /* ok */ } else if (h | v) penalty += 200;
else penalty += 600;
else if (h && v) { /* ok */ }
else if (((h ? cHHi2 : cVHi2) & (1L << clueIdx)) != X) penalty += 600;
else penalty += 200;
}
return penalty;
@@ -329,7 +338,7 @@ public record Masker(Rng rng, int[] stack, Clues cache) {
for (var h = c.hi & ~c.rhi & ~c.vhi; h != X; h &= h - 1) clearCluesHi(c, numberOfTrailingZeros(h), 0);
for (var h = c.hi & ~c.rhi & c.vhi; h != X; h &= h - 1) clearCluesHi(c, numberOfTrailingZeros(h), 1);
for (var h = c.hi & c.rhi & ~c.vhi; h != X; h &= h - 1) clearCluesHi(c, (numberOfTrailingZeros(h)), 2);
for (var h = c.hi & c.rhi & ~c.vhi; h != X; h &= h - 1) clearCluesHi(c, (numberOfTrailingZeros(h)), 3);
for (var h = c.hi & c.rhi & c.vhi; h != X; h &= h - 1) clearCluesHi(c, (numberOfTrailingZeros(h)), 3);
return c;
}
@@ -421,7 +430,7 @@ public record Masker(Rng rng, int[] stack, Clues cache) {
long lo, hi, vlo, vhi, rlo, rhi;
public static Clues createEmpty() { return new Clues(0, 0, 0, 0, 0, 0); }
public static Clues parse(String s) {
public static Clued parse(String s) {
var c = createEmpty();
var lines = s.split("\n");
for (int r = 0; r < Math.min(lines.length, R); r++) {
@@ -436,7 +445,7 @@ public record Masker(Rng rng, int[] stack, Clues cache) {
}
}
}
return c;
return new Clued(c);
}
public boolean cluelessLo(int idx) {
if (!isClueLo(idx)) return false;