introduce bitloops
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
package puzzle;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import lombok.Getter;
|
||||
import lombok.val;
|
||||
import precomp.Neighbors9x8;
|
||||
@@ -36,6 +35,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
//@formatter:off
|
||||
@FunctionalInterface interface SlotVisitor { void visit(int key, long packedPos, int len); }
|
||||
//@formatter:on
|
||||
static final long GT_1_OFFSET_53_BIT = 0x3E00000000000000L;
|
||||
static final long X = 0L;
|
||||
static final int LOG_EVERY_MS = 200;
|
||||
static final int BAR_LEN = 22;
|
||||
@@ -208,7 +208,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
if (idx < 64) lo &= ~(1L << idx);
|
||||
else hi &= ~(1L << (idx & 63));
|
||||
}
|
||||
static boolean isDigit(byte b) { return (b & 48) == 48; }
|
||||
static boolean isDigit(byte b) { return (b & B48) == B48; }
|
||||
boolean isDigitAt(int index) { return isDigit(g[index]); }
|
||||
boolean isClue(long index) {
|
||||
if (index < 64) return ((lo >> index) & 1L) != X;
|
||||
@@ -242,9 +242,12 @@ public record SwedishGenerator(Rng rng) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static boolean isLetter(byte b) { return (b & 64) != 0; }
|
||||
static final byte B0 = (byte) 0;
|
||||
static final byte B64 = (byte) 64;
|
||||
static final byte B48 = (byte) 48;
|
||||
static boolean isLetter(byte b) { return (b & B64) != B0; }
|
||||
public boolean isLetterSet(int idx) { return isLetter(g[idx]); }
|
||||
static boolean notDigit(byte b) { return (b & 48) != 48; }
|
||||
static boolean notDigit(byte b) { return (b & B48) != B48; }
|
||||
public boolean isLetterAt(int index) { return notDigit(g[index]); }
|
||||
|
||||
public double similarity(Grid b) {
|
||||
@@ -252,17 +255,11 @@ public record SwedishGenerator(Rng rng) {
|
||||
for (int i = 0; i < SIZE; i++) if (g[i] == b.g[i]) same++;
|
||||
return same / SIZED;
|
||||
}
|
||||
int clueCount() { return Long.bitCount(lo) + Long.bitCount(hi); }
|
||||
/* for (int k = 0, n = Math.min(MAX_WORD_LENGTH7, (int) (packed >>> 56) * 7); k < n; ) {
|
||||
if (isClue((int) ((packed >>> k) & 0x7F))) break;
|
||||
k += 7;
|
||||
if (k >= MIN_LEN7) return true;
|
||||
}
|
||||
return false;*/
|
||||
boolean hasRoomForClue(long packed) { return ((packed >>> 56)) > 1L && notClue(packed & 0x7FL) && notClue((packed >>> 7) & 0x7FL); }
|
||||
int clueCount() { return Long.bitCount(lo) + Long.bitCount(hi); }
|
||||
boolean hasRoomForClue(long packed) { return (packed & GT_1_OFFSET_53_BIT) != X && notClue(packed & 0x7FL) && notClue((packed >>> 7) & 0x7FL); }
|
||||
void forEachSlot(SlotVisitor visitor) {
|
||||
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));
|
||||
for (var h = hi; h != X; h &= h - 1) processSlot(this, visitor, 64 | Long.numberOfTrailingZeros(h));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,21 +283,21 @@ public record SwedishGenerator(Rng rng) {
|
||||
}
|
||||
}
|
||||
|
||||
public static record Lemma(int index, byte[] word, int simpel, String[] clue) {
|
||||
public static record Lemma(int index, byte[] word, int simpel) {
|
||||
|
||||
static int LEMMA_COUNTER = 0;
|
||||
public Lemma(int index, String word, int simpel, String[] clu) { this(index, word.getBytes(StandardCharsets.US_ASCII), simpel, clu); }
|
||||
public Lemma(String word, int simpel, String clue) { this(LEMMA_COUNTER++, word, simpel, new String[]{ clue }); }
|
||||
byte byteAt(int idx) { return word[idx]; }
|
||||
@Override public int hashCode() { return index; }
|
||||
@Override public boolean equals(Object o) { return (o == this) || (o instanceof Lemma l && l.index == index); }
|
||||
public Lemma(int index, String word, int simpel) { this(index, word.getBytes(StandardCharsets.US_ASCII), simpel); }
|
||||
public Lemma(String word, int simpel) { this(LEMMA_COUNTER++, word, simpel); }
|
||||
byte byteAt(int idx) { return word[idx]; }
|
||||
@Override public int hashCode() { return index; }
|
||||
@Override public boolean equals(Object o) { return (o == this) || (o instanceof Lemma l && l.index == index); }
|
||||
String[] clue() { return CsvIndexService.clues(index); }
|
||||
}
|
||||
|
||||
public static record Dict(
|
||||
DictEntry[] index,
|
||||
int length) {
|
||||
|
||||
static final Gson GSON = new Gson();
|
||||
public Dict(Lemma[] wordz) {
|
||||
var index = new DictEntry[MAX_WORD_LENGTH_PLUS_ONE];
|
||||
Arrays.setAll(index, i -> new DictEntry(i));
|
||||
@@ -317,59 +314,18 @@ public record SwedishGenerator(Rng rng) {
|
||||
entry.pos[i][letter].add(idx);
|
||||
}
|
||||
}
|
||||
for (int i = MIN_LEN; i < index.length; i++) {
|
||||
var len = index[i].words.size();
|
||||
if (len <= 0) {
|
||||
throw new RuntimeException("No words for length " + i);
|
||||
}
|
||||
}
|
||||
for (int i = MIN_LEN; i < index.length; i++) if (index[i].words.size() <= 0) throw new RuntimeException("No words for length " + i);
|
||||
this(index, Arrays.stream(index).mapToInt(i -> i.words.size()).sum());
|
||||
}
|
||||
static Dict loadDict(String wordsPath) {
|
||||
String raw;
|
||||
try {
|
||||
raw = Files.readString(Path.of(wordsPath), StandardCharsets.UTF_8);
|
||||
var map = new ArrayList<Lemma>();
|
||||
Files.lines(Path.of(wordsPath), StandardCharsets.UTF_8).forEach(line -> CsvIndexService.lineToLemma(line, map::add));
|
||||
return new Dict(map.toArray(Lemma[]::new));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Failed to load dictionary from " + wordsPath, e);
|
||||
}
|
||||
|
||||
var map = new ArrayList<Lemma>();
|
||||
var first = true;
|
||||
for (var line : raw.split("\\R")) {
|
||||
if (line.isBlank()) {
|
||||
System.err.println("Empty line: " + line);
|
||||
continue;
|
||||
}
|
||||
var parts = line.split(",", 5);
|
||||
var id = Integer.parseInt(parts[0].trim());
|
||||
var word = parts[1].trim();
|
||||
if (first && word.equalsIgnoreCase("WOORD")) {
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
first = false;
|
||||
var s = word.toUpperCase(Locale.ROOT);
|
||||
if (!s.matches("^[A-Z]{2,8}$")) {
|
||||
System.err.println("Invalid word: " + line);
|
||||
continue;
|
||||
}
|
||||
|
||||
// CSV has level 1-10. llmScores use 10-level.
|
||||
int score = Integer.parseInt(parts[2].trim());
|
||||
if (score < 1) {
|
||||
if (Main.VERBOSE) System.err.println("Word too complex: " + line);
|
||||
continue;
|
||||
}
|
||||
int simpel = Integer.parseInt(parts[3].trim());
|
||||
var rawClue = parts[4].trim();
|
||||
if (rawClue.startsWith("\"") && rawClue.endsWith("\"")) {
|
||||
rawClue = rawClue.substring(1, rawClue.length() - 1).replace("\"\"", "\"");
|
||||
}
|
||||
map.add(new Lemma(id, s, simpel, GSON.fromJson(rawClue, String[].class)));
|
||||
}
|
||||
|
||||
return new Dict(map.toArray(Lemma[]::new));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user