introduce bitloops

This commit is contained in:
mike
2026-01-17 16:37:48 +01:00
parent c76d463c8c
commit 9367833407
38 changed files with 147 additions and 93 deletions

View File

@@ -10,14 +10,11 @@ public final class DictDataL2 {
static final int POS_LEN = 208;
private static long[] words() {
return DictDataL2W0.DATA;
return DictDataL2W0.get();
}
private static long[] posFlat() {
long[] out = new long[POS_LEN];
int k = 0;
k = copy(out, k, DictDataL2P0.DATA);
return out;
return DictDataL2P0.get();
}
public static SwedishGenerator.DictEntry entry() {

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL2P0 {
private DictDataL2P0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x2210a009040800L,
0x308000004108008L,
0x0L,
@@ -212,4 +213,5 @@ public final class DictDataL2P0 {
0x0L,
0x0L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL2W0 {
private DictDataL2W0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x100000001c5L,
0x90000000245L,
0x1100000000b4L,
@@ -215,4 +216,5 @@ public final class DictDataL2W0 {
0x6890000000066L,
0x6910000000156L
};
}
}

View File

@@ -10,14 +10,11 @@ public final class DictDataL3 {
static final int POS_LEN = 1326;
private static long[] words() {
return DictDataL3W0.DATA;
return DictDataL3W0.get();
}
private static long[] posFlat() {
long[] out = new long[POS_LEN];
int k = 0;
k = copy(out, k, DictDataL3P0.DATA);
return out;
return DictDataL3P0.get();
}
public static SwedishGenerator.DictEntry entry() {

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL3P0 {
private DictDataL3P0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x2000000000001010L,
0x0L,
0x800300e020008000L,
@@ -1330,4 +1331,5 @@ public final class DictDataL3P0 {
0x0L,
0xc08009L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL3W0 {
private DictDataL3W0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x200000038a5L,
0xa0000005024L,
0x1200000050a8L,
@@ -1052,4 +1053,5 @@ public final class DictDataL3W0 {
0x20b20000006ae4L,
0x20ba00000069faL
};
}
}

View File

@@ -10,14 +10,11 @@ public final class DictDataL4 {
static final int POS_LEN = 4264;
private static long[] words() {
return DictDataL4W0.DATA;
return DictDataL4W0.get();
}
private static long[] posFlat() {
long[] out = new long[POS_LEN];
int k = 0;
k = copy(out, k, DictDataL4P0.DATA);
return out;
return DictDataL4P0.get();
}
public static SwedishGenerator.DictEntry entry() {

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL4P0 {
private DictDataL4P0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x800000000L,
0x1000000000L,
0xc000000000800L,
@@ -4268,4 +4269,5 @@ public final class DictDataL4P0 {
0x0L,
0x4L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL4W0 {
private DictDataL4W0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x3000009042eL,
0xb00000a152eL,
0x1300000714a7L,
@@ -2609,4 +2610,5 @@ public final class DictDataL4W0 {
0x515b0000063688L,
0x51630000085288L
};
}
}

View File

@@ -10,14 +10,14 @@ public final class DictDataL5 {
static final int POS_LEN = 9100;
private static long[] words() {
return DictDataL5W0.DATA;
return DictDataL5W0.get();
}
private static long[] posFlat() {
long[] out = new long[POS_LEN];
int k = 0;
k = copy(out, k, DictDataL5P0.DATA);
k = copy(out, k, DictDataL5P1.DATA);
k = copy(out, k, DictDataL5P0.get());
k = copy(out, k, DictDataL5P1.get());
return out;
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL5P0 {
private DictDataL5P0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0xc0000080001000L,
0x8000060000010L,
0xc0000000004000L,
@@ -8196,4 +8197,5 @@ public final class DictDataL5P0 {
0xe42b1c001045cf6dL,
0x1f0441a0de89e5fdL
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL5P1 {
private DictDataL5P1() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x2c8480052e3080L,
0x8405941a12001100L,
0x145d84220a201L,
@@ -912,4 +913,5 @@ public final class DictDataL5P1 {
0x0L,
0x0L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL5W0 {
private DictDataL5W0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x40000e2b4aeL,
0xc000149c8a5L,
0x140000e29d25L,
@@ -4438,4 +4439,5 @@ public final class DictDataL5W0 {
0x8a840000c7c877L,
0x8a8c000055612dL
};
}
}

View File

@@ -10,15 +10,15 @@ public final class DictDataL6 {
static final int POS_LEN = 19500;
private static long[] words() {
return DictDataL6W0.DATA;
return DictDataL6W0.get();
}
private static long[] posFlat() {
long[] out = new long[POS_LEN];
int k = 0;
k = copy(out, k, DictDataL6P0.DATA);
k = copy(out, k, DictDataL6P1.DATA);
k = copy(out, k, DictDataL6P2.DATA);
k = copy(out, k, DictDataL6P0.get());
k = copy(out, k, DictDataL6P1.get());
k = copy(out, k, DictDataL6P2.get());
return out;
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL6P0 {
private DictDataL6P0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x60000010024001L,
0x200000000800L,
0x0L,
@@ -8196,4 +8197,5 @@ public final class DictDataL6P0 {
0x10200000c41180L,
0x400000a4000000L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL6P1 {
private DictDataL6P1() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x4008000104000000L,
0xc200000e300002L,
0x2020L,
@@ -8196,4 +8197,5 @@ public final class DictDataL6P1 {
0x0L,
0x0L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL6P2 {
private DictDataL6P2() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x0L,
0x0L,
0x0L,
@@ -3120,4 +3121,5 @@ public final class DictDataL6P2 {
0x0L,
0x8000000000000000L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL6W0 {
private DictDataL6W0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x5001c52b181L,
0xd001c5a15edL,
0x150008e0b4a9L,
@@ -8004,4 +8005,5 @@ public final class DictDataL6W0 {
0xf9f500265561e2L,
0xf9fd00349ac6d4L
};
}
}

View File

@@ -12,18 +12,18 @@ public final class DictDataL7 {
private static long[] words() {
long[] out = new long[WORDS_LEN];
int k = 0;
k = copy(out, k, DictDataL7W0.DATA);
k = copy(out, k, DictDataL7W1.DATA);
k = copy(out, k, DictDataL7W0.get());
k = copy(out, k, DictDataL7W1.get());
return out;
}
private static long[] posFlat() {
long[] out = new long[POS_LEN];
int k = 0;
k = copy(out, k, DictDataL7P0.DATA);
k = copy(out, k, DictDataL7P1.DATA);
k = copy(out, k, DictDataL7P2.DATA);
k = copy(out, k, DictDataL7P3.DATA);
k = copy(out, k, DictDataL7P0.get());
k = copy(out, k, DictDataL7P1.get());
k = copy(out, k, DictDataL7P2.get());
k = copy(out, k, DictDataL7P3.get());
return out;
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL7P0 {
private DictDataL7P0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x400000000001001L,
0x1c0003800c0L,
0x1800000cL,
@@ -8196,4 +8197,5 @@ public final class DictDataL7P0 {
0x0L,
0x0L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL7P1 {
private DictDataL7P1() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x0L,
0x0L,
0x0L,
@@ -8196,4 +8197,5 @@ public final class DictDataL7P1 {
0x0L,
0x0L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL7P2 {
private DictDataL7P2() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x0L,
0x0L,
0x0L,
@@ -8196,4 +8197,5 @@ public final class DictDataL7P2 {
0x2040000001L,
0x8000L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL7P3 {
private DictDataL7P3() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x2009202L,
0x1000000204L,
0x80000000000L,
@@ -7096,4 +7097,5 @@ public final class DictDataL7P3 {
0x4000000000000L,
0x8004000L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL7W0 {
private DictDataL7W0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x6038b2291c1L,
0xe015f49042eL,
0x16048a573837L,
@@ -8196,4 +8197,5 @@ public final class DictDataL7W0 {
0xfff6048ac0e5f2L,
0xfffe01dc96a6b2L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL7W1 {
private DictDataL7W1() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x10006038b4abc73L,
0x1000e056740a513L,
0x10016038b45a5d3L,
@@ -2946,4 +2947,5 @@ public final class DictDataL7W1 {
0x15be604caa9d2adL,
0x15bee04ce1d1d3aL
};
}
}

View File

@@ -12,20 +12,20 @@ public final class DictDataL8 {
private static long[] words() {
long[] out = new long[WORDS_LEN];
int k = 0;
k = copy(out, k, DictDataL8W0.DATA);
k = copy(out, k, DictDataL8W1.DATA);
k = copy(out, k, DictDataL8W0.get());
k = copy(out, k, DictDataL8W1.get());
return out;
}
private static long[] posFlat() {
long[] out = new long[POS_LEN];
int k = 0;
k = copy(out, k, DictDataL8P0.DATA);
k = copy(out, k, DictDataL8P1.DATA);
k = copy(out, k, DictDataL8P2.DATA);
k = copy(out, k, DictDataL8P3.DATA);
k = copy(out, k, DictDataL8P4.DATA);
k = copy(out, k, DictDataL8P5.DATA);
k = copy(out, k, DictDataL8P0.get());
k = copy(out, k, DictDataL8P1.get());
k = copy(out, k, DictDataL8P2.get());
k = copy(out, k, DictDataL8P3.get());
k = copy(out, k, DictDataL8P4.get());
k = copy(out, k, DictDataL8P5.get());
return out;
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL8P0 {
private DictDataL8P0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x380200004284L,
0xc000000000000L,
0x2000001000030L,
@@ -8196,4 +8197,5 @@ public final class DictDataL8P0 {
0x0L,
0x1ffc000000000000L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL8P1 {
private DictDataL8P1() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x1800L,
0xffc000L,
0xc0000000000L,
@@ -8196,4 +8197,5 @@ public final class DictDataL8P1 {
0x0L,
0x301000004000L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL8P2 {
private DictDataL8P2() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x200000020000000L,
0x0L,
0x80000000000000L,
@@ -8196,4 +8197,5 @@ public final class DictDataL8P2 {
0xc0310000L,
0x2080L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL8P3 {
private DictDataL8P3() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x40120008L,
0x80000000000000L,
0x103000320000L,
@@ -8196,4 +8197,5 @@ public final class DictDataL8P3 {
0x4000200401L,
0x0L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL8P4 {
private DictDataL8P4() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x0L,
0x0L,
0x0L,
@@ -8196,4 +8197,5 @@ public final class DictDataL8P4 {
0x0L,
0x200004000000L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL8P5 {
private DictDataL8P5() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x401080000100L,
0x4000000000000000L,
0x10040L,
@@ -2100,4 +2101,5 @@ public final class DictDataL8P5 {
0x0L,
0x0L
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL8W0 {
private DictDataL8W0() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x7714b2290a9L,
0xf7148e2a656L,
0x176042d2b181L,
@@ -8196,4 +8197,5 @@ public final class DictDataL8W0 {
0xfff7224a89ac2cL,
0xffff9b9e98342cL
};
}
}

View File

@@ -2,7 +2,8 @@ package puzzle;
public final class DictDataL8W1 {
private DictDataL8W1() {}
public static final long[] DATA = new long[] {
public static long[] get() {
return new long[] {
0x100072a58f8342cL,
0x1000f2cdca4d02cL,
0x10017a3c522d8acL,
@@ -5050,4 +5051,5 @@ public final class DictDataL8W1 {
0x19da79d023cc1e3L,
0x19daf9ac6186133L
};
}
}

View File

@@ -194,7 +194,7 @@ public record Export() {
}
}
record Placed(long lemma, int shardIdx, int slotKey, int[] cells) {
record Placed(long lemma, int slotKey, int[] cells) {
static final char[] DIRECTION = { Placed.VERTICAL, Placed.HORIZONTAL, Placed.VERTICAL, Placed.HORIZONTAL };
public static final char HORIZONTAL = 'h';
@@ -211,8 +211,8 @@ public record Export() {
public record WordOut(String word, int[] cell, int startRow, int startCol, char direction, int arrowRow, int arrowCol, boolean isReversed, int complex, String[] clue) {
public WordOut(long l, int shardIdx, int startRow, int startCol, char d, int arrowRow, int arrowCol, boolean isReversed) {
val meta = Meta.readRecord(Meta.shardKey(l), shardIdx);
public WordOut(long l, int startRow, int startCol, char d, int arrowRow, int arrowCol, boolean isReversed) {
val meta = Meta.readRecord(Meta.shardKey(l), Lemma.unpackIndex(l));
this(Lemma.asWord(l), new int[]{ arrowRow, arrowCol, startRow, startCol }, startRow, startCol, d, arrowRow, arrowCol, isReversed,
meta.simpel(), meta.clues());
}
@@ -228,7 +228,7 @@ public record Export() {
for (var n = 1; n < slots.length; n++) {
if (slots[n].assign().w != X) {
k++;
simpel += Meta.readRecord(Meta.shardKey(slots[n].assign().w), slots[n].assign().shardIdx).simpel();//.simpel(Lemma.unpackIndex(slots[n].assign().w));
simpel += Meta.readRecord(Meta.shardKey(slots[n].assign().w), Lemma.unpackIndex(slots[n].assign().w)).simpel();//.simpel(Lemma.unpackIndex(slots[n].assign().w));
}
}
simpel = k == 0 ? 0 : simpel / k;
@@ -237,7 +237,7 @@ public record Export() {
public ExportedPuzzle exportFormatFromFilled(int difficulty, Rewards rewards) {
var placed = new ArrayList<Placed>();
for (var slot : slots) {
placed.add(new Placed(slot.assign().w, slot.assign().shardIdx, slot.key(), Gridded.walk((byte) slot.key(), slot.lo(), slot.hi()).toArray()));
placed.add(new Placed(slot.assign().w, slot.key(), Gridded.walk((byte) slot.key(), slot.lo(), slot.hi()).toArray()));
}
// If nothing placed: return full grid mapped to letters/# only
@@ -283,7 +283,6 @@ public record Export() {
int MIN_R = minR, MIN_C = minC;
var wordsOut = placed.stream().map(p -> new WordOut(
p.lemma,
p.shardIdx,
p.startRow() - MIN_R,
p.startCol() - MIN_C,
p.direction(),

View File

@@ -171,7 +171,6 @@ public class SwedishGenerator {
static class Assign {
long w;
int shardIdx;
}
public static record Slotinfo(int key, long lo, long hi, int score, Assign assign, DictEntry entry) {
@@ -397,7 +396,6 @@ public class SwedishGenerator {
Bit1029.set(used, lemIdx);
s.assign.w = w;
s.assign.shardIdx = shardIdx;
if (backtrack(depth + 1)) return true;
s.assign.w = X;
Bit1029.clear(used, lemIdx);
@@ -423,7 +421,6 @@ public class SwedishGenerator {
Bit1029.set(used, lemIdx);
s.assign.w = w;
s.assign.shardIdx = shardIdx;
if (backtrack(depth + 1)) return true;
s.assign.w = X;
Bit1029.clear(used, lemIdx);

View File

@@ -153,7 +153,7 @@ public final class DictJavaGeneratorMulti {
writeLengthAssembler(outDir, pkg, base, L, rows, cols, words.length, flat.length, wChunks, pChunks);
}
/** Writes classes like Prefix0..PrefixN each with static final long[] DATA. Returns chunk count. */
/** Writes classes like Prefix0..PrefixN each with static long[] DATA. Returns chunk count. */
private static int writeChunkClasses(Path outDir, String pkg, String prefix, long[] data, int chunkSize) throws IOException {
int chunks = (data.length + chunkSize - 1) / chunkSize;
for (int ci = 0; ci < chunks; ci++) {
@@ -165,11 +165,14 @@ public final class DictJavaGeneratorMulti {
w.write("package " + pkg + ";\n\n");
w.write("public final class " + prefix + ci + " {\n");
w.write(" private " + prefix + ci + "() {}\n");
w.write(" public static final long[] DATA = new long[] {\n");
w.write(" public static long[] get() {\n");
w.write(" return new long[] { \n");
for (int i = from; i < to; i++) {
w.write(" " + toLongLiteral(data[i]) + (i + 1 < to ? "," : "") + "\n");
}
w.write(" };\n");
w.write(" }\n");
w.write("}\n");
}
}
@@ -194,22 +197,32 @@ public final class DictJavaGeneratorMulti {
// assemble words
w.write(" private static long[] words() {\n");
w.write(" long[] out = new long[WORDS_LEN];\n");
w.write(" int k = 0;\n");
for (int ci = 0; ci < wChunks; ci++) {
w.write(" k = copy(out, k, DictDataL" + L + "W" + ci + ".DATA);\n");
String wPrefix = "DictDataL" + L + "W";
if (wChunks == 1) {
w.write(" return " + wPrefix + "0.get();\n");
} else {
w.write(" long[] out = new long[WORDS_LEN];\n");
w.write(" int k = 0;\n");
for (int ci = 0; ci < wChunks; ci++) {
w.write(" k = copy(out, k, " + wPrefix + ci + ".get());\n");
}
w.write(" return out;\n");
}
w.write(" return out;\n");
w.write(" }\n\n");
// assemble pos
w.write(" private static long[] posFlat() {\n");
w.write(" long[] out = new long[POS_LEN];\n");
w.write(" int k = 0;\n");
for (int ci = 0; ci < pChunks; ci++) {
w.write(" k = copy(out, k, DictDataL" + L + "P" + ci + ".DATA);\n");
String pPrefix = "DictDataL" + L + "P";
if (pChunks == 1) {
w.write(" return " + pPrefix + "0.get();\n");
} else {
w.write(" long[] out = new long[POS_LEN];\n");
w.write(" int k = 0;\n");
for (int ci = 0; ci < pChunks; ci++) {
w.write(" k = copy(out, k, " + pPrefix + ci + ".get());\n");
}
w.write(" return out;\n");
}
w.write(" return out;\n");
w.write(" }\n\n");
// entry

View File

@@ -71,7 +71,7 @@ public class ExportFormatTest {
var fillResult = new FillResult(true, 0, 0, 0, 0, new FillStats());
var puzzleResult = new PuzzleResult(new Clued(clues), grid, new Slotinfo[]{
new Slotinfo(key, lo, 0L, 0, new Assign(TEST, 0), null)
new Slotinfo(key, lo, 0L, 0, new Assign(TEST), null)
}, fillResult);
var rewards = new Rewards(10, 5, 1);
@@ -134,7 +134,7 @@ public class ExportFormatTest {
for (int i = 0; i < Math.min(words.length, 5); i++) {
val wordVal = words[i];
val word = Lemma.asWord(wordVal);
val assigned = new Assign(wordVal, i);
val assigned = new Assign(wordVal);
val shard = Meta.shardKey(assigned.w);
val clueRec = Meta.readRecord(shard, i);
@@ -149,15 +149,15 @@ public class ExportFormatTest {
@Test
void testSpecificWords() {
// These words are known to be in the CSV and likely in the dictionary
String[] testWords = {"EEN", "NAAR", "IEDEREEN"};
String[] testWords = { "EEN", "NAAR", "IEDEREEN" };
for (String wStr : testWords) {
long w = Lemma.pack(wStr);
int L = wStr.length();
var entry = DictData.DICT.index()[L];
long w = Lemma.pack(wStr);
int L = wStr.length();
var entry = DictData.DICT.index()[L];
if (entry == null) continue;
// Find index of word in entry
int idx = -1;
int idx = -1;
long[] words = entry.words();
for (int i = 0; i < words.length; i++) {
if (Lemma.asWord(words[i]).equals(wStr)) {
@@ -167,8 +167,8 @@ public class ExportFormatTest {
}
if (idx != -1) {
val shard = Meta.shardKey(w);
val clueRec = Meta.readRecord(shard, idx);
val shard = Meta.shardKey(w);
val clueRec = Meta.readRecord(shard, idx);
assertNotNull(clueRec);
assertEquals(wStr, Lemma.asWord(clueRec.w()));
// Check some expected complexity values (from CSV head output, column 3)