all
This commit is contained in:
@@ -179,8 +179,8 @@ public record Export() {
|
|||||||
var placed = new ArrayList<Placed>();
|
var placed = new ArrayList<Placed>();
|
||||||
var clueMap = filled().clueMap();
|
var clueMap = filled().clueMap();
|
||||||
g.grid().forEachSlot((int key, long lo, long hi) -> {
|
g.grid().forEachSlot((int key, long lo, long hi) -> {
|
||||||
var word = clueMap.get(key);
|
var word = clueMap[key];
|
||||||
if (word != null) {
|
if (word != 0L) {
|
||||||
placed.add(extractPlacedFromSlot(Slot.from(key, lo, hi), word));
|
placed.add(extractPlacedFromSlot(Slot.from(key, lo, hi), word));
|
||||||
} else {
|
} else {
|
||||||
System.err.println("Could not find clue for slot: " + key);
|
System.err.println("Could not find clue for slot: " + key);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class Main {
|
|||||||
|
|
||||||
public int seed = (int) (System.nanoTime() ^ System.currentTimeMillis());
|
public int seed = (int) (System.nanoTime() ^ System.currentTimeMillis());
|
||||||
public int pop = 18;
|
public int pop = 18;
|
||||||
public int gens = 1000;
|
public int gens = 1200;
|
||||||
public String wordsPath = "nl_score_hints_v3.csv";
|
public String wordsPath = "nl_score_hints_v3.csv";
|
||||||
public double minSimplicity = 0; // 0 means no limit
|
public double minSimplicity = 0; // 0 means no limit
|
||||||
public int threads = Math.max(1, Runtime.getRuntime().availableProcessors());
|
public int threads = Math.max(1, Runtime.getRuntime().availableProcessors());
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
|
|
||||||
record CandidateInfo(int[] indices, int count) { }
|
record CandidateInfo(int[] indices, int count) { }
|
||||||
|
|
||||||
// static final CandidateInfo[] CANDIDATES = IntStream.range(0, 10192 << 2).mapToObj(CandidateInfo::new).toArray(CandidateInfo[]::new);
|
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
@FunctionalInterface interface SlotVisitor { void visit(int key, long lo, long hi); }
|
@FunctionalInterface interface SlotVisitor { void visit(int key, long lo, long hi); }
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
@@ -100,21 +98,34 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
|
|
||||||
public static record FillResult(boolean ok,
|
public static record FillResult(boolean ok,
|
||||||
Gridded grid,
|
Gridded grid,
|
||||||
Map<Integer, Long> clueMap,
|
long[] clueMap,
|
||||||
FillStats stats) {
|
FillStats stats) {
|
||||||
|
|
||||||
public void calcSimpel() {
|
public void calcSimpel() {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
clueMap.forEach((k, v) -> stats.simplicity += Lemma.simpel(v));
|
int k = 0;
|
||||||
stats.simplicity = clueMap.isEmpty() ? 0 : stats.simplicity / clueMap.size();
|
for (var n = 1; n < clueMap.length; n++) {
|
||||||
|
if (clueMap[n] != 0L) {
|
||||||
|
k++;
|
||||||
|
stats.simplicity += Lemma.simpel(clueMap[n]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stats.simplicity = k == 0 ? 0 : stats.simplicity / k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int wordCount() {
|
||||||
|
int k = 0;
|
||||||
|
for (var n = 1; n < clueMap.length; n++) {
|
||||||
|
if (clueMap[n] != 0L) {
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class Context {
|
static final class Context {
|
||||||
|
|
||||||
final int[] cellCount = new int[SIZE];
|
|
||||||
final int[] stack = new int[SIZE];
|
final int[] stack = new int[SIZE];
|
||||||
long pattern;
|
long pattern;
|
||||||
final long[] undo = new long[128];
|
final long[] undo = new long[128];
|
||||||
@@ -245,7 +256,6 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
static String[] clue(long w) { return CsvIndexService.clues(unpackIndex(w)); }
|
static String[] clue(long w) { return CsvIndexService.clues(unpackIndex(w)); }
|
||||||
static int simpel(long w) { return CsvIndexService.simpel(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; }
|
static int length(long word) { return ((63 - Long.numberOfLeadingZeros(word & LETTER_MASK)) / 5) + 1; }
|
||||||
static int usedCharsInPattern(long p) { return ((63 - Long.numberOfLeadingZeros(p & LETTER_MASK)) / 5) + 1; }
|
|
||||||
public static String asWord(long word) {
|
public static String asWord(long word) {
|
||||||
var b = new byte[Lemma.length(word)];
|
var b = new byte[Lemma.length(word)];
|
||||||
for (var i = 0; i < b.length; i++) b[i] = (byte) ((word >>> (i * 5)) & 0b11111 | B64);
|
for (var i = 0; i < b.length; i++) b[i] = (byte) ((word >>> (i * 5)) & 0b11111 | B64);
|
||||||
@@ -325,8 +335,7 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void processSlot(Grid grid, SlotVisitor visitor, int idx) {
|
private static void processSlot(Grid grid, SlotVisitor visitor, int idx) {
|
||||||
int d = grid.digitAt(idx); // 0..3
|
int key = Slot.packSlotDir(idx, grid.digitAt(idx)); // 0..3
|
||||||
int key = Slot.packSlotDir(idx, d);
|
|
||||||
|
|
||||||
long rayLo = PATH_LO[key];
|
long rayLo = PATH_LO[key];
|
||||||
long rayHi = PATH_HI[key];
|
long rayHi = PATH_HI[key];
|
||||||
@@ -338,7 +347,7 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
// slice ray to stop before first clue, depending on direction monotonicity
|
// slice ray to stop before first clue, depending on direction monotonicity
|
||||||
// right/down => increasing indices; up/left => decreasing indices
|
// right/down => increasing indices; up/left => decreasing indices
|
||||||
|
|
||||||
if (Slot.increasing(d)) {
|
if (Slot.increasing(key)) {
|
||||||
// first clue is lowest index among hits (lo first, then hi)
|
// first clue is lowest index among hits (lo first, then hi)
|
||||||
if (hitsLo != 0) {
|
if (hitsLo != 0) {
|
||||||
long stop = 1L << Long.numberOfTrailingZeros(hitsLo);
|
long stop = 1L << Long.numberOfTrailingZeros(hitsLo);
|
||||||
@@ -375,7 +384,7 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long maskFitness(Grid grid) {
|
long maskFitness(Grid grid) {
|
||||||
var ctx = CTX.get();
|
|
||||||
long cHLo = 0L, cHHi = 0L, cVLo = 0L, cVHi = 0L;
|
long cHLo = 0L, cHHi = 0L, cVLo = 0L, cVHi = 0L;
|
||||||
long lo_cl = grid.lo, hi_cl = grid.hi;
|
long lo_cl = grid.lo, hi_cl = grid.hi;
|
||||||
long penalty = (((long) Math.abs(grid.clueCount() - TARGET_CLUES)) * 16000L);
|
long penalty = (((long) Math.abs(grid.clueCount() - TARGET_CLUES)) * 16000L);
|
||||||
@@ -384,11 +393,10 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
for (int i = 0; i < 65; i += 64) {
|
for (int i = 0; i < 65; i += 64) {
|
||||||
for (long bits = (i == 0 ? lo_cl : hi_cl); bits != X; bits &= bits - 1) {
|
for (long bits = (i == 0 ? lo_cl : hi_cl); bits != X; bits &= bits - 1) {
|
||||||
int clueIdx = i | Long.numberOfTrailingZeros(bits);
|
int clueIdx = i | Long.numberOfTrailingZeros(bits);
|
||||||
int d = grid.digitAt(clueIdx);
|
int key = Slot.packSlotDir(clueIdx, grid.digitAt(clueIdx));
|
||||||
int key = (clueIdx << 2) | d;
|
|
||||||
long rLo = PATH_LO[key], rHi = PATH_HI[key];
|
long rLo = PATH_LO[key], rHi = PATH_HI[key];
|
||||||
long hLo = rLo & lo_cl, hHi = rHi & hi_cl;
|
long hLo = rLo & lo_cl, hHi = rHi & hi_cl;
|
||||||
if (Slot.increasing(d)) {
|
if (Slot.increasing(key)) {
|
||||||
if (hLo != 0) {
|
if (hLo != 0) {
|
||||||
rLo &= ((1L << Long.numberOfTrailingZeros(hLo)) - 1);
|
rLo &= ((1L << Long.numberOfTrailingZeros(hLo)) - 1);
|
||||||
rHi = 0;
|
rHi = 0;
|
||||||
@@ -405,7 +413,7 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
}
|
}
|
||||||
if ((rLo | rHi) != 0) {
|
if ((rLo | rHi) != 0) {
|
||||||
hasSlots = true;
|
hasSlots = true;
|
||||||
if (Slot.horiz(d)) {
|
if (Slot.horiz(key)) {
|
||||||
cHLo |= rLo;
|
cHLo |= rLo;
|
||||||
cHHi |= rHi;
|
cHHi |= rHi;
|
||||||
} else {
|
} else {
|
||||||
@@ -420,7 +428,7 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!hasSlots) return 1_000_000_000L;
|
if (!hasSlots) return 1_000_000_000L;
|
||||||
|
var ctx = CTX.get();
|
||||||
var stack = ctx.stack;
|
var stack = ctx.stack;
|
||||||
long seenLo = 0L, seenHi = 0L;
|
long seenLo = 0L, seenHi = 0L;
|
||||||
|
|
||||||
@@ -512,7 +520,7 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
idx = rng.randint(0, SIZE_MIN_1);
|
idx = rng.randint(0, SIZE_MIN_1);
|
||||||
if (g.isClue(idx)) continue;
|
if (g.isClue(idx)) continue;
|
||||||
var d_idx = rng.randint2bitByte();
|
var d_idx = rng.randint2bitByte();
|
||||||
if (g.hasRoomForClue(OFFSETS_D_IDX[d_idx | idx << 2])) {
|
if (g.hasRoomForClue(OFFSETS_D_IDX[Slot.packSlotDir(idx, d_idx)])) {
|
||||||
g.setClue(idx, d_idx);
|
g.setClue(idx, d_idx);
|
||||||
placed++;
|
placed++;
|
||||||
}
|
}
|
||||||
@@ -527,7 +535,7 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
ri = bytes[rng.randint(0, 624)];
|
ri = bytes[rng.randint(0, 624)];
|
||||||
if (!g.clueless(ri)) {
|
if (!g.clueless(ri)) {
|
||||||
var d_idx = rng.randint2bitByte();
|
var d_idx = rng.randint2bitByte();
|
||||||
val packed = OFFSETS_D_IDX[d_idx | ri << 2];
|
val packed = OFFSETS_D_IDX[Slot.packSlotDir(ri, d_idx)];
|
||||||
if (g.hasRoomForClue(packed)) g.setClue(ri, d_idx);
|
if (g.hasRoomForClue(packed)) g.setClue(ri, d_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -562,7 +570,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[Slot.packSlotDir(idx, out.digitAt(idx))])) out.clearClue(idx); }
|
||||||
|
|
||||||
Grid hillclimb(Grid start, int limit) {
|
Grid hillclimb(Grid start, int limit) {
|
||||||
var best = start;
|
var best = start;
|
||||||
@@ -644,26 +652,38 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
if (s.increasing()) {
|
if (s.increasing()) {
|
||||||
for (long b = s.lo & ~grid.lo; b != 0; b &= b - 1) {
|
for (long b = s.lo & ~grid.lo; b != 0; b &= b - 1) {
|
||||||
int idx = Long.numberOfTrailingZeros(b);
|
int idx = Long.numberOfTrailingZeros(b);
|
||||||
|
int val = grid.g[idx] & 31;
|
||||||
|
if (val != 0) {
|
||||||
int i = Long.bitCount(s.lo & ((1L << idx) - 1));
|
int i = Long.bitCount(s.lo & ((1L << idx) - 1));
|
||||||
p |= ((long) (grid.g[idx] & 31)) << (i * 5);
|
p |= ((long) (i * 26 + val)) << (i << 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int offset = Long.bitCount(s.lo);
|
int offset = Long.bitCount(s.lo);
|
||||||
for (long b = s.hi & ~grid.hi; b != 0; b &= b - 1) {
|
for (long b = s.hi & ~grid.hi; b != 0; b &= b - 1) {
|
||||||
int idx = Long.numberOfTrailingZeros(b);
|
int idx = Long.numberOfTrailingZeros(b);
|
||||||
|
int val = grid.g[64 | idx] & 31;
|
||||||
|
if (val != 0) {
|
||||||
int i = offset + Long.bitCount(s.hi & ((1L << idx) - 1));
|
int i = offset + Long.bitCount(s.hi & ((1L << idx) - 1));
|
||||||
p |= ((long) (grid.g[64 | idx] & 31)) << (i * 5);
|
p |= ((long) (i * 26 + val)) << (i << 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int offset = Long.bitCount(s.hi);
|
int offset = Long.bitCount(s.hi);
|
||||||
for (long b = s.hi & ~grid.hi; b != 0; b &= b - 1) {
|
for (long b = s.hi & ~grid.hi; b != 0; b &= b - 1) {
|
||||||
int idx = Long.numberOfTrailingZeros(b);
|
int idx = Long.numberOfTrailingZeros(b);
|
||||||
|
int val = grid.g[64 | idx] & 31;
|
||||||
|
if (val != 0) {
|
||||||
int i = Long.bitCount(s.hi & ~((1L << idx) | ((1L << idx) - 1)));
|
int i = Long.bitCount(s.hi & ~((1L << idx) | ((1L << idx) - 1)));
|
||||||
p |= ((long) (grid.g[64 | idx] & 31)) << (i * 5);
|
p |= ((long) (i * 26 + val)) << (i << 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (long b = s.lo & ~grid.lo; b != 0; b &= b - 1) {
|
for (long b = s.lo & ~grid.lo; b != 0; b &= b - 1) {
|
||||||
int idx = Long.numberOfTrailingZeros(b);
|
int idx = Long.numberOfTrailingZeros(b);
|
||||||
|
int val = grid.g[idx] & 31;
|
||||||
|
if (val != 0) {
|
||||||
int i = offset + Long.bitCount(s.lo & ~((1L << idx) | ((1L << idx) - 1)));
|
int i = offset + Long.bitCount(s.lo & ~((1L << idx) | ((1L << idx) - 1)));
|
||||||
p |= ((long) (grid.g[idx] & 31)) << (i * 5);
|
p |= ((long) (i * 26 + val)) << (i << 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
@@ -743,16 +763,19 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
long[] res = ctx.bitset;
|
long[] res = ctx.bitset;
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
|
|
||||||
for (int i = 0, len = lenb/*Lemma.usedCharsInPattern(pattern)*/; i < len; i++) {
|
for (long p = pattern; p != 0; ) {
|
||||||
int val = (int) ((pattern >>> (i * 5)) & 31);
|
int combined = (int) (p & 0xFF);
|
||||||
if (val != 0) {
|
if (combined != 0) {
|
||||||
long[] bs = entry.posBitsets[i * 26 + (val - 1)];
|
long[] bs = entry.posBitsets[combined - 1];
|
||||||
if (first) {
|
if (first) {
|
||||||
System.arraycopy(bs, 0, res, 0, numLongs);
|
System.arraycopy(bs, 0, res, 0, numLongs);
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
for (int k = 0; k < numLongs; k++) res[k] &= bs[k];
|
for (int k = 0; k < numLongs; k++) res[k] &= bs[k];
|
||||||
}
|
}
|
||||||
|
p >>>= 8;
|
||||||
|
} else {
|
||||||
|
p >>>= (Long.numberOfTrailingZeros(p) & ~7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -783,16 +806,19 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
long[] res = ctx.bitset;
|
long[] res = ctx.bitset;
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
|
|
||||||
for (int i = 0, len = lenb /*Lemma.usedCharsInPattern(pattern)*/; i < len; i++) {
|
for (long p = pattern; p != 0; ) {
|
||||||
int val = (int) ((pattern >>> (i * 5)) & 31);
|
int combined = (int) (p & 0xFF);
|
||||||
if (val != 0) {
|
if (combined != 0) {
|
||||||
long[] bs = entry.posBitsets[i * 26 + (val - 1)];
|
long[] bs = entry.posBitsets[combined - 1];
|
||||||
if (first) {
|
if (first) {
|
||||||
System.arraycopy(bs, 0, res, 0, numLongs);
|
System.arraycopy(bs, 0, res, 0, numLongs);
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
for (int k = 0; k < numLongs; k++) res[k] &= bs[k];
|
for (int k = 0; k < numLongs; k++) res[k] &= bs[k];
|
||||||
}
|
}
|
||||||
|
p >>>= 8;
|
||||||
|
} else {
|
||||||
|
p >>>= (Long.numberOfTrailingZeros(p) & ~7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,7 +829,7 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
//72 << 3;
|
//72 << 3;
|
||||||
static final int BIGG = 581 + 1;
|
static final int BIGG = (288 | 3) + 1;
|
||||||
public FillResult fillMask(Grid mask, DictEntry[] dictIndex,
|
public FillResult fillMask(Grid mask, DictEntry[] dictIndex,
|
||||||
int timeLimitMs) {
|
int timeLimitMs) {
|
||||||
val multiThreaded = Thread.currentThread().getName().contains("pool");
|
val multiThreaded = Thread.currentThread().getName().contains("pool");
|
||||||
@@ -812,8 +838,7 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
|
|
||||||
long[] assigned = new long[BIGG];
|
long[] assigned = new long[BIGG];
|
||||||
val ctx = CTX.get();
|
val ctx = CTX.get();
|
||||||
val count = ctx.cellCount;
|
val count = new int[SIZE];
|
||||||
Arrays.fill(count, 0, SIZE, 0);
|
|
||||||
|
|
||||||
val slots = extractSlots(grid);
|
val slots = extractSlots(grid);
|
||||||
for (var s : slots) {
|
for (var s : slots) {
|
||||||
@@ -912,7 +937,7 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
|
|
||||||
for (var t = 0; t < tries; t++) {
|
for (var t = 0; t < tries; t++) {
|
||||||
double r = rng.nextFloat();
|
double r = rng.nextFloat();
|
||||||
int idxInArray = (int) (r * r * r * L);
|
int idxInArray = (int) (r * r * r * (L - 1));
|
||||||
var idx = idxs[idxInArray];
|
var idx = idxs[idxInArray];
|
||||||
var w = entry.words[idx];
|
var w = entry.words[idx];
|
||||||
var lemIdx = Lemma.unpackIndex(w);
|
var lemIdx = Lemma.unpackIndex(w);
|
||||||
@@ -942,7 +967,7 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
var tries = Math.min(MAX_TRIES_PER_SLOT, N);
|
var tries = Math.min(MAX_TRIES_PER_SLOT, N);
|
||||||
for (var t = 0; t < tries; t++) {
|
for (var t = 0; t < tries; t++) {
|
||||||
double r = rng.nextFloat();
|
double r = rng.nextFloat();
|
||||||
int idxInArray = (int) (r * r * r * N);
|
int idxInArray = (int) (r * r * r * (N - 1));
|
||||||
var w = entry.words[idxInArray];
|
var w = entry.words[idxInArray];
|
||||||
var lemIdx = Lemma.unpackIndex(w);
|
var lemIdx = Lemma.unpackIndex(w);
|
||||||
if (used.get(lemIdx)) continue;
|
if (used.get(lemIdx)) continue;
|
||||||
@@ -975,20 +1000,14 @@ public record SwedishGenerator(Rng rng) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stats.seconds = (System.currentTimeMillis() - t0) / 1000.0;
|
stats.seconds = (System.currentTimeMillis() - t0) / 1000.0;
|
||||||
Map<Integer, Long> lemmaMap = new HashMap<>();
|
var res = new FillResult(ok, new Gridded(grid), assigned, stats);
|
||||||
for (var i = 0; i < assigned.length; i++) {
|
|
||||||
if (assigned[i] != X) {
|
|
||||||
lemmaMap.put(i, assigned[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var res = new FillResult(ok, new Gridded(grid), lemmaMap, stats);
|
|
||||||
|
|
||||||
// print a final progress line
|
// print a final progress line
|
||||||
if (Main.VERBOSE && !multiThreaded) {
|
if (Main.VERBOSE && !multiThreaded) {
|
||||||
System.out.println(
|
System.out.println(
|
||||||
String.format(Locale.ROOT,
|
String.format(Locale.ROOT,
|
||||||
"[######################] %d/%d slots | nodes=%d | backtracks=%d | mrv=%d | %.1fs",
|
"[######################] %d/%d slots | nodes=%d | backtracks=%d | mrv=%d | %.1fs",
|
||||||
lemmaMap.size(), TOTAL, stats.nodes, stats.backtracks, stats.lastMRV, stats.seconds
|
res.wordCount(), TOTAL, stats.nodes, stats.backtracks, stats.lastMRV, stats.seconds
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ public class ExportFormatTest {
|
|||||||
grid.setClue(0, CLUE_RIGHT);
|
grid.setClue(0, CLUE_RIGHT);
|
||||||
// This creates a slot starting at (0,1)
|
// This creates a slot starting at (0,1)
|
||||||
|
|
||||||
var clueMap = new HashMap<Integer, Long>();
|
var clueMap = new long[300];
|
||||||
// key = (cellIndex << 2) | (direction)
|
// key = (cellIndex << 2) | (direction)
|
||||||
var key = (0 << 2) | (CLUE_RIGHT);
|
var key = (0 << 2) | (CLUE_RIGHT);
|
||||||
clueMap.put(key, Lemma.from("TEST"));
|
clueMap[key] = Lemma.from("TEST");
|
||||||
|
|
||||||
// Manually fill the grid letters for "TEST" at (0,1), (0,2), (0,3), (0,4)
|
// Manually fill the grid letters for "TEST" at (0,1), (0,2), (0,3), (0,4)
|
||||||
grid.setLetter(Grid.offset(0, 1), (byte) 'T');
|
grid.setLetter(Grid.offset(0, 1), (byte) 'T');
|
||||||
@@ -86,7 +86,7 @@ public class ExportFormatTest {
|
|||||||
void testExportFormatEmpty() {
|
void testExportFormatEmpty() {
|
||||||
var swe = new SwedishGenerator(new Rng(0));
|
var swe = new SwedishGenerator(new Rng(0));
|
||||||
var grid = Grid.createEmpty();
|
var grid = Grid.createEmpty();
|
||||||
var fillResult = new FillResult(true, new Gridded(grid), new HashMap<>(), new FillStats());
|
var fillResult = new FillResult(true, new Gridded(grid), new long[300], new FillStats());
|
||||||
var puzzleResult = new PuzzleResult(swe, null, null, fillResult);
|
var puzzleResult = new PuzzleResult(swe, null, null, fillResult);
|
||||||
|
|
||||||
var exported = puzzleResult.exportFormatFromFilled(1, new Rewards(0, 0, 0));
|
var exported = puzzleResult.exportFormatFromFilled(1, new Rewards(0, 0, 0));
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ public class MainTest {
|
|||||||
foundSeed = seed;
|
foundSeed = seed;
|
||||||
System.out.println("[DEBUG_LOG] Seed found: " + seed);
|
System.out.println("[DEBUG_LOG] Seed found: " + seed);
|
||||||
System.out.println("[DEBUG_LOG] Simplicity: " + res.filled().stats().simplicity);
|
System.out.println("[DEBUG_LOG] Simplicity: " + res.filled().stats().simplicity);
|
||||||
System.out.println("[DEBUG_LOG] ClueMap Size: " + res.filled().clueMap().size());
|
System.out.println("[DEBUG_LOG] ClueMap Size: " + res.filled().wordCount());
|
||||||
System.out.println("[DEBUG_LOG] Grid:");
|
System.out.println("[DEBUG_LOG] Grid:");
|
||||||
System.out.println(res.filled().grid().renderHuman());
|
System.out.println(res.filled().grid().renderHuman());
|
||||||
var aa = res.exportFormatFromFilled(1, new Rewards(1, 1, 1));
|
var aa = res.exportFormatFromFilled(1, new Rewards(1, 1, 1));
|
||||||
@@ -177,8 +177,8 @@ public class MainTest {
|
|||||||
|
|
||||||
// Regression baseline for seed search starting at 12347, pop 4, gens 20
|
// Regression baseline for seed search starting at 12347, pop 4, gens 20
|
||||||
Assertions.assertEquals(12348, foundSeed, "Found seed changed");
|
Assertions.assertEquals(12348, foundSeed, "Found seed changed");
|
||||||
Assertions.assertEquals(18, res.filled().clueMap().size(), "Number of assigned words changed");
|
Assertions.assertEquals(18, res.filled().wordCount(), "Number of assigned words changed");
|
||||||
Assertions.assertEquals("TROTS", Lemma.asWord(res.filled().clueMap().get(282)));
|
Assertions.assertEquals("SLEDE", Lemma.asWord(res.filled().clueMap()[282]));
|
||||||
Assertions.assertEquals(74732156493031040L, res.filled().grid().grid().lo);
|
Assertions.assertEquals(74732156493031040L, res.filled().grid().grid().lo);
|
||||||
Assertions.assertEquals(193L, res.filled().grid().grid().hi);
|
Assertions.assertEquals(193L, res.filled().grid().grid().hi);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class SwedishGeneratorTest {
|
|||||||
var slot = Slot.from(18 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
var slot = Slot.from(18 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
||||||
long pattern = patternForSlot(grid, slot);
|
long pattern = patternForSlot(grid, slot);
|
||||||
|
|
||||||
assertEquals(1 | (2 << 5) | (3 << 10), pattern);
|
assertEquals(1L | (28L << 8) | (55L << 16), pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -48,7 +48,7 @@ public class SwedishGeneratorTest {
|
|||||||
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
||||||
long pattern = patternForSlot(grid, slot);
|
long pattern = patternForSlot(grid, slot);
|
||||||
|
|
||||||
assertEquals(1 | (0 << 5) | (3 << 10), pattern);
|
assertEquals(1L | (0L << 8) | (55L << 16), pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -57,7 +57,7 @@ public class SwedishGeneratorTest {
|
|||||||
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
||||||
long pattern = patternForSlot(grid, slot);
|
long pattern = patternForSlot(grid, slot);
|
||||||
|
|
||||||
assertEquals(0, pattern);
|
assertEquals(0L, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -66,7 +66,7 @@ public class SwedishGeneratorTest {
|
|||||||
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L);
|
||||||
long pattern = patternForSlot(grid, slot);
|
long pattern = patternForSlot(grid, slot);
|
||||||
|
|
||||||
assertEquals(1, pattern);
|
assertEquals(1L, pattern);
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
void testRng() {
|
void testRng() {
|
||||||
@@ -232,6 +232,18 @@ public class SwedishGeneratorTest {
|
|||||||
assertEquals(0, count);
|
assertEquals(0, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long packPattern(String s) {
|
||||||
|
long p = 0;
|
||||||
|
byte[] b = s.getBytes(StandardCharsets.US_ASCII);
|
||||||
|
for (int i = 0; i < b.length; i++) {
|
||||||
|
int val = b[i] & 31;
|
||||||
|
if (val != 0) {
|
||||||
|
p |= (long) (i * 26 + val) << (i << 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCandidateInfoForPattern() {
|
void testCandidateInfoForPattern() {
|
||||||
var l0 = Lemma.from("IN");
|
var l0 = Lemma.from("IN");
|
||||||
@@ -247,7 +259,7 @@ public class SwedishGeneratorTest {
|
|||||||
|
|
||||||
// Pattern "APP--" for length 5
|
// Pattern "APP--" for length 5
|
||||||
var context = new Context();
|
var context = new Context();
|
||||||
context.setPattern(Lemma.pack(new byte[]{ 'A', 'P', 'P', DASH, DASH }));
|
context.setPattern(packPattern("APP"));
|
||||||
var info = candidateInfoForPattern(context, dict.index()[5], 5);
|
var info = candidateInfoForPattern(context, dict.index()[5], 5);
|
||||||
|
|
||||||
assertEquals(2, info.count());
|
assertEquals(2, info.count());
|
||||||
@@ -410,13 +422,13 @@ public class SwedishGeneratorTest {
|
|||||||
var entry5 = dict.index()[5];
|
var entry5 = dict.index()[5];
|
||||||
|
|
||||||
var ctx = new Context();
|
var ctx = new Context();
|
||||||
ctx.setPattern(Lemma.pack("APP".getBytes(StandardCharsets.US_ASCII)));
|
ctx.setPattern(packPattern("APP"));
|
||||||
assertEquals(2, candidateCountForPattern(ctx, entry5, 3));
|
assertEquals(2, candidateCountForPattern(ctx, entry5, 3));
|
||||||
|
|
||||||
ctx.setPattern(Lemma.pack("BAN".getBytes(StandardCharsets.US_ASCII)));
|
ctx.setPattern(packPattern("BAN"));
|
||||||
assertEquals(1, candidateCountForPattern(ctx, entry5, 3));
|
assertEquals(1, candidateCountForPattern(ctx, entry5, 3));
|
||||||
|
|
||||||
ctx.setPattern(Lemma.pack("CAT".getBytes(StandardCharsets.US_ASCII)));
|
ctx.setPattern(packPattern("CAT"));
|
||||||
assertEquals(0, candidateCountForPattern(ctx, entry5, 3));
|
assertEquals(0, candidateCountForPattern(ctx, entry5, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user