diff --git a/src/main/java/puzzle/Export.java b/src/main/java/puzzle/Export.java index 8874a36..2a67b56 100644 --- a/src/main/java/puzzle/Export.java +++ b/src/main/java/puzzle/Export.java @@ -160,7 +160,7 @@ public record Export() { record Placed(long lemma, int slotKey, int[] cells) { - static final char[] DIRECTION = { '\0', Placed.VERTICAL, Placed.HORIZONTAL, Placed.VERTICAL, Placed.HORIZONTAL, Placed.VERTICAL }; + static final char[] DIRECTION = { Placed.VERTICAL, Placed.HORIZONTAL, Placed.VERTICAL, Placed.HORIZONTAL }; public static final char HORIZONTAL = 'h'; static final char VERTICAL = 'v'; public int arrowCol() { return Grid.c(Slot.clueIndex(slotKey)); } diff --git a/src/main/java/puzzle/SwedishGenerator.java b/src/main/java/puzzle/SwedishGenerator.java index 62da830..a8bac21 100644 --- a/src/main/java/puzzle/SwedishGenerator.java +++ b/src/main/java/puzzle/SwedishGenerator.java @@ -68,8 +68,7 @@ public record SwedishGenerator(Rng rng) { static final byte B0 = (byte) 0; static final byte B64 = (byte) 64; - 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 long[] OFFSETS_D_IDX = Neighbors9x8.OFFSET_D_IDX_0_BASE; static final rci[] IT = Neighbors9x8.IT; static final int[][] MUTATE_RI = new int[SIZE][625]; static final long[] NBR8_PACKED_LO = Neighbors9x8.NBR8_PACKED_LO; @@ -314,19 +313,18 @@ public record SwedishGenerator(Rng rng) { static record Slot(int key, long lo, long hi) { - static final int BIT_FOR_DIR = 3; + static final int BIT_FOR_DIR = 2; static Slot from(int key, long lo, long hi) { return new Slot(key, lo, hi); } public int len() { return Long.bitCount(lo) + Long.bitCount(hi); } public int clueIndex() { return clueIndex(key); } 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 & 3; } public boolean horiz() { return horiz(key); } - public boolean increasing() { return (key & 2) != 0; } - public static boolean increasing(int dir) { return (dir & 2) != 0; } + public boolean increasing() { return (key & 2) == 0; } + 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 boolean horizv2(int d) { return (d & 1) == 1; } + public static boolean horiz(int d) { return (d & 1) != 0; } public static int packSlotDir(int idx, int d) { return (idx << BIT_FOR_DIR) | d; } } @@ -343,7 +341,7 @@ public record SwedishGenerator(Rng rng) { // slice ray to stop before first clue, depending on direction monotonicity // right/down => increasing indices; up/left => decreasing indices - boolean increasing = Slot.increasing(d + 1); + boolean increasing = Slot.increasing(d); if (increasing) { // first clue is lowest index among hits (lo first, then hi) @@ -371,7 +369,7 @@ public record SwedishGenerator(Rng rng) { } if ((rayLo | rayHi) != 0) { - visitor.visit(Slot.packSlotDir(idx, d + 1), rayLo, rayHi); + visitor.visit(Slot.packSlotDir(idx, d), rayLo, rayHi); } } @@ -398,7 +396,7 @@ public record SwedishGenerator(Rng rng) { int key = (clueIdx << 2) | d; long rLo = PATH_LO[key], rHi = PATH_HI[key]; long hLo = rLo & lo_cl, hHi = rHi & hi_cl; - if (Slot.increasing(d + 1)) { + if (Slot.increasing(d)) { if (hLo != 0) { rLo &= ((1L << Long.numberOfTrailingZeros(hLo)) - 1); rHi = 0; @@ -415,7 +413,7 @@ public record SwedishGenerator(Rng rng) { } if ((rLo | rHi) != 0) { hasSlots = true; - if (Slot.horizv2(d)) covH.or(rLo, rHi); + if (Slot.horiz(d)) covH.or(rLo, rHi); else covV.or(rLo, rHi); if ((Long.bitCount(rLo) + Long.bitCount(rHi)) < MIN_LEN) penalty += 8000; } else { diff --git a/src/test/java/puzzle/ExportFormatTest.java b/src/test/java/puzzle/ExportFormatTest.java index 59a20cb..17cbc0d 100644 --- a/src/test/java/puzzle/ExportFormatTest.java +++ b/src/test/java/puzzle/ExportFormatTest.java @@ -19,9 +19,9 @@ import static puzzle.SwedishGenerator.*; public class ExportFormatTest { - static final byte CLUE_UP = 0; + static final byte CLUE_DOWN = 0; static final byte CLUE_RIGHT = 1; - static final byte CLUE_DOWN = 2; + static final byte CLUE_UP = 2; static final byte CLUE_LEFT = 3; @Test @@ -34,8 +34,8 @@ public class ExportFormatTest { // This creates a slot starting at (0,1) var clueMap = new HashMap(); - // key = (cellIndex << 3) | (direction + 1) - var key = (0 << 3) | (CLUE_RIGHT + 1); + // key = (cellIndex << 2) | (direction) + var key = (0 << 2) | (CLUE_RIGHT); clueMap.put(key, Lemma.from("TEST")); // Manually fill the grid letters for "TEST" at (0,1), (0,2), (0,3), (0,4) diff --git a/src/test/java/puzzle/MainTest.java b/src/test/java/puzzle/MainTest.java index 0114f52..e03b5af 100644 --- a/src/test/java/puzzle/MainTest.java +++ b/src/test/java/puzzle/MainTest.java @@ -19,9 +19,9 @@ public class MainTest { static final byte LETTER_A = (byte) 'A'; static final byte LETTER_B = (byte) 'B'; static final byte LETTER_Z = (byte) 'Z'; - static final byte CLUE_UP = 0; + static final byte CLUE_DOWN = 0; static final byte CLUE_RIGHT = 1; - static final byte CLUE_DOWN = 2; + static final byte CLUE_UP = 2; static final byte CLUE_LEFT = 3; static final int OFF_0_0 = Grid.offset(0, 0); @@ -55,10 +55,10 @@ public class MainTest { @Test void testStaticSlotMethods() { // Test static horiz - // dir 2 (right) is horizontal - assertTrue(Slot.horizv2(1)); - // dir 3 (down) is vertical - assertFalse(Slot.horizv2(2)); + // dir 1 (right) is horizontal + assertTrue(Slot.horiz(1)); + // dir 0 (down) is vertical + assertFalse(Slot.horiz(0)); } @Test @@ -77,10 +77,10 @@ public class MainTest { } @Test public void testHoriz() { - assertTrue(Slot.from(2, 0L, 0L).horiz()); - assertTrue(Slot.from(0, 0L, 0L).horiz()); - assertFalse(Slot.from(1, 0L, 0L).horiz()); - assertFalse(Slot.from(3, 0L, 0L).horiz()); + assertTrue(Slot.from(1, 0L, 0L).horiz()); // Right + assertTrue(Slot.from(3, 0L, 0L).horiz()); // Left + assertFalse(Slot.from(0, 0L, 0L).horiz()); // Down + assertFalse(Slot.from(2, 0L, 0L).horiz()); // Up } @Test public void testGridBasics() { @@ -178,9 +178,9 @@ public class MainTest { // Regression baseline for seed search starting at 12347, pop 4, gens 20 Assertions.assertEquals(12348, foundSeed, "Found seed changed"); Assertions.assertEquals(18, res.filled().clueMap().size(), "Number of assigned words changed"); - Assertions.assertEquals("DISCO", Lemma.asWord(res.filled().clueMap().get(476))); - Assertions.assertEquals(3332734179516361088L, res.filled().grid().grid().lo); - Assertions.assertEquals(128L, res.filled().grid().grid().hi); + Assertions.assertEquals("TROTS", Lemma.asWord(res.filled().clueMap().get(282))); + Assertions.assertEquals(74732156493031040L, res.filled().grid().grid().lo); + Assertions.assertEquals(193L, res.filled().grid().grid().hi); } boolean isLetter(byte b) { return (b & 64) != 0; } @Test diff --git a/src/test/java/puzzle/SwedishGeneratorTest.java b/src/test/java/puzzle/SwedishGeneratorTest.java index eb8c6f7..368c406 100644 --- a/src/test/java/puzzle/SwedishGeneratorTest.java +++ b/src/test/java/puzzle/SwedishGeneratorTest.java @@ -16,9 +16,9 @@ public class SwedishGeneratorTest { static final byte LETTER_C = (byte) 'C'; static final byte LETTER_X = (byte) 'X'; static final byte LETTER_Z = (byte) 'Z'; - static final byte CLUE_UP = 0; + static final byte CLUE_DOWN = 0; static final byte CLUE_RIGHT = 1; - static final byte CLUE_DOWN = 2; + static final byte CLUE_UP = 2; static final byte CLUE_LEFT = 3; static final int OFF_0_0 = Grid.offset(0, 0); @@ -36,7 +36,7 @@ public class SwedishGeneratorTest { @Test void testPatternForSlotAllLetters() { var grid = new Grid(new byte[]{ LETTER_A, LETTER_B, LETTER_C }); - var slot = Slot.from(18 << Slot.BIT_FOR_DIR | (CLUE_RIGHT + 1), 7L, 0L); + var slot = Slot.from(18 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L); long pattern = patternForSlot(grid, slot); assertEquals(1 | (2 << 5) | (3 << 10), pattern); @@ -45,7 +45,7 @@ public class SwedishGeneratorTest { @Test void testPatternForSlotMixed() { var grid = new Grid(new byte[]{ LETTER_A, DASH, LETTER_C }); - var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT + 1), 7L, 0L); + var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L); long pattern = patternForSlot(grid, slot); assertEquals(1 | (0 << 5) | (3 << 10), pattern); @@ -54,7 +54,7 @@ public class SwedishGeneratorTest { @Test void testPatternForSlotAllDashes() { var grid = new Grid(new byte[]{ DASH, DASH, DASH }); // - - - - var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT + 1), 7L, 0L); + var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L); long pattern = patternForSlot(grid, slot); assertEquals(0, pattern); @@ -63,7 +63,7 @@ public class SwedishGeneratorTest { @Test void testPatternForSlotSingleLetter() { var grid = new Grid(new byte[]{ LETTER_A, DASH, DASH }); - var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT + 1), 7L, 0L); + var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L); long pattern = patternForSlot(grid, slot); assertEquals(1, pattern); @@ -157,7 +157,7 @@ public class SwedishGeneratorTest { // key = (r << 8) | (c << 4) | d var offset = OFF_2_3; System.out.println("[DEBUG_LOG] Grid.offset(2, 3) = " + offset); - var key = (offset << Slot.BIT_FOR_DIR) | (CLUE_DOWN + 1); + var key = (offset << Slot.BIT_FOR_DIR) | (CLUE_DOWN); System.out.println("[DEBUG_LOG] key = " + key); long lo = 0; // pos 0: (2, 5) @@ -170,7 +170,7 @@ public class SwedishGeneratorTest { var s = Slot.from(key, lo, 0L); System.out.println("[DEBUG_LOG] s.dir() = " + Slot.dir(s.key())); assertEquals(OFF_2_3, s.clueIndex()); - assertEquals(CLUE_DOWN + 1, Slot.dir(s.key())); + assertEquals(CLUE_DOWN, Slot.dir(s.key())); assertFalse(s.horiz()); var cells = s.walk().toArray(); assertEquals(2, Grid.r(cells[0])); @@ -180,8 +180,8 @@ public class SwedishGeneratorTest { assertEquals(5, Grid.c(cells[1])); assertEquals(5, Grid.c(cells[2])); - assertTrue(Slot.horizv2(CLUE_RIGHT)); // right - assertFalse(Slot.horizv2(CLUE_DOWN)); // down + assertTrue(Slot.horiz(CLUE_RIGHT)); // right + assertFalse(Slot.horiz(CLUE_DOWN)); // down } static int intersectSorted(int[] a, int aLen, int[] b, int bLen, int[] out) { if (aLen == 0 || bLen == 0) return 0; @@ -269,7 +269,7 @@ public class SwedishGeneratorTest { assertTrue(s.len() >= 2); assertEquals(OFF_0_0, s.clueIndex()); - assertEquals(CLUE_RIGHT + 1, Slot.dir(s.key())); + assertEquals(CLUE_RIGHT, Slot.dir(s.key())); } @Test @@ -315,7 +315,7 @@ public class SwedishGeneratorTest { void testPlaceWord() { var grid = Grid.createEmpty(); // Slot at OFF_0_0 length 3, horizontal (right) - var key = (OFF_0_0 << Slot.BIT_FOR_DIR) | (CLUE_RIGHT + 1); + var key = (OFF_0_0 << Slot.BIT_FOR_DIR) | (CLUE_RIGHT); var lo = (1L << OFF_0_0) | (1L << OFF_0_1) | (1L << OFF_0_2); var s = Slot.from(key, lo, 0L); var w1 = Lemma.from("ABC"); @@ -354,7 +354,7 @@ public class SwedishGeneratorTest { void testBacktrackingHelpers() { var grid = Grid.createEmpty(); // Slot at 0,1 length 2 - var key = (OFF_0_0 << Slot.BIT_FOR_DIR) | (CLUE_RIGHT + 1); + var key = (OFF_0_0 << Slot.BIT_FOR_DIR) | (CLUE_RIGHT); var lo = (1L << OFF_0_1) | (1L << OFF_0_2); var s = Slot.from(key, lo, 0L); var w = Lemma.from("AZ"); @@ -374,14 +374,14 @@ public class SwedishGeneratorTest { @Test void testInnerWorkings() { // 1. Test Slot.increasing - assertFalse(Slot.increasing(CLUE_LEFT + 1)); // Left - assertTrue(Slot.increasing(CLUE_RIGHT + 1)); // Right - assertTrue(Slot.increasing(CLUE_DOWN + 1)); // Down - assertFalse(Slot.increasing(CLUE_UP + 1)); // Up + assertFalse(Slot.increasing(CLUE_LEFT)); // Left + assertTrue(Slot.increasing(CLUE_RIGHT)); // Right + assertTrue(Slot.increasing(CLUE_DOWN)); // Down + assertFalse(Slot.increasing(CLUE_UP)); // Up - var sInc = Slot.from((0 << Slot.BIT_FOR_DIR) | CLUE_RIGHT + 1, 1L, 0L); + var sInc = Slot.from((0 << Slot.BIT_FOR_DIR) | CLUE_RIGHT, 1L, 0L); assertTrue(sInc.increasing()); - var sDec = Slot.from((0 << Slot.BIT_FOR_DIR) | CLUE_LEFT + 1, 1L, 0L); + var sDec = Slot.from((0 << Slot.BIT_FOR_DIR) | CLUE_LEFT, 1L, 0L); assertFalse(sDec.increasing()); // 2. Test slotScore