introduce bitloops
This commit is contained in:
13
src/main/java/puzzle/DictMark.java
Normal file
13
src/main/java/puzzle/DictMark.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package puzzle;
|
||||||
|
|
||||||
|
import gen.GenDict;
|
||||||
|
|
||||||
|
@GenDict(
|
||||||
|
packageName = "puzzle.dict950",
|
||||||
|
className = "DictData950",
|
||||||
|
scv = "/home/mike/dev/puzzle-generator/nl_score_hints_v4.csv",
|
||||||
|
simpleMax = 950,
|
||||||
|
minLen = 2,
|
||||||
|
maxLen = 8
|
||||||
|
)
|
||||||
|
public class DictMark { }
|
||||||
@@ -4,6 +4,8 @@ import gen.GenerateDict;
|
|||||||
|
|
||||||
@GenerateDict(
|
@GenerateDict(
|
||||||
packageName = "puzzle",
|
packageName = "puzzle",
|
||||||
|
packageNameDict = "puzzle",
|
||||||
|
classNameDict = "DictData",
|
||||||
className = "LemmaData",
|
className = "LemmaData",
|
||||||
scv = "nl_score_hints_v4.csv",
|
scv = "nl_score_hints_v4.csv",
|
||||||
words = {
|
words = {
|
||||||
@@ -11,6 +13,7 @@ import gen.GenerateDict;
|
|||||||
"APPLE", "AXE", "ABC", "ABD", "AZ", "AB",
|
"APPLE", "AXE", "ABC", "ABD", "AZ", "AB",
|
||||||
"AT", "CAT", "DOGS", "APPLY", "BANAN", "BANANA", "BANANAS", "BANANASS"
|
"AT", "CAT", "DOGS", "APPLY", "BANAN", "BANANA", "BANANAS", "BANANASS"
|
||||||
},
|
},
|
||||||
|
simpleMax=900,
|
||||||
minLen = 2,
|
minLen = 2,
|
||||||
maxLen = 8
|
maxLen = 8
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,16 +8,17 @@ import precomp.Const9x8.Cell;
|
|||||||
import puzzle.Export.Gridded.Replacar.Rell;
|
import puzzle.Export.Gridded.Replacar.Rell;
|
||||||
import puzzle.Export.LetterVisit.LetterAt;
|
import puzzle.Export.LetterVisit.LetterAt;
|
||||||
import puzzle.Masker.Clues;
|
import puzzle.Masker.Clues;
|
||||||
|
import puzzle.SwedishGenerator.Dict;
|
||||||
import puzzle.SwedishGenerator.FillResult;
|
import puzzle.SwedishGenerator.FillResult;
|
||||||
import puzzle.SwedishGenerator.Grid;
|
import puzzle.SwedishGenerator.Grid;
|
||||||
import puzzle.SwedishGenerator.Slotinfo;
|
import puzzle.SwedishGenerator.Slotinfo;
|
||||||
|
import static precomp.Const9x8.INIT_GRID_OUTPUT;
|
||||||
import static puzzle.Export.Clue.DOWN0;
|
import static puzzle.Export.Clue.DOWN0;
|
||||||
import static puzzle.Export.Clue.RIGHT1;
|
import static puzzle.Export.Clue.RIGHT1;
|
||||||
import static puzzle.Masker.Clues.createEmpty;
|
import static puzzle.Masker.Clues.createEmpty;
|
||||||
import static puzzle.SwedishGenerator.R;
|
|
||||||
import static puzzle.SwedishGenerator.Lemma;
|
|
||||||
import static puzzle.Masker.Slot;
|
import static puzzle.Masker.Slot;
|
||||||
import static puzzle.SwedishGenerator.C;
|
import static puzzle.SwedishGenerator.C;
|
||||||
|
import static puzzle.SwedishGenerator.Lemma;
|
||||||
import static puzzle.SwedishGenerator.X;
|
import static puzzle.SwedishGenerator.X;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,8 +65,6 @@ public record Export() {
|
|||||||
static String padRight(String s, int n) { return s.length() >= n ? s : s + " ".repeat(n - s.length()); }
|
static String padRight(String s, int n) { return s.length() >= n ? s : s + " ".repeat(n - s.length()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
static final String INIT = IntStream.range(0, Config.PUZZLE_ROWS).mapToObj(l_ -> " ").collect(Collectors.joining("\n"));
|
|
||||||
|
|
||||||
public record ClueAt(int index, int clue) { }
|
public record ClueAt(int index, int clue) { }
|
||||||
|
|
||||||
public record Clued(@Delegate Clues c) {
|
public record Clued(@Delegate Clues c) {
|
||||||
@@ -76,25 +75,8 @@ public record Export() {
|
|||||||
return new Clued(c);
|
return new Clued(c);
|
||||||
}
|
}
|
||||||
public Clued deepCopyGrid() { return new Clued(new Clues(c.lo, c.hi, c.vlo, c.vhi, c.rlo, c.rhi, c.xlo, c.xhi)); }
|
public Clued deepCopyGrid() { return new Clued(new Clues(c.lo, c.hi, c.vlo, c.vhi, c.rlo, c.rhi, c.xlo, c.xhi)); }
|
||||||
public static Clued parse(String s) {
|
|
||||||
var c = createEmpty();
|
|
||||||
var lines = s.split("\n");
|
|
||||||
for (int r = 0; r < Math.min(lines.length, R); r++) {
|
|
||||||
var line = lines[r];
|
|
||||||
for (int col = 0; col < Math.min(line.length(), C); col++) {
|
|
||||||
char ch = line.charAt(col);
|
|
||||||
if (ch >= '0' && ch <= '4') {
|
|
||||||
int idx = Masker.offset(r, col);
|
|
||||||
byte dir = (byte) (ch - '0');
|
|
||||||
if ((idx & 64) == 0) c.setClueLo(1L << idx, dir);
|
|
||||||
else c.setClueHi(1L << (idx & 63), dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Clued(c);
|
|
||||||
}
|
|
||||||
String gridToString() {
|
String gridToString() {
|
||||||
var sb = new StringBuilder(INIT);
|
var sb = new StringBuilder(INIT_GRID_OUTPUT);
|
||||||
forEachSlot((s, _, _) -> {
|
forEachSlot((s, _, _) -> {
|
||||||
val idx = Slot.clueIndex(s);
|
val idx = Slot.clueIndex(s);
|
||||||
val dir = Slot.dir(s);
|
val dir = Slot.dir(s);
|
||||||
@@ -121,11 +103,13 @@ public record Export() {
|
|||||||
return stream.build();
|
return stream.build();
|
||||||
}
|
}
|
||||||
public Slotinfo[] slots() {
|
public Slotinfo[] slots() {
|
||||||
return Masker.slots(c, DictData.DICT.index());
|
return slots(DictData.DICT);
|
||||||
|
}
|
||||||
|
public Slotinfo[] slots(Dict D) {
|
||||||
|
return Masker.slots(c, D.index());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
interface LetterVisit {
|
interface LetterVisit {
|
||||||
|
|
||||||
record LetterAt(int index, byte letter) {
|
record LetterAt(int index, byte letter) {
|
||||||
@@ -137,24 +121,22 @@ public record Export() {
|
|||||||
public int index(int cols) { return (row() * cols) + col(); }
|
public int index(int cols) { return (row() * cols) + col(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(int index, byte letter);
|
|
||||||
default void visit(int index, byte[] letters) { visit(index, letters[index]); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
record Gridded(@Delegate Grid grid, Clues cl)
|
record Gridded(@Delegate Grid grid, Clues cl)
|
||||||
implements Stream<LetterAt> {
|
implements Stream<LetterAt> {
|
||||||
|
|
||||||
public Gridded(Clues clues) { this(clues.toGrid(), clues); }
|
public Gridded(Clues clues) { this(clues.toGrid(), clues); }
|
||||||
public Gridded(Clued clues) { this(clues.toGrid(), clues.c); }
|
public Gridded(Clued clues) { this(clues.c); }
|
||||||
public @Delegate Stream<LetterAt> stream() {
|
public @Delegate Stream<LetterAt> stream() {
|
||||||
val stream = Stream.<LetterAt>builder();
|
val stream = Stream.<LetterAt>builder();
|
||||||
for (var l = grid.lo & ~cl.lo; l != X; l &= l - 1) stream.accept(LetterAt.from(Long.numberOfTrailingZeros(l), grid.g));
|
for (var l = grid.lo & ~cl.lo; l != X; l &= l - 1) stream.accept(LetterAt.from(Long.numberOfTrailingZeros(l), grid.g));
|
||||||
for (var h = grid.hi & ~cl.hi & 0xFF; h != X; h &= h - 1) stream.accept(LetterAt.from(64 | Long.numberOfTrailingZeros(h), grid.g));
|
for (var h = grid.hi & ~cl.hi & 0xFF; h != X; h &= h - 1) stream.accept(LetterAt.from(64 | Long.numberOfTrailingZeros(h), grid.g));
|
||||||
return stream.build();
|
return stream.build();
|
||||||
}
|
}
|
||||||
String gridToString(Clues clues) {
|
String gridToString() {
|
||||||
var sb = new StringBuilder(INIT);
|
var sb = new StringBuilder(INIT_GRID_OUTPUT);
|
||||||
clues.forEachSlot((s, _, _) -> {
|
cl.forEachSlot((s, _, _) -> {
|
||||||
val idx = Slot.clueIndex(s);
|
val idx = Slot.clueIndex(s);
|
||||||
val r = idx & 7;
|
val r = idx & 7;
|
||||||
val c = idx >>> 3;
|
val c = idx >>> 3;
|
||||||
@@ -164,14 +146,14 @@ public record Export() {
|
|||||||
stream().forEach((l) -> sb.setCharAt(l.index(C + 1), l.human()));
|
stream().forEach((l) -> sb.setCharAt(l.index(C + 1), l.human()));
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
public String[] exportGrid(Clues clues, Replacar clueChar, char emptyFallback) {
|
public String[] exportGrid(Replacar clueChar, char emptyFallback) {
|
||||||
var sb = new StringBuilder(INIT);
|
var sb = new StringBuilder(INIT_GRID_OUTPUT);
|
||||||
clues.forEachSlot((s, l, a) -> {
|
cl.forEachSlot((s, l, a) -> {
|
||||||
val idx = Slot.clueIndex(s);
|
val idx = Slot.clueIndex(s);
|
||||||
val r = idx & 7;
|
val r = idx & 7;
|
||||||
val c = idx >>> 3;
|
val c = idx >>> 3;
|
||||||
val dir = Slot.dir(s);
|
val dir = Slot.dir(s);
|
||||||
sb.setCharAt(r * (C + 1) + c, clueChar.replace(new Rell(grid, clues, idx, (byte) (dir | 48))));
|
sb.setCharAt(r * (C + 1) + c, clueChar.replace(new Rell(grid, cl, idx, (byte) (dir | 48))));
|
||||||
});
|
});
|
||||||
stream().forEach((l) -> sb.setCharAt(l.index(C + 1), l.human()));
|
stream().forEach((l) -> sb.setCharAt(l.index(C + 1), l.human()));
|
||||||
return sb.toString().replaceAll(" ", "" + emptyFallback).split("\n");
|
return sb.toString().replaceAll(" ", "" + emptyFallback).split("\n");
|
||||||
@@ -224,7 +206,7 @@ public record Export() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String renderHuman(Clues clues) { return String.join("\n", exportGrid(clues, _ -> ' ', '#')); }
|
public String renderHuman() { return String.join("\n", exportGrid(_ -> ' ', '#')); }
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
interface Replacar {
|
interface Replacar {
|
||||||
|
|
||||||
@@ -266,7 +248,7 @@ public record Export() {
|
|||||||
public ExportedPuzzle exportFormatFromFilled(Rewards rewards) {
|
public ExportedPuzzle exportFormatFromFilled(Rewards rewards) {
|
||||||
// If nothing placed: return full grid mapped to letters/# only
|
// If nothing placed: return full grid mapped to letters/# only
|
||||||
if (slots.length == 0) {
|
if (slots.length == 0) {
|
||||||
return new ExportedPuzzle(grid.exportGrid(clues.c, _ -> '#', '#'), new WordOut[0], 1, rewards);
|
return new ExportedPuzzle(grid.exportGrid(_ -> '#', '#'), new WordOut[0], 1, rewards);
|
||||||
}
|
}
|
||||||
|
|
||||||
var placed = Arrays.stream(slots).map(slot -> new Placed(slot.assign().w, slot.key(), Gridded.cellWalk((byte) slot.key(), slot.lo(), slot.hi()).toArray())).toArray(
|
var placed = Arrays.stream(slots).map(slot -> new Placed(slot.assign().w, slot.key(), Gridded.cellWalk((byte) slot.key(), slot.lo(), slot.hi()).toArray())).toArray(
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import lombok.NoArgsConstructor;
|
|||||||
import lombok.val;
|
import lombok.val;
|
||||||
import puzzle.Masker.Clues;
|
import puzzle.Masker.Clues;
|
||||||
import puzzle.SwedishGenerator.Rng;
|
import puzzle.SwedishGenerator.Rng;
|
||||||
import puzzle.dict800.DictData;
|
|
||||||
|
|
||||||
import static puzzle.Export.*;
|
import static puzzle.Export.*;
|
||||||
import static puzzle.SwedishGenerator.*;
|
import static puzzle.SwedishGenerator.*;
|
||||||
@@ -80,10 +79,10 @@ public class Main {
|
|||||||
System.out.print(indentLines(res.clues().gridToString(), " "));
|
System.out.print(indentLines(res.clues().gridToString(), " "));
|
||||||
|
|
||||||
section("Grid (raw)");
|
section("Grid (raw)");
|
||||||
System.out.print(indentLines(res.grid().gridToString(res.clues().c()), " "));
|
System.out.print(indentLines(res.grid().gridToString(), " "));
|
||||||
|
|
||||||
section("Grid (human)");
|
section("Grid (human)");
|
||||||
System.out.print(indentLines(res.grid().renderHuman(res.clues().c()), " "));
|
System.out.print(indentLines(res.grid().renderHuman(), " "));
|
||||||
|
|
||||||
var exported = res.exportFormatFromFilled(new Rewards(50, 2, 1));
|
var exported = res.exportFormatFromFilled(new Rewards(50, 2, 1));
|
||||||
|
|
||||||
@@ -247,7 +246,7 @@ public class Main {
|
|||||||
PuzzleResult generatePuzzle(Opts opts) {
|
PuzzleResult generatePuzzle(Opts opts) {
|
||||||
|
|
||||||
var tLoad0 = System.nanoTime();
|
var tLoad0 = System.nanoTime();
|
||||||
var dict = DictData.DICT800;//loadDict(opts.wordsPath);
|
var dict = puzzle.dict800.DictData.DICT800;//loadDict(opts.wordsPath);
|
||||||
var tLoad1 = System.nanoTime();
|
var tLoad1 = System.nanoTime();
|
||||||
|
|
||||||
section("Load");
|
section("Load");
|
||||||
|
|||||||
@@ -643,12 +643,10 @@ public final class Masker {
|
|||||||
}
|
}
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
@FunctionalInterface public interface SlotVisitor { void visit(int key, long lo, long hi); }
|
@FunctionalInterface public interface SlotVisitor { void visit(int key, long lo, long hi); }
|
||||||
sealed interface BitPop permits Clues { long hi(); long lo(); }
|
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Accessors(fluent = true)
|
@Accessors(fluent = true)
|
||||||
public static final class Clues
|
public static final class Clues {
|
||||||
implements BitPop {
|
|
||||||
|
|
||||||
@Getter long lo, hi, vlo, vhi, rlo, rhi, xlo, xhi;
|
@Getter long lo, hi, vlo, vhi, rlo, rhi, xlo, xhi;
|
||||||
public static Clues createEmpty() { return new Clues(0, 0, 0, 0, 0, 0, 0, 0); }
|
public static Clues createEmpty() { return new Clues(0, 0, 0, 0, 0, 0, 0, 0); }
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package puzzle;
|
package puzzle;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import lombok.val;
|
|
||||||
import puzzle.SwedishGenerator.Lemma;
|
import puzzle.SwedishGenerator.Lemma;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@@ -30,14 +29,10 @@ public class Meta {
|
|||||||
static final Path dir = projectRoot.resolve("src/main/resources/shards");
|
static final Path dir = projectRoot.resolve("src/main/resources/shards");
|
||||||
static final Path shardData = dir.resolve("shard0.data");
|
static final Path shardData = dir.resolve("shard0.data");
|
||||||
static final Path shardMap = dir.resolve("shard0.map");
|
static final Path shardMap = dir.resolve("shard0.map");
|
||||||
static String normWord(String s) {
|
|
||||||
// belangrijk: zelfde normalisatie bij build en query
|
|
||||||
return s.toUpperCase(Locale.ROOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Lookup: w -> i using mmap ---
|
// --- Lookup: w -> i using mmap ---
|
||||||
static int findIndexInMapMmap(Path mapFile, long target) throws IOException {
|
static int findIndexInMapMmap(long target) throws IOException {
|
||||||
try (var ch = FileChannel.open(mapFile, StandardOpenOption.READ)) {
|
try (var ch = FileChannel.open(Meta.shardMap, StandardOpenOption.READ)) {
|
||||||
var mbb = (MappedByteBuffer) ch.map(FileChannel.MapMode.READ_ONLY, 0, ch.size()).order(ORDER);
|
var mbb = (MappedByteBuffer) ch.map(FileChannel.MapMode.READ_ONLY, 0, ch.size()).order(ORDER);
|
||||||
|
|
||||||
var magic = mbb.getInt(0);
|
var magic = mbb.getInt(0);
|
||||||
@@ -60,8 +55,8 @@ public class Meta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- Read record i from shard.data (your format) ---
|
// --- Read record i from shard.data (your format) ---
|
||||||
static ShardLem readRecord(Path shardFile, long w, int i) throws IOException {
|
static ShardLem readRecord(long w, int i) throws IOException {
|
||||||
try (var ch = FileChannel.open(shardFile, StandardOpenOption.READ)) {
|
try (var ch = FileChannel.open(Meta.shardData, StandardOpenOption.READ)) {
|
||||||
var hdr = ByteBuffer.allocate(12).order(ORDER);
|
var hdr = ByteBuffer.allocate(12).order(ORDER);
|
||||||
ch.read(hdr);
|
ch.read(hdr);
|
||||||
hdr.flip();
|
hdr.flip();
|
||||||
@@ -105,10 +100,10 @@ public class Meta {
|
|||||||
// --- Demo main ---
|
// --- Demo main ---
|
||||||
public static ShardLem lookup(long w) {
|
public static ShardLem lookup(long w) {
|
||||||
try {
|
try {
|
||||||
var i = findIndexInMapMmap(shardMap, Lemma.pack43(w));
|
var i = findIndexInMapMmap(Lemma.pack43(w));
|
||||||
System.out.println("\nQuery: w=" + w + " -> i=" + i);
|
System.out.println("\nQuery: w=" + w + " -> i=" + i);
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
var rec = readRecord(shardData, w, i);
|
var rec = readRecord(w, i);
|
||||||
System.out.println(" simpel=" + rec.simpel());
|
System.out.println(" simpel=" + rec.simpel());
|
||||||
System.out.println(" clues=" + Arrays.toString(rec.clues()));
|
System.out.println(" clues=" + Arrays.toString(rec.clues()));
|
||||||
return rec;
|
return rec;
|
||||||
@@ -117,7 +112,6 @@ public class Meta {
|
|||||||
throw new RuntimeException("NOT FOUND");
|
throw new RuntimeException("NOT FOUND");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,14 +30,14 @@ public record SwedishGenerator() {
|
|||||||
public static final long X = 0L;
|
public static final long X = 0L;
|
||||||
public static final int LOG_EVERY_MS = 200;
|
public static final int LOG_EVERY_MS = 200;
|
||||||
public static final int BAR_LEN = 22;
|
public static final int BAR_LEN = 22;
|
||||||
public static final int C = Config.PUZZLE_COLS;
|
public static final int C = Neighbors9x8.C;
|
||||||
public static final int R = Config.PUZZLE_ROWS;
|
public static final int R = Neighbors9x8.R;
|
||||||
public static final int SIZE = Neighbors9x8.SIZE;// ~18
|
public static final int SIZE = Neighbors9x8.SIZE;// ~18
|
||||||
public static final int SIZE_MIN_1 = SIZE - 1;// ~18
|
public static final int SIZE_MIN_1 = Neighbors9x8.SIZE_MIN_1;// ~18
|
||||||
public static final double SIZED = (double) SIZE;// ~18
|
public static final double SIZED = Neighbors9x8.SIZED;// ~18
|
||||||
public static final long MASK_LO = -1L;
|
public static final long MASK_LO = -1L;
|
||||||
public static final long MASK_HI = Neighbors9x8.MASK_HI;//(1L << (SIZE - 64)) - 1;
|
public static final long MASK_HI = Neighbors9x8.MASK_HI;//(1L << (SIZE - 64)) - 1;
|
||||||
public static final int MAX_WORD_LENGTH = Config.PUZZLE_ROWS;
|
public static final int MAX_WORD_LENGTH = Neighbors9x8.R;
|
||||||
public static final int MAX_WORD_LENGTH_PLUS_ONE = MAX_WORD_LENGTH + 1;
|
public static final int MAX_WORD_LENGTH_PLUS_ONE = MAX_WORD_LENGTH + 1;
|
||||||
public static final int MIN_LEN = Neighbors9x8.MIN_LEN;//Config.MIN_LEN;
|
public static final int MIN_LEN = Neighbors9x8.MIN_LEN;//Config.MIN_LEN;
|
||||||
public static final int MAX_TRIES_PER_SLOT = 500;//Config.MAX_TRIES_PER_SLOT;
|
public static final int MAX_TRIES_PER_SLOT = 500;//Config.MAX_TRIES_PER_SLOT;
|
||||||
@@ -57,12 +57,12 @@ public record SwedishGenerator() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
public static record Dict(DictEntry[] index, int length) { }
|
||||||
|
public static record DictEntry(long[] words, long[][] posBitsets, int length, int numlong) { }
|
||||||
@AllArgsConstructor @NoArgsConstructor static final class Assign { long w; }
|
@AllArgsConstructor @NoArgsConstructor static final class Assign { long w; }
|
||||||
public static final class FillStats { public double simplicity; }
|
public static final class FillStats { public double simplicity; }
|
||||||
@AllArgsConstructor public static final class Grid { public final byte[] g; public long lo, hi; }
|
@AllArgsConstructor public static final class Grid { public final byte[] g; public long lo, hi; }
|
||||||
public static record Dict(DictEntry[] index, int length) { }
|
|
||||||
public static record FillResult(boolean ok, long nodes, long backtracks, int lastMRV, long elapsed, FillStats stats) { }
|
public static record FillResult(boolean ok, long nodes, long backtracks, int lastMRV, long elapsed, FillStats stats) { }
|
||||||
public static record DictEntry(long[] words, long[][] posBitsets, int length, int numlong) { }
|
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
public static final long[] PATH_LO = Neighbors9x8.PATH_LO;
|
public static final long[] PATH_LO = Neighbors9x8.PATH_LO;
|
||||||
|
|||||||
@@ -23,14 +23,13 @@ public class BuildClueAndSimpelIndex {
|
|||||||
|
|
||||||
buildShard(records);
|
buildShard(records);
|
||||||
|
|
||||||
for (var qRaw : List.of("FIETS", "huis", "kiwi")) {
|
for (var qRaw : List.of("FIETS", "HUIS", "KIWI")) {
|
||||||
var q = Meta.normWord(qRaw);
|
var w = Lemma.from(qRaw);
|
||||||
var w = Lemma.from(q);
|
var i = Meta.findIndexInMapMmap(w);
|
||||||
var i = Meta.findIndexInMapMmap(Meta.shardMap, w);
|
|
||||||
|
|
||||||
System.out.println("\nQuery: " + qRaw + " (norm=" + q + ") w=" + w + " -> i=" + i);
|
System.out.println("\nQuery: " + qRaw + " (norm=" + qRaw + ") w=" + w + " -> i=" + i);
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
var rec = Meta.readRecord(Meta.shardData, w, i);
|
var rec = Meta.readRecord(w, i);
|
||||||
System.out.println(" simpel=" + rec.simpel());
|
System.out.println(" simpel=" + rec.simpel());
|
||||||
System.out.println(" clues=" + Arrays.toString(rec.clues()));
|
System.out.println(" clues=" + Arrays.toString(rec.clues()));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -110,11 +110,7 @@ public final class DictJavaGeneratorMulti {
|
|||||||
static final class ShardBuilder {
|
static final class ShardBuilder {
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
int addRecord() {
|
int addRecord() { return c++; }
|
||||||
val currSize = c;
|
|
||||||
c++;
|
|
||||||
return currSize;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeAggregator(Path outDir, String pkg, String cls, int totalLen, int thress) throws IOException {
|
private static void writeAggregator(Path outDir, String pkg, String cls, int totalLen, int thress) throws IOException {
|
||||||
@@ -262,9 +258,7 @@ public final class DictJavaGeneratorMulti {
|
|||||||
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE);
|
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String toLongLiteral(long v) {
|
private static String toLongLiteral(long v) { return "0x" + Long.toUnsignedString(v, 16) + "L"; }
|
||||||
return "0x" + Long.toUnsignedString(v, 16) + "L";
|
|
||||||
}
|
|
||||||
public static final class CsvIndexService {
|
public static final class CsvIndexService {
|
||||||
|
|
||||||
static int SIMPEL_IDX = 2;
|
static int SIMPEL_IDX = 2;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import puzzle.Export.PuzzleResult;
|
|||||||
import puzzle.Export.Rewards;
|
import puzzle.Export.Rewards;
|
||||||
import puzzle.Main.Opts;
|
import puzzle.Main.Opts;
|
||||||
import puzzle.SwedishGenerator.Rng;
|
import puzzle.SwedishGenerator.Rng;
|
||||||
|
import puzzle.dict950.DictData950;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
@@ -140,15 +141,17 @@ public class MainTest {
|
|||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
void testFiller2() {
|
void testFiller2() {
|
||||||
val mask = Clued.parse(
|
var mask = Clued.of(
|
||||||
"1 000000\n" +
|
r0c0d1,
|
||||||
"1 \n" +
|
r0c3d0, r0c4d0, r0c5d0, r0c6d0, r0c7d0, r0c8d0,
|
||||||
"1 \n" +
|
r1c0d1,
|
||||||
"3 3 \n" +
|
r2c0d1,
|
||||||
"3 0 3 \n" +
|
r3c0d3, r3c3d3,
|
||||||
"3 \n" +
|
r4c0d3, r4c3d0, r4c6d3,
|
||||||
"3 \n" +
|
r5c0d3,
|
||||||
"222 3");
|
r6c0d3,
|
||||||
|
r7c0d2, r7c1d2, r7c2d2, r7c8d3
|
||||||
|
);
|
||||||
Assertions.assertEquals(20, mask.clueCount());
|
Assertions.assertEquals(20, mask.clueCount());
|
||||||
val map = mask.stream().collect(Collectors.toMap(ClueAt::index, ClueAt::clue));
|
val map = mask.stream().collect(Collectors.toMap(ClueAt::index, ClueAt::clue));
|
||||||
Assertions.assertEquals(20, map.size());
|
Assertions.assertEquals(20, map.size());
|
||||||
@@ -158,17 +161,19 @@ public class MainTest {
|
|||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
void testFiller() {
|
void testFiller() {
|
||||||
|
System.out.println(DictData950.DICT950.index().length);
|
||||||
val rng = new Rng(-343913721);
|
val rng = new Rng(-343913721);
|
||||||
val mask = Clued.parse(
|
var mask = Clued.of(
|
||||||
" 3 300\n" +
|
r0c3d3, r0c6d3, r0c7d0, r0c8d0,
|
||||||
" 1 \n" +
|
r1c1d1,
|
||||||
" 1 \n" +
|
r2c1d1,
|
||||||
" 3 0 \n" +
|
r3c3d3, r3c6d0,
|
||||||
" 31 \n" +
|
r4c2d3, r4c3d1,
|
||||||
" 1 \n" +
|
r5c1d1,
|
||||||
" 1 2\n" +
|
r6c1d1, r6c8d2,
|
||||||
"21 22 3");
|
r7c0d2, r7c1d1, r7c4d2, r7c5d2, r7c8d3
|
||||||
var slotInfo = mask.slots();
|
);
|
||||||
|
var slotInfo = mask.slots(/*DictData950.DICT950*/);
|
||||||
var grid = Slotinfo.grid(slotInfo);
|
var grid = Slotinfo.grid(slotInfo);
|
||||||
var filled = fillMask(rng, slotInfo, grid);
|
var filled = fillMask(rng, slotInfo, grid);
|
||||||
Assertions.assertTrue(filled.ok(), "Puzzle generation failed (not ok)");
|
Assertions.assertTrue(filled.ok(), "Puzzle generation failed (not ok)");
|
||||||
@@ -177,7 +182,7 @@ public class MainTest {
|
|||||||
Assertions.assertEquals(-1L, grid.lo);
|
Assertions.assertEquals(-1L, grid.lo);
|
||||||
Assertions.assertEquals(-1L, grid.hi);
|
Assertions.assertEquals(-1L, grid.hi);
|
||||||
var g = new Gridded(grid, mask.c());
|
var g = new Gridded(grid, mask.c());
|
||||||
g.gridToString(mask.c());
|
g.gridToString();
|
||||||
var aa = new PuzzleResult(mask, g, slotInfo, filled).exportFormatFromFilled(new Rewards(1, 1, 1));
|
var aa = new PuzzleResult(mask, g, slotInfo, filled).exportFormatFromFilled(new Rewards(1, 1, 1));
|
||||||
System.out.println(String.join("\n", aa.grid()));
|
System.out.println(String.join("\n", aa.grid()));
|
||||||
|
|
||||||
@@ -194,8 +199,8 @@ public class MainTest {
|
|||||||
System.out.println("[DEBUG_LOG] Seed found: " + seed);
|
System.out.println("[DEBUG_LOG] Seed found: " + seed);
|
||||||
System.out.println("[DEBUG_LOG] ClueMap Size: " + Slotinfo.wordCount(0, res.slots()));
|
System.out.println("[DEBUG_LOG] ClueMap Size: " + Slotinfo.wordCount(0, res.slots()));
|
||||||
System.out.println("[DEBUG_LOG] Grid:");
|
System.out.println("[DEBUG_LOG] Grid:");
|
||||||
System.out.println(res.grid().renderHuman(res.clues().c()));
|
System.out.println(res.grid().renderHuman());
|
||||||
System.out.println(res.grid().gridToString(res.clues().c()));
|
System.out.println(res.grid().gridToString());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import puzzle.SwedishGenerator.Rng;
|
|||||||
import puzzle.SwedishGenerator.Slotinfo;
|
import puzzle.SwedishGenerator.Slotinfo;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static precomp.Const9x8.Cell.*;
|
||||||
import static puzzle.SwedishGenerator.fillMask;
|
import static puzzle.SwedishGenerator.fillMask;
|
||||||
import static puzzle.dict800.DictData.DICT800;
|
import static puzzle.dict800.DictData.DICT800;
|
||||||
import static puzzle.dict900.DictData.DICT900;
|
import static puzzle.dict900.DictData.DICT900;
|
||||||
@@ -74,15 +75,16 @@ public class PerformanceTest {
|
|||||||
void testIncrementalComplexity() {
|
void testIncrementalComplexity() {
|
||||||
|
|
||||||
// Use the complex mask from Main.java
|
// Use the complex mask from Main.java
|
||||||
var maskStr = "1 0000\n" +
|
var mask = Clued.of(
|
||||||
"1 \n" +
|
r0c0d1, r0c5d0, r0c6d0, r0c7d0, r0c8d0,
|
||||||
"00 01 \n" +
|
r1c0d1,
|
||||||
" 1 \n" +
|
r2c0d0, r2c1d0, r2c3d0, r2c4d1,
|
||||||
" 1 \n" +
|
r3c4d1,
|
||||||
" 2 1 \n" +
|
r4c4d1,
|
||||||
" 1 \n" +
|
r5c2d2, r5c4d1,
|
||||||
"221 22\n";
|
r6c2d1,
|
||||||
val mask = Clued.parse(maskStr);
|
r7c0d2, r7c1d2, r7c2d1, r7c7d2, r7c8d2
|
||||||
|
);
|
||||||
val allSlots = Masker.slots(mask.c(), DICT900.index());
|
val allSlots = Masker.slots(mask.c(), DICT900.index());
|
||||||
//mask.toGrid()
|
//mask.toGrid()
|
||||||
System.out.println("[DEBUG_LOG] \n--- Incremental Complexity Test ---");
|
System.out.println("[DEBUG_LOG] \n--- Incremental Complexity Test ---");
|
||||||
@@ -103,7 +105,7 @@ public class PerformanceTest {
|
|||||||
val rng = new Rng(42);
|
val rng = new Rng(42);
|
||||||
|
|
||||||
// A single horizontal slot at (0,0)
|
// A single horizontal slot at (0,0)
|
||||||
val mask = Clued.parse("1 \n");
|
val mask = Clued.of(r0c0d1);
|
||||||
val slots = Masker.slots(mask.c(), EN);
|
val slots = Masker.slots(mask.c(), EN);
|
||||||
|
|
||||||
System.out.println("[DEBUG_LOG] \n--- Single Slot Resolution ---");
|
System.out.println("[DEBUG_LOG] \n--- Single Slot Resolution ---");
|
||||||
|
|||||||
Reference in New Issue
Block a user