introduce bitloops

This commit is contained in:
mike
2026-01-12 23:25:59 +01:00
parent a9b4dfb422
commit 61d246e551
3 changed files with 65 additions and 60 deletions

View File

@@ -61,10 +61,15 @@ 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) { }
// 0b11
//0b00
// 0b01
// 0b10
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 long[] OFFSETS_D_IDX = Neighbors9x8.OFFSET_D_IDX; static final long[] OFFSETS_D_IDX = Neighbors9x8.OFFSET_D_IDX;
static final long[] OFFSET_D_IDX_0_BASE = Neighbors9x8.OFFSET_D_IDX_0_BASE;
static final rci[] IT = Neighbors9x8.IT; static final rci[] IT = Neighbors9x8.IT;
static final int[][] MUTATE_RI = new int[SIZE][625]; static final int[][] MUTATE_RI = new int[SIZE][625];
static final long[] NBR8_PACKED_LO = Neighbors9x8.NBR8_PACKED_LO; static final long[] NBR8_PACKED_LO = Neighbors9x8.NBR8_PACKED_LO;
@@ -317,11 +322,11 @@ public record SwedishGenerator(Rng rng) {
public static int clueIndex(int key) { return key >>> BIT_FOR_DIR; } public static int clueIndex(int key) { return key >>> BIT_FOR_DIR; }
public static int dir(int key) { return key & 7; } public static int dir(int key) { return key & 7; }
public boolean horiz() { return horiz(key); } public boolean horiz() { return horiz(key); }
public boolean reversed() { return (key & 2) == 0; }
public boolean increasing() { return (key & 2) != 0; } public boolean increasing() { return (key & 2) != 0; }
public static boolean increasing(int dir) { return (dir & 2) != 0; } public static boolean increasing(int dir) { return (dir & 2) != 0; }
public IntStream walk() { return Gridded.walk((byte) key, lo, hi); } public IntStream walk() { return Gridded.walk((byte) key, lo, hi); }
public static boolean horiz(int d) { return (d & 1) == 0; } public static boolean horiz(int d) { return (d & 1) == 0; }
public static boolean horizv2(int d) { return (d & 1) == 1; }
public static int packSlotDir(int idx, int d) { return (idx << BIT_FOR_DIR) | d; } public static int packSlotDir(int idx, int d) { return (idx << BIT_FOR_DIR) | d; }
} }
@@ -410,7 +415,7 @@ public record SwedishGenerator(Rng rng) {
} }
if ((rLo | rHi) != 0) { if ((rLo | rHi) != 0) {
hasSlots = true; hasSlots = true;
if (Slot.horiz(d + 1)) covH.or(rLo, rHi); if (Slot.horizv2(d)) covH.or(rLo, rHi);
else covV.or(rLo, rHi); else covV.or(rLo, rHi);
if ((Long.bitCount(rLo) + Long.bitCount(rHi)) < MIN_LEN) penalty += 8000; if ((Long.bitCount(rLo) + Long.bitCount(rHi)) < MIN_LEN) penalty += 8000;
} else { } else {
@@ -555,7 +560,7 @@ public record SwedishGenerator(Rng rng) {
for (var hi = out.hi; hi != X; hi &= hi - 1L) clearClues(out, 64 + Long.numberOfTrailingZeros(hi)); for (var hi = out.hi; hi != X; hi &= hi - 1L) clearClues(out, 64 + Long.numberOfTrailingZeros(hi));
return out; return out;
} }
public static void clearClues(Grid out, int idx) { if (!out.hasRoomForClue(OFFSETS_D_IDX[(out.digitAt(idx) ) | (idx << 2)])) out.clearClue(idx); } public static void clearClues(Grid out, int idx) { if (!out.hasRoomForClue(OFFSETS_D_IDX[(out.digitAt(idx)) | (idx << 2)])) out.clearClue(idx); }
Grid hillclimb(Grid start, int limit) { Grid hillclimb(Grid start, int limit) {
var best = start; var best = start;

View File

@@ -56,9 +56,9 @@ public class MainTest {
void testStaticSlotMethods() { void testStaticSlotMethods() {
// Test static horiz // Test static horiz
// dir 2 (right) is horizontal // dir 2 (right) is horizontal
assertTrue(Slot.horiz(2)); assertTrue(Slot.horizv2(1));
// dir 3 (down) is vertical // dir 3 (down) is vertical
assertFalse(Slot.horiz(3)); assertFalse(Slot.horizv2(2));
} }
@Test @Test
@@ -78,7 +78,7 @@ public class MainTest {
@Test @Test
public void testHoriz() { public void testHoriz() {
assertTrue(Slot.from(2, 0L, 0L).horiz()); assertTrue(Slot.from(2, 0L, 0L).horiz());
assertTrue(Slot.from(4, 0L, 0L).horiz()); assertTrue(Slot.from(0, 0L, 0L).horiz());
assertFalse(Slot.from(1, 0L, 0L).horiz()); assertFalse(Slot.from(1, 0L, 0L).horiz());
assertFalse(Slot.from(3, 0L, 0L).horiz()); assertFalse(Slot.from(3, 0L, 0L).horiz());
} }

View File

@@ -180,8 +180,8 @@ public class SwedishGeneratorTest {
assertEquals(5, Grid.c(cells[1])); assertEquals(5, Grid.c(cells[1]));
assertEquals(5, Grid.c(cells[2])); assertEquals(5, Grid.c(cells[2]));
assertTrue(Slot.horiz(CLUE_RIGHT + 1)); // right assertTrue(Slot.horizv2(CLUE_RIGHT)); // right
assertFalse(Slot.horiz(CLUE_DOWN + 1)); // down assertFalse(Slot.horizv2(CLUE_DOWN)); // down
} }
static int intersectSorted(int[] a, int aLen, int[] b, int bLen, int[] out) { static int intersectSorted(int[] a, int aLen, int[] b, int bLen, int[] out) {
if (aLen == 0 || bLen == 0) return 0; if (aLen == 0 || bLen == 0) return 0;
@@ -366,7 +366,7 @@ public class SwedishGeneratorTest {
assertEquals('Z', grid.byteAt(OFF_0_2)); assertEquals('Z', grid.byteAt(OFF_0_2));
assertEquals(lo, undoBuffer[0]); assertEquals(lo, undoBuffer[0]);
grid.undoPlace( undoBuffer[0], undoBuffer[1]); grid.undoPlace(undoBuffer[0], undoBuffer[1]);
assertEquals(DASH, grid.byteAt(OFF_0_1)); assertEquals(DASH, grid.byteAt(OFF_0_1));
assertEquals(DASH, grid.byteAt(OFF_0_2)); assertEquals(DASH, grid.byteAt(OFF_0_2));
} }
@@ -394,7 +394,7 @@ public class SwedishGeneratorTest {
assertEquals(32, slotScore(counts, sScore)); assertEquals(32, slotScore(counts, sScore));
// 3. Test candidateCountForPattern // 3. Test candidateCountForPattern
var words = new long[] { var words = new long[]{
Lemma.from("AT"), Lemma.from("AT"),
Lemma.from("CAT"), Lemma.from("CAT"),
Lemma.from("DOGS"), Lemma.from("DOGS"),