From ecf4ae913e61b63811b35c9b974b346ddf4fb56f Mon Sep 17 00:00:00 2001 From: mike Date: Wed, 14 Jan 2026 12:45:08 +0100 Subject: [PATCH] introduce bitloops --- src/main/java/puzzle/SwedishGenerator.java | 64 +++++++++++----------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/main/java/puzzle/SwedishGenerator.java b/src/main/java/puzzle/SwedishGenerator.java index 0ad4540..1ffbf09 100644 --- a/src/main/java/puzzle/SwedishGenerator.java +++ b/src/main/java/puzzle/SwedishGenerator.java @@ -129,7 +129,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { if (ok) { int k = 0; for (var n = 1; n < clueMap.length; n++) { - if (clueMap[n] != 0L) { + if (clueMap[n] != X) { k++; stats.simplicity += Lemma.simpel(clueMap[n]); } @@ -140,7 +140,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { public int wordCount() { int k = 0; for (var n = 1; n < clueMap.length; n++) { - if (clueMap[n] != 0L) { + if (clueMap[n] != X) { k++; } } @@ -422,12 +422,12 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { } } else { // first clue is highest index among hits (hi first, then lo) - if (hitsHi != 0) { + if (hitsHi != X) { 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) { + } else if (hitsLo != X) { int msb = 63 - Long.numberOfLeadingZeros(hitsLo); long stop = 1L << msb; rayLo &= ~((stop << 1) - 1); @@ -468,21 +468,21 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { long rLo = PATH_LO[key], rHi = PATH_HI[key]; long hLo = rLo & lo_cl, hHi = rHi & hi_cl; if (Slot.increasing(key)) { - if (hLo != 0) { + if (hLo != X) { rLo &= ((1L << Long.numberOfTrailingZeros(hLo)) - 1); rHi = 0; } else if (hHi != 0) { rHi &= ((1L << Long.numberOfTrailingZeros(hHi)) - 1); } } else { - if (hHi != 0) { + if (hHi != X) { int msb = 63 - Long.numberOfLeadingZeros(hHi); rHi &= ~((1L << msb << 1) - 1); rLo = 0; - } else if (hLo != 0) { + } else if (hLo != X) { int msb = 63 - Long.numberOfLeadingZeros(hLo); rLo &= ~((1L << msb << 1) - 1); } } - if ((rLo | rHi) != 0L) { + if ((rLo | rHi) != X) { hasSlots = true; if (Slot.horiz(key)) { cHLo |= rLo; @@ -499,7 +499,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { } if (!hasSlots) return 1_000_000_000L; - long seenLo = 0L, seenHi = 0L; + long seenLo = X, seenHi = X; // loop over beide helften for (int base = 0; base <= 64; base += 64) { @@ -507,7 +507,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { long seenMask = (base == 0) ? seenLo : seenHi; // "unseen clues" in deze helft - for (long bits = clueMask & ~seenMask; bits != 0L; bits &= bits - 1) { + for (long bits = clueMask & ~seenMask; bits != X; bits &= bits - 1) { int clueIdx = base | Long.numberOfTrailingZeros(bits); // start nieuwe component @@ -533,7 +533,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { nHi &= hi_cl & ~seenHi; // push lo-neighbors - while (nLo != 0L) { + while (nLo != X) { long lsb = nLo & -nLo; int nidx = Long.numberOfTrailingZeros(nLo); // 0..63 seenLo |= lsb; @@ -544,7 +544,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { } // push hi-neighbors - while (nHi != 0L) { + while (nHi != X) { long lsb = nHi & -nHi; int nidx = 64 | Long.numberOfTrailingZeros(nHi); // 64..127 seenHi |= lsb; @@ -728,19 +728,19 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { static long patternForSlot(Grid grid, final int key, final long lo, final long hi) { final long glo = grid.lo, ghi = grid.hi; - if ((lo & glo) == 0 && (hi & ghi) == 0) { + if ((lo & glo) == X && (hi & ghi) == X) { return 0; } long p = 0; if (Slot.increasing(key)) { - for (long b = lo & glo; b != 0; b &= b - 1) { + for (long b = lo & glo; b != X; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); byte val = grid.g[idx]; int i = Long.bitCount(lo & ((1L << idx) - 1)); p |= ((long) (i * 26 + val)) << (i << 3); } int offset = Long.bitCount(lo); - for (long b = hi & ghi; b != 0; b &= b - 1) { + for (long b = hi & ghi; b != X; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); byte val = grid.g[64 | idx]; int i = offset + Long.bitCount(hi & ((1L << idx) - 1)); @@ -748,13 +748,13 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { } } else { int offset = Long.bitCount(hi); - for (long b = hi & ghi; b != 0; b &= b - 1) { + for (long b = hi & ghi; b != X; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); byte val = grid.g[64 | idx]; int i = Long.bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))); p |= ((long) (i * 26 + val)) << (i << 3); } - for (long b = lo & glo; b != 0; b &= b - 1) { + for (long b = lo & glo; b != X; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); byte val = grid.g[idx]; int i = offset + Long.bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))); @@ -765,8 +765,8 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { } static int slotScore(byte[] count, long lo, long hi) { int cross = 0; - for (long b = lo; b != 0; b &= b - 1) cross += (count[Long.numberOfTrailingZeros(b)] - 1); - for (long b = hi; b != 0; b &= b - 1) cross += (count[64 | Long.numberOfTrailingZeros(b)] - 1); + for (long b = lo; b != X; b &= b - 1) cross += (count[Long.numberOfTrailingZeros(b)] - 1); + for (long b = hi; b != X; b &= b - 1) cross += (count[64 | Long.numberOfTrailingZeros(b)] - 1); return cross * 10 + Slot.length(lo, hi); } static boolean placeWord(Grid grid, final int key, final long lo, final long hi, final long w) { @@ -777,18 +777,18 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { if (grid.g[idx] != Lemma.byteAt(w, Long.bitCount(lo & ((1L << idx) - 1)))) return false; } int bcLo = Long.bitCount(lo); - for (long b = hi & ghi; b != 0; b &= b - 1) { + for (long b = hi & ghi; b != X; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); if (grid.g[64 | idx] != Lemma.byteAt(w, bcLo + Long.bitCount(hi & ((1L << idx) - 1)))) return false; } long maskLo = lo & ~glo, maskHi = hi & ~ghi; - if ((maskLo | maskHi) != 0) { - for (long b = maskLo; b != 0; b &= b - 1) { + if ((maskLo | maskHi) != X) { + for (long b = maskLo; b != X; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); grid.g[idx] = Lemma.byteAt(w, Long.bitCount(lo & ((1L << idx) - 1))); } - for (long b = maskHi; b != 0; b &= b - 1) { + for (long b = maskHi; b != X; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); grid.g[64 | idx] = Lemma.byteAt(w, bcLo + Long.bitCount(hi & ((1L << idx) - 1))); } @@ -797,22 +797,22 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { } } else { int bcHi = Long.bitCount(hi); - for (long b = hi & ghi; b != 0; b &= b - 1) { + for (long b = hi & ghi; b != X; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); if (grid.g[64 | idx] != Lemma.byteAt(w, Long.bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))))) return false; } - for (long b = lo & glo; b != 0; b &= b - 1) { + for (long b = lo & glo; b != X; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); if (grid.g[idx] != Lemma.byteAt(w, bcHi + Long.bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))))) return false; } long maskLo = lo & ~glo, maskHi = hi & ~ghi; - if ((maskLo | maskHi) != 0) { + if ((maskLo | maskHi) != X) { for (long b = maskHi; b != 0; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); grid.g[64 | idx] = Lemma.byteAt(w, Long.bitCount(hi & ~((1L << idx) | ((1L << idx) - 1)))); } - for (long b = maskLo; b != 0; b &= b - 1) { + for (long b = maskLo; b != X; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); grid.g[idx] = Lemma.byteAt(w, bcHi + Long.bitCount(lo & ~((1L << idx) | ((1L << idx) - 1)))); } @@ -826,7 +826,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { static int[] candidateInfoForPattern(long[] res, long pattern, long[][] posBitsets, int numLongs) { boolean first = true; - for (long p = pattern; p != 0; ) { + for (long p = pattern; p != X; ) { int combined = (int) (p & 0xFF); if (combined != 0) { long[] bs = posBitsets[combined - 1]; @@ -849,7 +849,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { int ki = 0; for (int k = 0; k < numLongs; k++) { long w = res[k]; - while (w != 0) { + while (w != X) { int t = Long.numberOfTrailingZeros(w); indices[ki++] = (k << 6) | t; w &= w - 1; @@ -862,7 +862,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { static int candidateCountForPattern(final long[] res, final long pattern, final long[][] posBitsets, final int numLongs) { boolean first = true; - for (long p = pattern; p != 0; ) { + for (long p = pattern; p != X; ) { int combined = (int) (p & 0xFF); if (combined != 0) { long[] bs = posBitsets[combined - 1]; @@ -886,8 +886,8 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { static void scoreSlots(int[] slotScores, Slot[] slots) { val count = new byte[SIZE]; for (var s : slots) { - for (long b = s.lo; b != 0; b &= b - 1) count[Long.numberOfTrailingZeros(b)]++; - for (long b = s.hi; b != 0; b &= b - 1) count[64 | Long.numberOfTrailingZeros(b)]++; + for (long b = s.lo; b != X; b &= b - 1) count[Long.numberOfTrailingZeros(b)]++; + for (long b = s.hi; b != X; b &= b - 1) count[64 | Long.numberOfTrailingZeros(b)]++; } for (int i = 0; i < slots.length; i++) { var slot = slots[i];