diff --git a/src/main/java/puzzle/ExportFormat.java b/src/main/java/puzzle/ExportFormat.java index 12aa4ca..dfee640 100644 --- a/src/main/java/puzzle/ExportFormat.java +++ b/src/main/java/puzzle/ExportFormat.java @@ -31,15 +31,15 @@ public final class ExportFormat { var W = g[0].length; // 1) extract "placed" list from all clue digits in the filled grid - List placed = new ArrayList<>(); - var allSlots = extractSlots(g); - var clueMap = puz.filled().clueMap; + var placed = new ArrayList(); + var allSlots = extractSlots(g); + var clueMap = puz.filled().clueMap; for (var s : allSlots) { var word = clueMap.get(s.key()); if (word == null) continue; - var p = extractPlacedFromSlot(puz.dict(),s, word); + var p = extractPlacedFromSlot(puz.dict(), s, word); if (p == null) continue; placed.add(p); } @@ -99,9 +99,10 @@ public final class ExportFormat { } // 5) words output with cropped coordinates - List wordsOut = new ArrayList<>(placed.size()); + var wordsOut = new ArrayList(placed.size()); for (var p : placed) { wordsOut.add(new WordOut( + p.lemma, p.word, p.clue, // placeholder = word (same as JS) p.startRow - minR, @@ -111,7 +112,7 @@ public final class ExportFormat { p.arrowRow - minR, p.arrowCol - minC, p.isReversed, - puz.dict().words().get(p.word).simpel() + p.lemma.simpel() )); } @@ -121,7 +122,7 @@ public final class ExportFormat { /** * Convert a generator Slot + assigned word into a Placed object for export. */ - private static Placed extractPlacedFromSlot(Dict dict,Slot s, String word) { + private static Placed extractPlacedFromSlot(Dict dict, Slot s, Lemma lemma) { int r = s.clueR(); int c = s.clueC(); char d = s.dir(); @@ -167,12 +168,13 @@ public final class ExportFormat { } return new Placed( - word, - dict.words().get(word).clue().toArray( String[]::new), // clue placeholder + lemma, + lemma.word(), + dict.words().get(lemma.word()).clue().toArray(String[]::new), // clue placeholder startRow, startCol, direction, - word, // answer + lemma.word(), // answer arrowRow, arrowCol, cells, @@ -187,13 +189,14 @@ public final class ExportFormat { * @param direction "h" | "v" * @param cells word cells * @param arrow [arrowRow, arrowCol] */ - private record Placed(String word, String[] clue, int startRow, int startCol, String direction, String answer, int arrowRow, int arrowCol, List cells, int[] arrow, + private record Placed(Lemma lemma, String word, String[] clue, int startRow, int startCol, String direction, String answer, int arrowRow, int arrowCol, List cells, + int[] arrow, boolean isReversed) { } public record Rewards(int coins, int stars, int hints) { } /// @param direction "h" | "v" - public record WordOut(String word, String[] clue, int startRow, int startCol, String direction, String answer, int arrowRow, int arrowCol, boolean isReversed, int complex) { } + public record WordOut(Lemma lemma,String word, String[] clue, int startRow, int startCol, String direction, String answer, int arrowRow, int arrowCol, boolean isReversed, int complex) { } public record ExportedPuzzle(List gridv2, List words, int difficulty, Rewards rewards) { } } diff --git a/src/main/java/puzzle/SwedishGenerator.java b/src/main/java/puzzle/SwedishGenerator.java index 6157d55..153a883 100644 --- a/src/main/java/puzzle/SwedishGenerator.java +++ b/src/main/java/puzzle/SwedishGenerator.java @@ -124,10 +124,6 @@ public class SwedishGenerator { if (n >= a.length) a = Arrays.copyOf(a, a.length * 2); a[n++] = v; } - void replaceAll(int[] newData) { - this.a = newData; - this.n = newData.length; - } int size() { return n; } int[] data() { return a; } // note: may have extra capacity } @@ -142,14 +138,15 @@ public class SwedishGenerator { } } - static record Lemma(String word, int difficulty, int simpel, int score, int cross, ArrayList clue) { + static record Lemma(int index, String word,int length, int difficulty, int simpel, int score, int cross, ArrayList clue) { + static int LEMMA_COUNTER = 0; public Lemma(String word, int simpel, int score, String clue) { var complex = 0 + ((8 - word.length()) * 30) + ((10 - score) * 15); var crossScore = ThemePoolBuilderLength.crossabilityScore(word); var list = new ArrayList(10); list.add(clue); - this(word, 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. // lScore (1-10) adds up to 1000 points (weight 100). @@ -161,7 +158,12 @@ public class SwedishGenerator { // Length impact: up to 8 * 10 = 80 // Score impact: up to 10 * 15 = 150 } - char charAt(int idx) { return word.charAt(idx); } + char charAt(int idx) { return word.charAt(idx); } + @Override public int hashCode() { return index; } + @Override public boolean equals(Object o) { + if (o == this) return true; + return o instanceof Lemma l && l.index == index; + } } public static record Dict(Map words, @@ -215,7 +217,7 @@ public class SwedishGenerator { var lenCounts = new HashMap(); for (var w : words) { - var L = w.word.length(); + var L = w.length(); lenCounts.put(L, lenCounts.getOrDefault(L, 0) + 1); var entry = index.get(L); @@ -228,8 +230,9 @@ public class SwedishGenerator { entry.words.add(w); for (var i = 0; i < L; i++) { - var letter = w.word.charAt(i) - 'A'; + var letter = w.charAt(i) - 'A'; if (letter >= 0 && letter < 26) entry.pos[i][letter].add(idx); + else throw new RuntimeException("Illegal letter: " + letter + " in word " + w); } } @@ -288,6 +291,7 @@ public class SwedishGenerator { public Slot(int clueR, int clueC, char dir, int[] rs, int[] cs) { this(clueR, clueC, dir, rs, cs, rs.length); + } String key() { return clueR + "," + clueC + ":" + dir; } } @@ -597,7 +601,7 @@ public class SwedishGenerator { public boolean ok; public char[][] grid; - public HashMap clueMap; + public HashMap clueMap; public FillStats stats; public double simplicity; } @@ -658,8 +662,8 @@ public class SwedishGenerator { var slots = new ArrayList(); for (var s : allSlots) if (s.len >= MIN_LEN && s.len <= MAX_LEN) slots.add(s); - var used = new HashSet(); - var assigned = new HashMap(); + var used = new BitSet(); + var assigned = new HashMap(); var cellCount = new int[H][W]; for (var s : slots) for (var i = 0; i < s.len; i++) cellCount[s.rs[i]][s.cs[i]]++; @@ -733,7 +737,7 @@ public class SwedishGenerator { return new Pick(best, bestInfo, false); } }; - + IO.println("hit"); final var MAX_TRIES_PER_SLOT = 2000; class Solver { @@ -760,8 +764,11 @@ public class SwedishGenerator { var pat = patternForSlot(grid, s); Predicate tryWord = (Lemma w) -> { - if (w == null) return false; - if (used.contains(w.word())) return false; + if (w == null) { + IO.println("tryword null Error"); + return false; + } + if (used.get(w.index())) return false; for (var i = 0; i < pat.length; i++) { if (pat[i] != 0 && pat[i] != w.charAt(i)) return false; @@ -770,13 +777,13 @@ public class SwedishGenerator { var undo = placeWord(grid, s, w); if (undo == null) return false; - used.add(w.word()); - assigned.put(k, w.word()); + used.set(w.index()); + assigned.put(k, w); if (backtrack()) return true; assigned.remove(k); - used.remove(w); + used.set(w.index,false); undoPlace(grid, undo); return false; }; @@ -836,7 +843,7 @@ public class SwedishGenerator { if (ok) { double totalSimplicity = 0; for (var w : assigned.values()) { - totalSimplicity += llmScores.get(w).difficulty; + totalSimplicity += w.difficulty; } res.simplicity = assigned.isEmpty() ? 0 : totalSimplicity / assigned.size(); }