introduce bitloops

This commit is contained in:
mike
2026-01-21 06:38:25 +01:00
parent dd53009e69
commit 1e13d39153
46 changed files with 51 additions and 150429 deletions

View File

@@ -16,7 +16,7 @@ import static puzzle.Export.Clue.DOWN0;
import static puzzle.Export.Clue.RIGHT1;
import static puzzle.Masker.Clues.createEmpty;
import static puzzle.Masker.Slot;
import static puzzle.SwedishGenerator.C;
import static puzzle.Masker.C;
import static puzzle.SwedishGenerator.Lemma;
import static puzzle.SwedishGenerator.X;
@@ -31,7 +31,7 @@ import static puzzle.SwedishGenerator.X;
*/
public record Export() {
public static final ThreadLocal<byte[]> BYTES = ThreadLocal.withInitial(() -> new byte[SwedishGenerator.MAX_WORD_LENGTH]);
public static final ThreadLocal<byte[]> BYTES = ThreadLocal.withInitial(() -> new byte[8]);
static final byte CLUE_DOWN = 0;
static final byte CLUE_RIGHT = 1;
static final byte CLUE_UP = 2;
@@ -101,9 +101,6 @@ public record Export() {
return stream.build();
}
public Slotinfo[] slots() {
return slots(DictData.DICT);
}
public Slotinfo[] slots(Dict D) {
return Masker.slots(c, D.index());
}
@@ -237,7 +234,8 @@ public record Export() {
return new ExportedPuzzle(grid.exportGrid(_ -> '#', '#'), new WordOut[0], 1, rewards);
}
var placed = Arrays.stream(slots).map(slot -> new Placed(slot.assign().w, slot.key(), Gridded.cellWalk((byte) slot.key(), slot.lo(), slot.hi()).toArray())).toArray(Placed[]::new);
var placed = Arrays.stream(slots).map(slot -> new Placed(slot.assign().w, slot.key(), Gridded.cellWalk((byte) slot.key(), slot.lo(), slot.hi()).toArray())).toArray(
Placed[]::new);
// 2) bounding box around all word cells + arrow cells, with 1-cell margin
int minR = Integer.MAX_VALUE, minC = Integer.MAX_VALUE;

View File

@@ -349,7 +349,7 @@ public class Main {
}
}
static Clues generateNewClues(Rng rng, Opts opts) {
var masker = new Masker(rng, new int[STACK_SIZE], Masker.Clues.createEmpty());
var masker = new Masker(rng, new int[Masker.STACK_SIZE], Masker.Clues.createEmpty());
return masker.generateMask(opts.clueSize, opts.pop, opts.gens, opts.offspring);
}
static PuzzleResult _attempt(Rng rng, Dict dict, Opts opts) {

View File

@@ -18,6 +18,11 @@ public final class Masker {
public static final long[] PATH_HI = Neighbors9x8.PATH_HI;
public static final long MASK_LO = -1L;
public static final long MASK_HI = Neighbors9x8.MASK_HI;//(1L << (SIZE - 64)) - 1;
public static final int MIN_LEN = Neighbors9x8.MIN_LEN;//Config.MIN_LEN;
public static final int STACK_SIZE = 128;
public static final int C = Neighbors9x8.C;
public static final int R = Neighbors9x8.R;
public static final double SIZED = Neighbors9x8.SIZED;// ~18
private final Rng rng;
private final int[] stack;
private final Clues cache;
@@ -134,9 +139,9 @@ public final class Masker {
var hitsLo = rayLo & lo;
var hitsHi = rayHi & hi;
if (hitsHi != X) return (Long.bitCount(rayHi & -(1L << 63 - numberOfLeadingZeros(hitsHi) << 1)) >= SwedishGenerator.MIN_LEN);
else if (hitsLo != X) return (Long.bitCount(rayLo & -(1L << 63 - numberOfLeadingZeros(hitsLo) << 1)) + Long.bitCount(rayHi) >= SwedishGenerator.MIN_LEN);
else return (Long.bitCount(rayLo) + Long.bitCount(rayHi) >= SwedishGenerator.MIN_LEN);
if (hitsHi != X) return (Long.bitCount(rayHi & -(1L << 63 - numberOfLeadingZeros(hitsHi) << 1)) >= MIN_LEN);
else if (hitsLo != X) return (Long.bitCount(rayLo & -(1L << 63 - numberOfLeadingZeros(hitsLo) << 1)) + Long.bitCount(rayHi) >= MIN_LEN);
else return (Long.bitCount(rayLo) + Long.bitCount(rayHi) >= MIN_LEN);
}
private static boolean validSlot(long lo, long hi, int key) {
var rayLo = PATH_LO[key];
@@ -144,9 +149,9 @@ public final class Masker {
var hitsLo = rayLo & lo;
var hitsHi = rayHi & hi;
if (hitsLo != X) return (Long.bitCount(rayLo & ((1L << numberOfTrailingZeros(hitsLo)) - 1)) >= SwedishGenerator.MIN_LEN);
else if (hitsHi != X) return (Long.bitCount(rayLo) + Long.bitCount(rayHi & ((1L << numberOfTrailingZeros(hitsHi)) - 1)) >= SwedishGenerator.MIN_LEN);
else return (Long.bitCount(rayLo) + Long.bitCount(rayHi) >= SwedishGenerator.MIN_LEN);
if (hitsLo != X) return (Long.bitCount(rayLo & ((1L << numberOfTrailingZeros(hitsLo)) - 1)) >= MIN_LEN);
else if (hitsHi != X) return (Long.bitCount(rayLo) + Long.bitCount(rayHi & ((1L << numberOfTrailingZeros(hitsHi)) - 1)) >= MIN_LEN);
else return (Long.bitCount(rayLo) + Long.bitCount(rayHi) >= MIN_LEN);
}
private static void processSlot(Clues c, SlotVisitor visitor, int key) {
var rayLo = PATH_LO[key];

View File

@@ -40,21 +40,12 @@ import static java.nio.charset.StandardCharsets.US_ASCII;
)
public record SwedishGenerator() {
public static final long X = 0L;
public static final int C = Neighbors9x8.C;
public static final int R = Neighbors9x8.R;
public static final int SIZE = Neighbors9x8.SIZE;// ~18
public static final int SIZE_MIN_1 = Neighbors9x8.SIZE_MIN_1;// ~18
public static final double SIZED = Neighbors9x8.SIZED;// ~18
public static final int MAX_WORD_LENGTH = Neighbors9x8.R;
public static final int MAX_WORD_LENGTH_PLUS_ONE = MAX_WORD_LENGTH + 1;
public static final int MIN_LEN = Neighbors9x8.MIN_LEN;//Config.MIN_LEN;
public static final int MAX_TRIES_PER_SLOT = 500;//Config.MAX_TRIES_PER_SLOT;
public static final int STACK_SIZE = 128;
public static final long RANGE_0_SIZE = Neighbors9x8.RANGE_0_SIZE;// (long) SIZE_MIN_1 - 0L + 1L
public static final long RANGE_0_624 = Neighbors9x8.RANGE_0_624;//624L - 0L + 1L;
static final int PICK_NOT_DONE = -1;
static final int PICK_DONE = 0;
public static final long X = 0L;
public static final int SIZE = Neighbors9x8.SIZE;// ~18
public static final int MAX_TRIES_PER_SLOT = 500;//Config.MAX_TRIES_PER_SLOT;
public static final long RANGE_0_SIZE = Neighbors9x8.RANGE_0_SIZE;// (long) SIZE_MIN_1 - 0L + 1L
public static final long RANGE_0_624 = Neighbors9x8.RANGE_0_624;//624L - 0L + 1L;
public static boolean isLo(int n) { return (n & 64) == 0; }
interface Bit1029 {
@@ -120,9 +111,9 @@ public record SwedishGenerator() {
for (long w = word & LETTER_MASK; w != 0; w >>>= 5) bytes[bi++] = (byte) ((w & 31) | 64);
return new String(bytes, 0, bi, US_ASCII);
}
static int unpackIndex(long w) { return (int) (w >>> 40); }
static int unpackSize(long w) { return (int) (w >>> 40) & 7; }
static int unpackLetters(long w) { return (int) (w & LETTER_MASK); }
static int unpackIndex(long w) { return (int) (w >>> 40); }
static int unpackSize(long w) { return (int) (w >>> 40) & 7; }
static int unpackLetters(long w) { return (int) (w & LETTER_MASK); }
static long pack43(long w) {
return w & INDEX_MASK;
}
@@ -213,6 +204,8 @@ public record SwedishGenerator() {
val t0 = System.currentTimeMillis();
class Solver {
static final int PICK_NOT_DONE = -1;
static final int PICK_DONE = 0;
long nodes;
long backtracks;
long glo = grid.lo, ghi = grid.hi;