introduce bitloops
This commit is contained in:
@@ -357,7 +357,7 @@ public class Main {
|
||||
static PuzzleResult _attempt(Rng rng, Dict dict, Opts opts) {
|
||||
TOTAL_ATTEMPTS.incrementAndGet();
|
||||
val stack = new int[STACK_SIZE];
|
||||
var swe = new SwedishGenerator(rng, stack);
|
||||
var swe = new SwedishGenerator(rng, stack, Clues.createEmpty());
|
||||
var mask = swe.generateMask(opts.pop, opts.gens, Math.max(opts.pop, (int) Math.floor(opts.pop * 1.5)));
|
||||
var filled = fillMask(rng, extractSlots(mask), mask.toGrid(), dict.index());
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ import static java.nio.charset.StandardCharsets.*;
|
||||
* java SwedishGenerator [--seed N] [--pop N] [--gens N] [--tries N] [--words word-list.txt]
|
||||
*/
|
||||
@SuppressWarnings("ALL")
|
||||
public record SwedishGenerator(Rng rng, int[] stack) {
|
||||
public record SwedishGenerator(Rng rng, int[] stack, Clues cache) {
|
||||
|
||||
record CandidateInfo(int[] indices, int count) { }
|
||||
|
||||
@@ -283,6 +283,15 @@ public record SwedishGenerator(Rng rng, int[] stack) {
|
||||
for (var l = lo; l != X; l &= l - 1) processSlot(this, visitor, Long.numberOfTrailingZeros(l));
|
||||
for (var h = hi; h != X; h &= h - 1) processSlot(this, visitor, 64 | Long.numberOfTrailingZeros(h));
|
||||
}
|
||||
public Clues from(Clues best) {
|
||||
lo = best.lo;
|
||||
hi = best.hi;
|
||||
vlo = best.vlo;
|
||||
vhi = best.vhi;
|
||||
rlo = best.rlo;
|
||||
rhi = best.rhi;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
static record Grid(byte[] g, long lo, long hi) {
|
||||
@@ -605,8 +614,7 @@ public record SwedishGenerator(Rng rng, int[] stack) {
|
||||
}
|
||||
return g;
|
||||
}
|
||||
Clues mutate(Clues clues) {
|
||||
var c = clues.deepCopyGrid();
|
||||
Clues mutate(Clues c) {
|
||||
int ri;
|
||||
var bytes = MUTATE_RI[rng.randint(0, SIZE_MIN_1)];
|
||||
for (var k = 0; k < 4; k++) {
|
||||
@@ -666,6 +674,7 @@ public record SwedishGenerator(Rng rng, int[] stack) {
|
||||
var fails = 0;
|
||||
|
||||
while (fails < limit) {
|
||||
cache.from(best);
|
||||
var cand = mutate(best);
|
||||
var f = maskFitness(cand);
|
||||
if (f < bestF) {
|
||||
@@ -673,6 +682,7 @@ public record SwedishGenerator(Rng rng, int[] stack) {
|
||||
bestF = f;
|
||||
fails = 0;
|
||||
} else {
|
||||
best.from(cache);
|
||||
fails++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import puzzle.SwedishGenerator.Rng;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static puzzle.SwedishGenerator.*;
|
||||
@@ -28,7 +27,7 @@ public class ExportFormatTest {
|
||||
|
||||
@Test
|
||||
void testExportFormatFromFilled() {
|
||||
var swe = new SwedishGenerator(new Rng(0), new int[STACK_SIZE]);
|
||||
var swe = new SwedishGenerator(new Rng(0), new int[STACK_SIZE], Clues.createEmpty());
|
||||
|
||||
val clues = Clues.createEmpty();
|
||||
// Place a RIGHT clue at (0,0)
|
||||
@@ -87,7 +86,7 @@ public class ExportFormatTest {
|
||||
|
||||
@Test
|
||||
void testExportFormatEmpty() {
|
||||
var swe = new SwedishGenerator(new Rng(0), new int[STACK_SIZE]);
|
||||
var swe = new SwedishGenerator(new Rng(0), new int[STACK_SIZE], Clues.createEmpty());
|
||||
var grid = Grid.createEmpty();
|
||||
val clues = Clues.createEmpty();
|
||||
var fillResult = new FillResult(true, new Gridded(grid), new long[300], new FillStats(0, 0, 0, 0));
|
||||
|
||||
@@ -255,8 +255,7 @@ public class SwedishGeneratorTest {
|
||||
// This should detect a slot starting at 0,1 with length 2 (0,1 and 0,2)
|
||||
var clues = Clues.createEmpty();
|
||||
clues.setClue(OFF_0_0, CLUE_RIGHT);
|
||||
var grid = clues.toGrid();
|
||||
|
||||
var grid = clues.toGrid();
|
||||
|
||||
var slots = extractSlots(clues);
|
||||
assertEquals(1, slots.length);
|
||||
@@ -269,7 +268,7 @@ public class SwedishGeneratorTest {
|
||||
|
||||
@Test
|
||||
void testMaskFitnessBasic() {
|
||||
var gen = new SwedishGenerator(new Rng(0), new int[STACK_SIZE]);
|
||||
var gen = new SwedishGenerator(new Rng(0), new int[STACK_SIZE], Clues.createEmpty());
|
||||
var grid = Clues.createEmpty();
|
||||
// Empty grid should have high penalty (no slots)
|
||||
var f1 = gen.maskFitness(grid);
|
||||
@@ -284,12 +283,12 @@ public class SwedishGeneratorTest {
|
||||
@Test
|
||||
void testGeneticAlgorithmComponents() {
|
||||
var rng = new Rng(42);
|
||||
var gen = new SwedishGenerator(rng, new int[STACK_SIZE]);
|
||||
var gen = new SwedishGenerator(rng, new int[STACK_SIZE], Clues.createEmpty());
|
||||
|
||||
var g1 = gen.randomMask();
|
||||
assertNotNull(g1);
|
||||
|
||||
var g2 = gen.mutate(g1);
|
||||
var g2 = gen.mutate(g1.deepCopyGrid());
|
||||
assertNotNull(g2);
|
||||
assertNotSame(g1, g2);
|
||||
|
||||
@@ -410,7 +409,7 @@ public class SwedishGeneratorTest {
|
||||
|
||||
@Test
|
||||
void testMaskFitnessDetailed() {
|
||||
var gen = new SwedishGenerator(new Rng(42), new int[STACK_SIZE]);
|
||||
var gen = new SwedishGenerator(new Rng(42), new int[STACK_SIZE], Clues.createEmpty());
|
||||
var grid = Clues.createEmpty();
|
||||
// Empty grid: huge penalty
|
||||
var fitEmpty = gen.maskFitness(grid);
|
||||
|
||||
Reference in New Issue
Block a user