diff --git a/src/main/java/puzzle/Export.java b/src/main/java/puzzle/Export.java index 53f9048..8763df1 100644 --- a/src/main/java/puzzle/Export.java +++ b/src/main/java/puzzle/Export.java @@ -58,7 +58,6 @@ public record Export() { record Gridded(@Delegate Grid grid) { - static boolean isLetter(byte b) { return (b & SwedishGenerator.B64) != SwedishGenerator.B0; } public static IntStream walk(byte base, long lo, long hi) { if (Slot.increasing(base)) { return IntStream.concat( @@ -109,7 +108,7 @@ public record Export() { } } //public boolean isLetterSet(int idx) { return isLetter(g[idx]); } - char NOT_CLUE_NOT_LETTER_TO(byte b, char fallback) { return isLetter(b) ? (char) (64 | b) : fallback; } + char NOT_CLUE_NOT_LETTER_TO(byte b, char fallback) { return b == SwedishGenerator.DASH ? fallback : (char) (64 | b); } String gridToString(Clues clues) { var sb = new StringBuilder(); for (var r = 0; r < R; r++) { @@ -166,10 +165,10 @@ public record Export() { 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)); } - public int arrowRow() { return Grid.r(Slot.clueIndex(slotKey)); } - public int startRow() { return Grid.r(cells[0]); } - public int startCol() { return Grid.c(cells[0]); } + public int arrowCol() { return SwedishGenerator.IT[Slot.clueIndex(slotKey)].c(); } + public int arrowRow() { return SwedishGenerator.IT[Slot.clueIndex(slotKey)].r(); } + public int startRow() { return SwedishGenerator.IT[cells[0]].r(); } + public int startCol() { return SwedishGenerator.IT[cells[0]].c(); } public boolean isReversed() { return !Slot.increasing(slotKey); } public char direction() { return DIRECTION[Slot.dir(slotKey)]; } } @@ -214,10 +213,11 @@ public record Export() { for (var rc : placed) { for (var c : rc.cells) { - minR = Math.min(minR, Grid.r(c)); - minC = Math.min(minC, Grid.c(c)); - maxR = Math.max(maxR, Grid.r(c)); - maxC = Math.max(maxC, Grid.c(c)); + val it = SwedishGenerator.IT[c]; + minR = Math.min(minR, it.r()); + minC = Math.min(minC, it.c()); + maxR = Math.max(maxR, it.r()); + maxC = Math.max(maxC, it.c()); } minR = Math.min(minR, rc.arrowRow()); minC = Math.min(minC, rc.arrowCol()); diff --git a/src/main/java/puzzle/SwedishGenerator.java b/src/main/java/puzzle/SwedishGenerator.java index 67185e7..19bdbb1 100644 --- a/src/main/java/puzzle/SwedishGenerator.java +++ b/src/main/java/puzzle/SwedishGenerator.java @@ -99,9 +99,11 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { for (int dr1 = -2; dr1 <= 2; dr1++) for (int dr2 = -2; dr2 <= 2; dr2++) for (int dc1 = -2; dc1 <= 2; dc1++) - for (int dc2 = -2; dc2 <= 2; dc2++) - MUTATE_RI[i][k++] = Grid.offset(clamp(Grid.r(i) + dr1 + dr2, 0, R - 1), - clamp(Grid.c(i) + dc1 + dc2, 0, C - 1)); + for (int dc2 = -2; dc2 <= 2; dc2++) { + val ti = IT[i]; + MUTATE_RI[i][k++] = Grid.offset(clamp(ti.r() + dr1 + dr2, 0, R - 1), + clamp(ti.c() + dc1 + dc2, 0, C - 1)); + } } } @@ -280,14 +282,12 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { final byte[] g; public long lo, hi; - public static int r(int offset) { return offset & 7; } - public static int c(int offset) { return offset >>> 3; } 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]; } - void setLetter(int idx, byte ch) { g[idx] = ch; } - void clearletter(int idx) { g[idx] = DASH; } + void setLetter(int idx, byte ch) { g[idx] = ch; } + private void clearletter(int idx) { g[idx] = DASH; } void undoPlace(long maskLo, long maskHi) { for (long b = maskLo; b != 0; b &= b - 1) clearletter(Long.numberOfTrailingZeros(b)); for (long b = maskHi; b != 0; b &= b - 1) clearletter(64 | Long.numberOfTrailingZeros(b)); @@ -305,12 +305,11 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { static long pack(int index, byte[] b) { return pack(b) | ((long) index << 40); } static long pack(byte[] b) { long w = 0; - for (var i = 0; i < b.length; i++) w |= ((long) b[i] & 63) << (i * 5); + for (var i = 0; i < b.length; i++) w |= ((long) b[i] & 31) << (i * 5); return w; } static public long from(int index, String word) { return pack(index, word.getBytes(US_ASCII)); } - static byte byteAt(long word, int idx) { return (byte) ((word >>> (idx * 5)) & 0b11111 | B64); }// word[]; } - static int intAt(long word, int idx) { return (int) (((word >>> (idx * 5))) & 0b11111); }// word[]; } + static byte byteAt(long word, int idx) { return (byte) ((word >>> (idx * 5)) & 0b11111); } static String[] clue(long w) { return CsvIndexService.clues(unpackIndex(w)); } static int simpel(long w) { return CsvIndexService.simpel(unpackIndex(w)); } static int length(long word) { return ((63 - Long.numberOfLeadingZeros(word & LETTER_MASK)) / 5) + 1; } @@ -338,7 +337,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { entry.words().add(lemma); for (var i = 0; i < L; i++) { - var letter = Lemma.intAt(lemma, i) - 1; + var letter = Lemma.byteAt(lemma, i) - 1; if (letter < 0 || letter >= 26) throw new RuntimeException("Illegal letter: " + letter + " in word " + lemma); entry.pos()[i][letter].add(idx); } @@ -724,12 +723,14 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { } static long patternForSlot(Grid grid, Slot s) { - if ((s.lo & ~grid.lo) == 0 && (s.hi & ~grid.hi) == 0) return 0; + /*if ((s.lo & ~grid.lo) == 0 && (s.hi & ~grid.hi) == 0) { + return 0; + }*/ long p = 0; if (s.increasing()) { for (long b = s.lo & ~grid.lo; b != 0; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); - int val = grid.g[idx] & 31; + int val = grid.g[idx]; if (val != 0) { int i = Long.bitCount(s.lo & ((1L << idx) - 1)); p |= ((long) (i * 26 + val)) << (i << 3); @@ -738,7 +739,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { int offset = Long.bitCount(s.lo); for (long b = s.hi & ~grid.hi; b != 0; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); - int val = grid.g[64 | idx] & 31; + int val = grid.g[64 | idx]; if (val != 0) { int i = offset + Long.bitCount(s.hi & ((1L << idx) - 1)); p |= ((long) (i * 26 + val)) << (i << 3); @@ -748,7 +749,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { int offset = Long.bitCount(s.hi); for (long b = s.hi & ~grid.hi; b != 0; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); - int val = grid.g[64 | idx] & 31; + int val = grid.g[64 | idx]; if (val != 0) { int i = Long.bitCount(s.hi & ~((1L << idx) | ((1L << idx) - 1))); p |= ((long) (i * 26 + val)) << (i << 3); @@ -756,7 +757,7 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { } for (long b = s.lo & ~grid.lo; b != 0; b &= b - 1) { int idx = Long.numberOfTrailingZeros(b); - int val = grid.g[idx] & 31; + int val = grid.g[idx]; if (val != 0) { int i = offset + Long.bitCount(s.lo & ~((1L << idx) | ((1L << idx) - 1))); p |= ((long) (i * 26 + val)) << (i << 3); diff --git a/src/test/java/puzzle/MainTest.java b/src/test/java/puzzle/MainTest.java index fd31512..0aa2e2e 100644 --- a/src/test/java/puzzle/MainTest.java +++ b/src/test/java/puzzle/MainTest.java @@ -59,10 +59,10 @@ public class MainTest { var s = slots[0]; assertEquals(8, s.length()); var cells = s.walk().toArray(); - assertEquals(0, Grid.r(cells[0])); - assertEquals(1, Grid.c(cells[0])); - assertEquals(0, Grid.r(cells[1])); - assertEquals(2, Grid.c(cells[1])); + assertEquals(0, SwedishGenerator.IT[cells[0]].r()); + assertEquals(1, SwedishGenerator.IT[cells[0]].c()); + assertEquals(0, SwedishGenerator.IT[cells[1]].r()); + assertEquals(2, SwedishGenerator.IT[cells[1]].c()); } @Test @@ -82,8 +82,8 @@ public class MainTest { clues.forEachSlot((key, lo, hi) -> { count.incrementAndGet(); assertEquals(8, Long.bitCount(lo) + Long.bitCount(hi)); - assertEquals(0, Grid.r(Long.numberOfTrailingZeros(lo))); - assertEquals(1, Grid.c(Long.numberOfTrailingZeros(lo))); + assertEquals(0, SwedishGenerator.IT[Long.numberOfTrailingZeros(lo)].r()); + assertEquals(1, SwedishGenerator.IT[Long.numberOfTrailingZeros(lo)].c()); }); assertEquals(1, count.get()); } diff --git a/src/test/java/puzzle/SwedishGeneratorTest.java b/src/test/java/puzzle/SwedishGeneratorTest.java index 6330295..41a0fd7 100644 --- a/src/test/java/puzzle/SwedishGeneratorTest.java +++ b/src/test/java/puzzle/SwedishGeneratorTest.java @@ -53,11 +53,11 @@ public class SwedishGeneratorTest { static final long ABC = Lemma.from(26, "ABC"); static final long ABD = Lemma.from(27, "ABD"); static final long AZ = Lemma.from(28, "AZ"); - static final byte LETTER_A = (byte) 'A'; - static final byte LETTER_B = (byte) 'B'; - static final byte LETTER_C = (byte) 'C'; - static final byte LETTER_X = (byte) 'X'; - static final byte LETTER_Z = (byte) 'Z'; + static final byte LETTER_A = ((byte) 'A') & 31; + static final byte LETTER_B = ((byte) 'B') & 31; + static final byte LETTER_C = ((byte) 'C') & 31; + static final byte LETTER_X = ((byte) 'X') & 31; + static final byte LETTER_Z = ((byte) 'Z') & 31; static final byte CLUE_DOWN = 0; static final byte CLUE_RIGHT = 1; static final byte CLUE_UP = 2; @@ -151,8 +151,7 @@ public class SwedishGeneratorTest { void testLemmaAndDict() { Assertions.assertEquals(Lemma.pack("APPLE".getBytes(StandardCharsets.US_ASCII)), Lemma.unpackLetters(l1)); assertEquals(5, Lemma.length(l1)); - assertEquals((byte) 'A', Lemma.byteAt(l1, 0)); - assertEquals(1, Lemma.intAt(l1, 0)); + assertEquals(LETTER_A, Lemma.byteAt(l1, 0)); var dict = new Dict(new long[]{ l1, l2, l2a, l4a, l6a, l7a, l8a }); @@ -192,12 +191,12 @@ public class SwedishGeneratorTest { assertEquals(CLUE_DOWN, Slot.dir(s.key())); assertFalse(s.horiz()); var cells = s.walk().toArray(); - assertEquals(2, Grid.r(cells[0])); - assertEquals(3, Grid.r(cells[1])); - assertEquals(4, Grid.r(cells[2])); - assertEquals(5, Grid.c(cells[0])); - assertEquals(5, Grid.c(cells[1])); - assertEquals(5, Grid.c(cells[2])); + assertEquals(2, SwedishGenerator.IT[cells[0]].r()); + assertEquals(3, SwedishGenerator.IT[cells[1]].r()); + assertEquals(4, SwedishGenerator.IT[cells[2]].r()); + assertEquals(5, SwedishGenerator.IT[cells[0]].c()); + assertEquals(5, SwedishGenerator.IT[cells[1]].c()); + assertEquals(5, SwedishGenerator.IT[cells[2]].c()); assertTrue(Slot.horiz(CLUE_RIGHT)); // right assertFalse(Slot.horiz(CLUE_DOWN)); // down