Gather data
This commit is contained in:
@@ -259,7 +259,7 @@ public class Main {
|
|||||||
completionService.submit(() -> {
|
completionService.submit(() -> {
|
||||||
var threadRng = new Rng(opts.seed + attempt);
|
var threadRng = new Rng(opts.seed + attempt);
|
||||||
var mask = generateMask(threadRng, dict.lenCounts(), opts.pop, opts.gens, false);
|
var mask = generateMask(threadRng, dict.lenCounts(), opts.pop, opts.gens, false);
|
||||||
var filled = fillMask(threadRng, mask, dict.index(), dict.words(), 200, fillTimeout, false);
|
var filled = fillMask(threadRng, mask, dict.index(), 200, fillTimeout, false);
|
||||||
|
|
||||||
if (filled.ok && (opts.minSimplicity <= 0 || filled.simplicity >= opts.minSimplicity)) {
|
if (filled.ok && (opts.minSimplicity <= 0 || filled.simplicity >= opts.minSimplicity)) {
|
||||||
return new PuzzleResult(dict, mask, filled);
|
return new PuzzleResult(dict, mask, filled);
|
||||||
@@ -284,7 +284,7 @@ public class Main {
|
|||||||
completionService.submit(() -> {
|
completionService.submit(() -> {
|
||||||
var threadRng = new Rng(opts.seed + attempt);
|
var threadRng = new Rng(opts.seed + attempt);
|
||||||
var mask = generateMask(threadRng, dict.lenCounts(), opts.pop, opts.gens, false);
|
var mask = generateMask(threadRng, dict.lenCounts(), opts.pop, opts.gens, false);
|
||||||
var filled = fillMask(threadRng, mask, dict.index(), dict.words(), 200, fillTimeout, false);
|
var filled = fillMask(threadRng, mask, dict.index(), 200, fillTimeout, false);
|
||||||
|
|
||||||
if (filled.ok && (opts.minSimplicity <= 0 || filled.simplicity >= opts.minSimplicity)) {
|
if (filled.ok && (opts.minSimplicity <= 0 || filled.simplicity >= opts.minSimplicity)) {
|
||||||
return new PuzzleResult(dict, mask, filled);
|
return new PuzzleResult(dict, mask, filled);
|
||||||
@@ -314,7 +314,7 @@ public class Main {
|
|||||||
info("try : " + attempt + " (remaining: " + (deadline - System.currentTimeMillis()) / 1000 + "s)");
|
info("try : " + attempt + " (remaining: " + (deadline - System.currentTimeMillis()) / 1000 + "s)");
|
||||||
|
|
||||||
var mask = generateMask(rng, dict.lenCounts(), opts.pop, opts.gens, true);
|
var mask = generateMask(rng, dict.lenCounts(), opts.pop, opts.gens, true);
|
||||||
var filled = fillMask(rng, mask, dict.index(), dict.words(), 200, fillTimeout, true);
|
var filled = fillMask(rng, mask, dict.index(), 200, fillTimeout, true);
|
||||||
|
|
||||||
if (filled.ok && (opts.minSimplicity <= 0 || filled.simplicity >= opts.minSimplicity)) {
|
if (filled.ok && (opts.minSimplicity <= 0 || filled.simplicity >= opts.minSimplicity)) {
|
||||||
info("status : SOLVED");
|
info("status : SOLVED");
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ public class SwedishGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static record Lemma(int index, String word,int length, int difficulty, int simpel, int score, int cross, ArrayList<String> clue) {
|
static record Lemma(int index, String word, int length, int difficulty, int simpel, int score, int cross, ArrayList<String> clue) {
|
||||||
|
|
||||||
static int LEMMA_COUNTER = 0;
|
static int LEMMA_COUNTER = 0;
|
||||||
public Lemma(String word, int simpel, int score, String clue) {
|
public Lemma(String word, int simpel, int score, String clue) {
|
||||||
@@ -146,7 +146,7 @@ public class SwedishGenerator {
|
|||||||
var crossScore = ThemePoolBuilderLength.crossabilityScore(word);
|
var crossScore = ThemePoolBuilderLength.crossabilityScore(word);
|
||||||
var list = new ArrayList<String>(10);
|
var list = new ArrayList<String>(10);
|
||||||
list.add(clue);
|
list.add(clue);
|
||||||
this(++LEMMA_COUNTER, word,word.length(), complex, simpel, score, (crossScore * 7) + ((score) * 30) + ((word.length()) * 15), list);
|
this(++LEMMA_COUNTER, word, word.length(), complex, simpel, score, (crossScore * 7) + ((score) * 30) + ((word.length()) * 15), list);
|
||||||
|
|
||||||
// Prioritize simple words (high lScore) and long words.
|
// Prioritize simple words (high lScore) and long words.
|
||||||
// lScore (1-10) adds up to 1000 points (weight 100).
|
// lScore (1-10) adds up to 1000 points (weight 100).
|
||||||
@@ -167,8 +167,8 @@ public class SwedishGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static record Dict(Map<String, Lemma> words,
|
public static record Dict(Map<String, Lemma> words,
|
||||||
HashMap<Integer, DictEntry> index,
|
DictEntry[] index,
|
||||||
HashMap<Integer, Integer> lenCounts) { }
|
int[] lenCounts) { }
|
||||||
static Dict loadWords(String wordsPath) {
|
static Dict loadWords(String wordsPath) {
|
||||||
String raw;
|
String raw;
|
||||||
try {
|
try {
|
||||||
@@ -213,19 +213,16 @@ public class SwedishGenerator {
|
|||||||
// Sort words by difficulty in ascending order
|
// Sort words by difficulty in ascending order
|
||||||
words.sort(Comparator.comparingInt(wd -> wd.simpel));
|
words.sort(Comparator.comparingInt(wd -> wd.simpel));
|
||||||
|
|
||||||
var index = new HashMap<Integer, DictEntry>();
|
var lenCounts = new int[12];
|
||||||
var lenCounts = new HashMap<Integer, Integer>();
|
var index = new DictEntry[12];
|
||||||
|
Arrays.setAll(index, i -> new DictEntry(i));
|
||||||
|
int maxLength = -1;
|
||||||
for (var w : words) {
|
for (var w : words) {
|
||||||
var L = w.length();
|
var L = w.length();
|
||||||
lenCounts.put(L, lenCounts.getOrDefault(L, 0) + 1);
|
if (L > maxLength) maxLength = L;
|
||||||
|
lenCounts[L]++;
|
||||||
var entry = index.get(L);
|
|
||||||
if (entry == null) {
|
|
||||||
entry = new DictEntry(L);
|
|
||||||
index.put(L, entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
var entry = index[L];
|
||||||
var idx = entry.words.size();
|
var idx = entry.words.size();
|
||||||
entry.words.add(w);
|
entry.words.add(w);
|
||||||
|
|
||||||
@@ -349,7 +346,7 @@ public class SwedishGenerator {
|
|||||||
|
|
||||||
// ---------------- FAST mask fitness ----------------
|
// ---------------- FAST mask fitness ----------------
|
||||||
|
|
||||||
static long maskFitness(char[][] grid, HashMap<Integer, Integer> lenCounts) {
|
static long maskFitness(char[][] grid, int[] lenCounts) {
|
||||||
long penalty = 0;
|
long penalty = 0;
|
||||||
|
|
||||||
var clueCount = 0;
|
var clueCount = 0;
|
||||||
@@ -371,7 +368,7 @@ public class SwedishGenerator {
|
|||||||
if (s.len > MAX_LEN) penalty += 8000 + (long) (s.len - MAX_LEN) * 500L;
|
if (s.len > MAX_LEN) penalty += 8000 + (long) (s.len - MAX_LEN) * 500L;
|
||||||
|
|
||||||
if (s.len >= MIN_LEN && s.len <= MAX_LEN) {
|
if (s.len >= MIN_LEN && s.len <= MAX_LEN) {
|
||||||
if (!lenCounts.containsKey(s.len)) penalty += 12000;
|
if (lenCounts[s.len]<=0) penalty += 12000;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < s.len; i++) {
|
for (var i = 0; i < s.len; i++) {
|
||||||
@@ -514,7 +511,7 @@ public class SwedishGenerator {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char[][] hillclimb(Rng rng, char[][] start, HashMap<Integer, Integer> lenCounts, int limit) {
|
static char[][] hillclimb(Rng rng, char[][] start, int[] lenCounts, int limit) {
|
||||||
var best = deepCopyGrid(start);
|
var best = deepCopyGrid(start);
|
||||||
var bestF = maskFitness(best, lenCounts);
|
var bestF = maskFitness(best, lenCounts);
|
||||||
var fails = 0;
|
var fails = 0;
|
||||||
@@ -539,7 +536,7 @@ public class SwedishGenerator {
|
|||||||
return same / (double) (W * H);
|
return same / (double) (W * H);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char[][] generateMask(Rng rng, HashMap<Integer, Integer> lenCounts, int popSize, int gens, boolean verbose) {
|
static char[][] generateMask(Rng rng, int[] lenCounts, int popSize, int gens, boolean verbose) {
|
||||||
if (verbose) System.out.println("generateMask init pop: " + popSize);
|
if (verbose) System.out.println("generateMask init pop: " + popSize);
|
||||||
var pop = new ArrayList<char[][]>();
|
var pop = new ArrayList<char[][]>();
|
||||||
|
|
||||||
@@ -653,8 +650,7 @@ public class SwedishGenerator {
|
|||||||
for (var i = 0; i < u.n; i++) grid[u.rs[i]][u.cs[i]] = u.prev[i];
|
for (var i = 0; i < u.n; i++) grid[u.rs[i]][u.cs[i]] = u.prev[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static FillResult fillMask(Rng rng, char[][] mask, HashMap<Integer, DictEntry> dictIndex,
|
static FillResult fillMask(Rng rng, char[][] mask, DictEntry[] dictIndex,
|
||||||
Map<String, Lemma> llmScores,
|
|
||||||
int logEveryMs, int timeLimitMs, boolean verbose) {
|
int logEveryMs, int timeLimitMs, boolean verbose) {
|
||||||
|
|
||||||
var grid = deepCopyGrid(mask);
|
var grid = deepCopyGrid(mask);
|
||||||
@@ -710,7 +706,7 @@ public class SwedishGenerator {
|
|||||||
var k = s.key();
|
var k = s.key();
|
||||||
if (assigned.containsKey(k)) continue;
|
if (assigned.containsKey(k)) continue;
|
||||||
|
|
||||||
var entry = dictIndex.get(s.len);
|
var entry = dictIndex[s.len];
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
return new Pick(null, null, false);
|
return new Pick(null, null, false);
|
||||||
}
|
}
|
||||||
@@ -760,7 +756,7 @@ public class SwedishGenerator {
|
|||||||
|
|
||||||
var s = pick.slot;
|
var s = pick.slot;
|
||||||
var k = s.key();
|
var k = s.key();
|
||||||
var entry = dictIndex.get(s.len);
|
var entry = dictIndex[s.len];
|
||||||
var pat = patternForSlot(grid, s);
|
var pat = patternForSlot(grid, s);
|
||||||
|
|
||||||
Predicate<Lemma> tryWord = (Lemma w) -> {
|
Predicate<Lemma> tryWord = (Lemma w) -> {
|
||||||
@@ -783,7 +779,7 @@ public class SwedishGenerator {
|
|||||||
if (backtrack()) return true;
|
if (backtrack()) return true;
|
||||||
|
|
||||||
assigned.remove(k);
|
assigned.remove(k);
|
||||||
used.set(w.index,false);
|
used.set(w.index, false);
|
||||||
undoPlace(grid, undo);
|
undoPlace(grid, undo);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user