introduce bitloops

This commit is contained in:
mike
2026-01-12 04:27:46 +01:00
parent 123cdbdc01
commit 93628f9b4e

View File

@@ -70,18 +70,19 @@ public record SwedishGenerator(Rng rng) {
static int clamp(int x, int a, int b) { return Math.max(a, Math.min(b, x)); } static int clamp(int x, int a, int b) { return Math.max(a, Math.min(b, x)); }
record Pick(Slot slot, CandidateInfo info, boolean done) { } record Pick(Slot slot, CandidateInfo info, boolean done) { }
static final byte B0 = (byte) 0; static final byte B0 = (byte) 0;
static final byte B64 = (byte) 64; static final byte B64 = (byte) 64;
static final byte B48 = (byte) 48; static final byte B48 = (byte) 48;
// Directions for '1'..'6' // Directions for '1'..'6'
static final nbrs_16[] OFFSETS = Neighbors9x8.OFFSETS; static final nbrs_16[] OFFSETS = Neighbors9x8.OFFSETS;
static final nbrs_16[] OFFSETS_FOUR = Neighbors9x8.OFFSETS_FOUR; static final nbrs_16[] OFFSETS_FOUR = Neighbors9x8.OFFSETS_FOUR;
static final nbrs_8[] nbrs8 = Neighbors9x8.nbrs8; static final nbrs_8[] nbrs8 = Neighbors9x8.nbrs8;
static final nbrs_8[] nbrs4 = Neighbors9x8.nbrs4; static final nbrs_8[] nbrs4 = Neighbors9x8.nbrs4;
static final rci[] IT = Neighbors9x8.IT; static final rci[] IT = Neighbors9x8.IT;
static final long[] INBR8_PACKEDT = Neighbors9x8.NBR8_PACKED; static final long[] INBR8_PACKEDT = Neighbors9x8.NBR8_PACKED;
static final int[][] MUTATE_RI = new int[SIZE][625]; static final int[][] MUTATE_RI = new int[SIZE][625];
static final long[] NBR8_PACKED = Neighbors9x8.NBR8_PACKED; static final long[] NBR8_PACKED_LO = Neighbors9x8.NBR8_PACKED_LO;
static final long[] NBR8_PACKED_HI = Neighbors9x8.NBR8_PACKED_HI;
static { static {
for (int i = 0; i < SIZE; i++) { for (int i = 0; i < SIZE; i++) {
@@ -441,11 +442,67 @@ public record SwedishGenerator(Rng rng) {
if (!hasSlots) return 1_000_000_000L; if (!hasSlots) return 1_000_000_000L;
var seen = ctx.seen; var stack = ctx.stack;
var stack = ctx.stack; long seenLo = 0L, seenHi = 0L;
seen.clear();
for (int i = 0; i < 65; i += 64) { // loop over beide helften
for (int base = 0; base <= 64; base += 64) {
long clueMask = (base == 0) ? lo_cl : hi_cl;
long seenMask = (base == 0) ? seenLo : seenHi;
// "unseen clues" in deze helft
for (long bits = clueMask & ~seenMask; bits != 0L; bits &= bits - 1) {
int clueIdx = base + Long.numberOfTrailingZeros(bits);
// start nieuwe component
int size = 0;
int sp = 0;
stack[sp++] = clueIdx;
// mark seen
if (clueIdx < 64) seenLo |= 1L << clueIdx;
else seenHi |= 1L << (clueIdx - 64);
// flood fill / bfs
while (sp > 0) {
int cur = stack[--sp];
size++;
// neighbors als 2x long masks
long nLo = NBR8_PACKED_LO[cur];
long nHi = NBR8_PACKED_HI[cur];
// filter: alleen clues, en nog niet seen
nLo &= lo_cl & ~seenLo;
nHi &= hi_cl & ~seenHi;
// push lo-neighbors
while (nLo != 0L) {
long lsb = nLo & -nLo;
int nidx = Long.numberOfTrailingZeros(nLo); // 0..63
seenLo |= lsb;
stack[sp++] = nidx;
nLo &= nLo - 1;
}
// push hi-neighbors
while (nHi != 0L) {
long lsb = nHi & -nHi;
int nidx = 64 + Long.numberOfTrailingZeros(nHi); // 64..127
seenHi |= lsb;
stack[sp++] = nidx;
nHi &= nHi - 1;
}
}
if (size >= 2) penalty += (size - 1L) * 120L;
}
}
/*for (int i = 0; i < 65; i += 64) {
for (long bits = (i == 0 ? lo_cl : hi_cl); bits != X; bits &= bits - 1) { for (long bits = (i == 0 ? lo_cl : hi_cl); bits != X; bits &= bits - 1) {
int clueIdx = i + Long.numberOfTrailingZeros(bits); int clueIdx = i + Long.numberOfTrailingZeros(bits);
if (seen.get(clueIdx)) continue; if (seen.get(clueIdx)) continue;
@@ -463,7 +520,7 @@ public record SwedishGenerator(Rng rng) {
} }
if (size >= 2) penalty += ((size - 1L) * 120L); if (size >= 2) penalty += ((size - 1L) * 120L);
} }
} }*/
for (int i = 0; i < 65; i += 64) { for (int i = 0; i < 65; i += 64) {
long bits = (i == 0 ? ~lo_cl : (~hi_cl & 0xFFL)); long bits = (i == 0 ? ~lo_cl : (~hi_cl & 0xFFL));