introduce bitloops

This commit is contained in:
mike
2026-01-17 04:35:53 +01:00
parent 47b33af09d
commit 3bd7a0f958
6 changed files with 95 additions and 100 deletions

View File

@@ -7,9 +7,15 @@ import lombok.val;
import puzzle.Export.Gridded.Replacar.Cell;
import puzzle.Export.LetterVisit.LetterAt;
import puzzle.Masker.Clues;
import puzzle.SwedishGenerator.Dict;
import puzzle.SwedishGenerator.DictEntry;
import puzzle.SwedishGenerator.FillResult;
import puzzle.SwedishGenerator.Grid;
import puzzle.SwedishGenerator.Slotinfo;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -191,15 +197,6 @@ public record Export() {
}
}
interface Bit1029 {
static long[] bit1029() { return new long[2048]; }
static int wordIndex(int bitIndex) { return bitIndex >> 6; }
static boolean get(long[] bits, int bitIndex) { return (bits[wordIndex(bitIndex)] & 1L << bitIndex) != 0L; }
static void set(long[] bits, int bitIndex) { bits[wordIndex(bitIndex)] |= 1L << bitIndex; }
static void clear(long[] bits, int bitIndex) { bits[wordIndex(bitIndex)] &= ~(1L << bitIndex); }
}
record Placed(long lemma, int slotKey, int[] cells) {
static final char[] DIRECTION = { Placed.VERTICAL, Placed.HORIZONTAL, Placed.VERTICAL, Placed.HORIZONTAL };
@@ -286,6 +283,51 @@ public record Export() {
}
}
interface Dicts {
static Dict loadDict(String wordsPath) {
try {
var map = new LongArrayList(100_000);
Files.lines(Path.of(wordsPath), StandardCharsets.UTF_8).forEach(line -> CsvIndexService.lineToLemma(line, map::add));
return makeDict(map.toArray());
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Failed to load dictionary from " + wordsPath, e);
}
}
static Dict makeDict(long[] wordz) {
var index = new DictEntryDTO[SwedishGenerator.MAX_WORD_LENGTH_PLUS_ONE];
Arrays.setAll(index, i -> new DictEntryDTO(i));
for (var lemma : wordz) {
var L = Lemma.length(lemma);
var entry = index[L];
var idx = entry.words().size();
entry.words().add(lemma);
for (var i = 0; i < L; i++) entry.pos()[i][Lemma.byteAt(lemma, i) - 1].add(idx);
}
for (int i = SwedishGenerator.MIN_LEN; i < index.length; i++) if (index[i].words().size() <= 0) throw new RuntimeException("No words for length " + i);
return new Dict(Arrays.stream(index).map(i -> {
var words = i.words().toArray();
int numWords = words.length;
int numLongs = (numWords + 63) >>> 6;
var bitsets = new long[i.pos().length * 26][numLongs];
for (int p = 0; p < i.pos().length; p++) {
for (int l = 0; l < 26; l++) {
var list = i.pos()[p][l];
var bs = bitsets[p * 26 + l];
for (int k = 0; k < list.size(); k++) {
int wordIdx = list.data()[k];
bs[wordIdx >>> 6] |= (1L << (wordIdx & 63));
}
}
}
return new DictEntry(words, bitsets, words.length, (words.length + 63) >>> 6);
}).toArray(DictEntry[]::new),
Arrays.stream(index).mapToInt(i -> i.words().size()).sum());
}
}
record DictEntryDTO(LongArrayList words, IntListDTO[][] pos) {
public DictEntryDTO(int L) {