update them
This commit is contained in:
@@ -14,6 +14,7 @@ import java.util.stream.IntStream;
|
||||
* javac SwedishGenerator.java
|
||||
* java SwedishGenerator [--seed N] [--pop N] [--gens N] [--tries N] [--words word-list.txt]
|
||||
*/
|
||||
@SuppressWarnings("ALL")
|
||||
public class SwedishGenerator {
|
||||
|
||||
static final int W = 9, H = 8;
|
||||
@@ -136,7 +137,7 @@ public class SwedishGenerator {
|
||||
final int score;
|
||||
|
||||
public WordDifficulty(String word, int score) {
|
||||
this.word = word;
|
||||
this.word = word;
|
||||
this.score = score;
|
||||
// We want LONGER and SIMPLER words to be tried earlier (lower difficulty value).
|
||||
// word.length() is 2 to 8.
|
||||
@@ -144,7 +145,8 @@ public class SwedishGenerator {
|
||||
// Base difficulty starts high and decreases with length and score.
|
||||
// Length impact: up to 8 * 10 = 80
|
||||
// Score impact: up to 10 * 15 = 150
|
||||
this.difficulty = 250 - (word.length() * 10) - (score * 15);
|
||||
var difficulty1 = 0 + ((8 - word.length()) * 30) + ((10-score) * 15);
|
||||
this.difficulty = difficulty1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,17 +156,26 @@ public class SwedishGenerator {
|
||||
var lines = Files.readAllLines(Path.of("word_scores.csv"), StandardCharsets.UTF_8);
|
||||
var first = true;
|
||||
for (var line : lines) {
|
||||
if (first) { first = false; continue; }
|
||||
var parts = line.split(",", 3);
|
||||
if (first) {
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
var parts = line.split("," );
|
||||
if (parts.length >= 3) {
|
||||
try {
|
||||
var word = parts[0].trim().toUpperCase(Locale.ROOT);
|
||||
var score = Integer.parseInt(parts[1].trim());
|
||||
var word = parts[0].trim().toUpperCase(Locale.ROOT);
|
||||
var score = Integer.parseInt(parts[1].trim());
|
||||
var status = parts[2].trim();
|
||||
if ("OK".equalsIgnoreCase(status)) {
|
||||
scores.put(word, score);
|
||||
} else {
|
||||
System.err.println("Skipping:" +Arrays.toString( parts));
|
||||
}
|
||||
} catch (NumberFormatException ignored) {}
|
||||
} catch (NumberFormatException ignored) {
|
||||
System.err.println("Illegal number format: " + line);
|
||||
}
|
||||
} else {
|
||||
System.err.println("Illegal word: " + line);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@@ -184,7 +195,7 @@ public class SwedishGenerator {
|
||||
this.lenCounts = lenCounts;
|
||||
}
|
||||
}
|
||||
static Dict loadWords(String wordsPath) {
|
||||
static Dict loadWords(String wordsPath, Map<String, Integer> llmScores) {
|
||||
String raw;
|
||||
try {
|
||||
raw = Files.readString(Path.of(wordsPath), StandardCharsets.UTF_8);
|
||||
@@ -192,8 +203,7 @@ public class SwedishGenerator {
|
||||
raw = "EU\nUUR\nAUTO\nBOOM\nHUIS\nKAT\nZEE\nRODE\nDRAAD\nKENNIS\nNETWERK\nPAKTE\n";
|
||||
}
|
||||
|
||||
var llmScores = loadScores();
|
||||
var words = new ArrayList<WordDifficulty>();
|
||||
var words = new ArrayList<WordDifficulty>();
|
||||
for (var line : raw.split("\\R")) {
|
||||
var s = line.trim().toUpperCase(Locale.ROOT);
|
||||
if (s.matches("^[A-Z]{2,8}$")) {
|
||||
@@ -289,11 +299,10 @@ public class SwedishGenerator {
|
||||
return ci;
|
||||
}
|
||||
static int indexToDifficulty(DictEntry entry, int index, Map<String, Integer> llmScores) {
|
||||
var word = entry.words.get(index);
|
||||
var word = entry.words.get(index);
|
||||
var score = llmScores.getOrDefault(word, 5);
|
||||
return new WordDifficulty(word, score).difficulty;
|
||||
}
|
||||
|
||||
|
||||
// ---------------- Slots ----------------
|
||||
|
||||
@@ -617,6 +626,7 @@ public class SwedishGenerator {
|
||||
public char[][] grid;
|
||||
public HashMap<String, String> clueMap;
|
||||
public FillStats stats;
|
||||
public double simplicity;
|
||||
}
|
||||
|
||||
record Undo(int[] rs, int[] cs, char[] prev, int n) {
|
||||
@@ -667,6 +677,7 @@ public class SwedishGenerator {
|
||||
}
|
||||
|
||||
static FillResult fillMask(Rng rng, char[][] mask, HashMap<Integer, DictEntry> dictIndex,
|
||||
Map<String, Integer> llmScores,
|
||||
int logEveryMs, int timeLimitMs) {
|
||||
|
||||
var grid = deepCopyGrid(mask);
|
||||
@@ -819,10 +830,10 @@ public class SwedishGenerator {
|
||||
// (lower difficulty) but still have some randomness.
|
||||
for (var t = 0; t < tries; t++) {
|
||||
// Bias strongly towards lower indices (simpler words) using r^3
|
||||
double r = rng.nextFloat();
|
||||
int idxInArray = (int) (r * r * r * L);
|
||||
var idx = idxs[idxInArray];
|
||||
var w = entry.words.get(idx);
|
||||
double r = rng.nextFloat();
|
||||
int idxInArray = (int) (r * r * r * L);
|
||||
var idx = idxs[idxInArray];
|
||||
var w = entry.words.get(idx);
|
||||
if (tryWord.apply(w)) return true;
|
||||
}
|
||||
stats.backtracks++;
|
||||
@@ -837,9 +848,9 @@ public class SwedishGenerator {
|
||||
|
||||
var tries = Math.min(MAX_TRIES_PER_SLOT, N);
|
||||
for (var t = 0; t < tries; t++) {
|
||||
double r = rng.nextFloat();
|
||||
int idxInArray = (int) (r * r * r * N);
|
||||
var w = entry.words.get(idxInArray);
|
||||
double r = rng.nextFloat();
|
||||
int idxInArray = (int) (r * r * r * N);
|
||||
var w = entry.words.get(idxInArray);
|
||||
if (tryWord.apply(w)) return true;
|
||||
}
|
||||
|
||||
@@ -862,6 +873,14 @@ public class SwedishGenerator {
|
||||
stats.seconds = (System.currentTimeMillis() - t0) / 1000.0;
|
||||
res.stats = stats;
|
||||
|
||||
if (ok) {
|
||||
double totalSimplicity = 0;
|
||||
for (var w : assigned.values()) {
|
||||
totalSimplicity += llmScores.getOrDefault(w, 5);
|
||||
}
|
||||
res.simplicity = assigned.isEmpty() ? 0 : totalSimplicity / assigned.size();
|
||||
}
|
||||
|
||||
// print a final progress line
|
||||
System.out.println(
|
||||
String.format(Locale.ROOT,
|
||||
@@ -882,11 +901,12 @@ public class SwedishGenerator {
|
||||
public record PuzzleResult(char[][] mask, FillResult filled) { }
|
||||
|
||||
public static PuzzleResult generatePuzzle(Main.Opts opts) {
|
||||
var rng = new Rng(opts.seed);
|
||||
var tLoad0 = System.nanoTime();
|
||||
var dict = loadWords(opts.wordsPath);
|
||||
var tLoad1 = System.nanoTime();
|
||||
System.out.printf(Locale.ROOT, "LOAD_WORDS: %.3fs%n", (tLoad1 - tLoad0) / 1e9);
|
||||
var rng = new Rng(opts.seed);
|
||||
var llmScores = loadScores();
|
||||
var tLoad0 = System.nanoTime();
|
||||
var dict = loadWords(opts.wordsPath, llmScores);
|
||||
var tLoad1 = System.nanoTime();
|
||||
System.out.printf(Locale.ROOT, "LOAD_WORDS: %.3fs%n %s words", (tLoad1 - tLoad0) / 1e9,dict.words.size());
|
||||
|
||||
for (var attempt = 1; attempt <= opts.tries; attempt++) {
|
||||
System.out.println("\nAttempt " + attempt + "/" + opts.tries);
|
||||
@@ -897,14 +917,19 @@ public class SwedishGenerator {
|
||||
System.out.printf(Locale.ROOT, "MASK: %.3fs%n", (tMask1 - tMask0) / 1e9);
|
||||
|
||||
var tFill0 = System.nanoTime();
|
||||
var filled = fillMask(rng, mask, dict.index, 200, 60000);
|
||||
var filled = fillMask(rng, mask, dict.index, llmScores, 200, 60000);
|
||||
var tFill1 = System.nanoTime();
|
||||
System.out.printf(Locale.ROOT, "FILL: %.3fms%n", (tFill1 - tFill0) / 1e6);
|
||||
System.out.printf(Locale.ROOT, "FILL: %.3fms | Simplicity: %.2f%n", (tFill1 - tFill0) / 1e6, filled.simplicity);
|
||||
|
||||
if (filled.ok) {
|
||||
if (filled.ok && (opts.minSimplicity <= 0 || filled.simplicity >= opts.minSimplicity)) {
|
||||
return new PuzzleResult(mask, filled);
|
||||
}
|
||||
if (filled.ok) {
|
||||
System.out.printf(Locale.ROOT, "Puzzle simplicity %.2f is below min %.2f, retrying...%n",
|
||||
filled.simplicity, opts.minSimplicity);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user