introduce bitloops

This commit is contained in:
mike
2026-01-14 13:43:02 +01:00
parent b1f54c2cae
commit b29831859b
3 changed files with 24 additions and 82 deletions

View File

@@ -58,7 +58,11 @@ public record Export() {
}
record Gridded(@Delegate Grid grid) {
public boolean lisLetterAt(int pos) {
if ((pos & 64) == 0)
return lisLetterAtLo(pos);
return lisLetterAtHi(pos);
}
public static IntStream walk(byte base, long lo, long hi) {
if (Slot.increasing(base)) {
return IntStream.concat(
@@ -119,7 +123,7 @@ public record Export() {
var offset = Grid.offset(r, c);
if (clues.isClue(offset))
sb.append((char) (48 | clues.digitAt(offset)));
else if (grid.lisLetterAt(offset))
else if (lisLetterAt(offset))
sb.append((char) (64 | grid.letter32At(offset)));
else
sb.append(' ');
@@ -144,7 +148,7 @@ public record Export() {
var offset = Grid.offset(r, c);
if (clues.isClue(offset)) {
sb.append(clueChar.replace(new Cell(grid, clues, offset, clues.digitAt(offset))));
} else if (grid.lisLetterAt(offset)) {
} else if (lisLetterAt(offset)) {
sb.append(NOT_CLUE_NOT_LETTER_TO(grid.letter32At(offset)));
} else {
sb.append(emptyFallback);
@@ -192,7 +196,6 @@ public record Export() {
public record PuzzleResult(Clued mask, FillResult filled) {
boolean inBounds(int idx) { return idx >= 0 && idx < SwedishGenerator.SIZE; }
Placed extractPlacedFromSlot(Slot s, long lemma) { return new Placed(lemma, s.key(), s.walk().toArray()); }
public ExportedPuzzle exportFormatFromFilled(int difficulty, Rewards rewards) {
var g = filled().grid();
@@ -236,7 +239,6 @@ public record Export() {
var letterAt = new HashMap<Integer, Character>();
for (var p : placed) {
for (var c : p.cells) {
if (!inBounds(c)) throw new RuntimeException();
if (mask.notClue(c) && g.lisLetterAt(c)) {
letterAt.put(c, (char) (64 | g.letter32At(c)));
}

View File

@@ -277,12 +277,6 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
static int offset(int r, int c) { return r | (c << 3); }
/// the pos will never target a clue
public byte letter32At(int pos) { return g[pos]; }
public boolean lisLetterAt(int pos) {
if ((pos & 64) == 0)
return lisLetterAtLo(pos);
return lisLetterAtHi(pos);
}
public boolean lisLetterAtLo(int pos) { return (lo & (1L << pos)) != X; }
public boolean lisLetterAtHi(int pos) { return (hi & (1L << (pos & 63))) != X; }
void setLetterLo(int idx, byte ch) {
@@ -387,11 +381,11 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
public static boolean increasing(int dir) { return (dir & 2) == 0; }
public IntStream walk() { return Gridded.walk((byte) key, lo, hi); }
public static boolean horiz(int d) { return (d & 1) != 0; }
public static int packSlotDir(int idx, int d) { return (idx << BIT_FOR_DIR) | d; }
public static int packSlotKey(int idx, int d) { return (idx << BIT_FOR_DIR) | d; }
}
private static void processSlot(Clues grid, SlotVisitor visitor, int idx) {
int key = Slot.packSlotDir(idx, grid.digitAt(idx)); // 0..3
int key = Slot.packSlotKey(idx, grid.digitAt(idx)); // 0..3
long rayLo = PATH_LO[key];
long rayHi = PATH_HI[key];
@@ -451,7 +445,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
int clueIdx = Long.numberOfTrailingZeros(lsb);
int v = (grid.vlo & lsb) != 0 ? 1 : 0;
int r = (grid.rlo & lsb) != 0 ? 1 : 0;
int key = Slot.packSlotDir(clueIdx, (r << 1) | v);
int key = Slot.packSlotKey(clueIdx, (r << 1) | v);
long rLo = PATH_LO[key], rHi = PATH_HI[key];
long hLo = rLo & lo_cl, hHi = rHi & hi_cl;
if (Slot.increasing(key)) {
@@ -488,7 +482,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
int clueIdx = Long.numberOfTrailingZeros(lsb);
int v = (grid.vhi & lsb) != 0 ? 1 : 0;
int r = (grid.rhi & lsb) != 0 ? 1 : 0;
int key = Slot.packSlotDir(64 | clueIdx, (r << 1) | v);
int key = Slot.packSlotKey(64 | clueIdx, (r << 1) | v);
long rLo = PATH_LO[key], rHi = PATH_HI[key];
long hLo = rLo & lo_cl, hHi = rHi & hi_cl;
if (Slot.increasing(key)) {
@@ -612,7 +606,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
idx = rng.randint(0, SIZE_MIN_1);
if (g.isClue(idx)) continue;
var d_idx = rng.randint2bitByte();
if (g.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotDir(idx, d_idx)])) {
if (g.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotKey(idx, d_idx)])) {
g.setClue(idx, d_idx);
placed++;
}
@@ -626,7 +620,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
ri = bytes[rng.randint(0, 624)];
if (!c.clueless(ri)) {
var d_idx = rng.randint2bitByte();
if (c.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotDir(ri, d_idx)])) c.setClue(ri, d_idx);
if (c.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotKey(ri, d_idx)])) c.setClue(ri, d_idx);
}
}
return c;
@@ -657,7 +651,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
for (var hi = out.hi; hi != X; hi &= hi - 1L) clearClues(out, 64 | Long.numberOfTrailingZeros(hi));
return out;
}
public static void clearClues(Clues out, int idx) { if (!out.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotDir(idx, out.digitAt(idx))])) out.clearClue(idx); }
public static void clearClues(Clues out, int idx) { if (!out.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotKey(idx, out.digitAt(idx))])) out.clearClue(idx); }
Clues hillclimb(Clues start, int limit) {
var best = start;