introduce bitloops
This commit is contained in:
@@ -9,15 +9,6 @@ import lombok.experimental.Delegate;
|
||||
import lombok.val;
|
||||
import precomp.Neighbors9x8;
|
||||
import precomp.Neighbors9x8.rci;
|
||||
import puzzle.Export.Bit1029;
|
||||
import puzzle.Export.DictEntryDTO;
|
||||
import puzzle.Export.Gridded;
|
||||
import puzzle.Export.Strings;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import static java.lang.Long.*;
|
||||
import static java.lang.Long.numberOfTrailingZeros;
|
||||
@@ -66,6 +57,18 @@ public class SwedishGenerator {
|
||||
public static final long RANGE_0_624 = 624L - 0L + 1L;
|
||||
public static final int CLUE_INDEX_MAX_SIZE = (288 | 3) + 1;
|
||||
public static int clamp(int x, int a, int b) { return Math.max(a, Math.min(b, x)); }
|
||||
interface Bit1029 {
|
||||
|
||||
static long[] bit1029() { return new long[2048]; }
|
||||
private 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); }
|
||||
}
|
||||
static String padRight(String s, int n) {
|
||||
if (s.length() >= n) return s;
|
||||
return s + " ".repeat(n - s.length());
|
||||
}
|
||||
@AllArgsConstructor
|
||||
public static class Pick {
|
||||
|
||||
@@ -88,24 +91,20 @@ public class SwedishGenerator {
|
||||
@Accessors(fluent = true)
|
||||
public static final class FillStats {
|
||||
|
||||
final public long nodes;
|
||||
final public long backtracks;
|
||||
final public double seconds;
|
||||
final public int lastMRV;
|
||||
public double simplicity;
|
||||
}
|
||||
|
||||
public static record FillResult(boolean ok,
|
||||
|
||||
@Delegate FillStats stats) {
|
||||
public static record FillResult(boolean ok, long nodes, long backtracks, @Delegate FillStats stats) {
|
||||
|
||||
static public long calcSimpel(Slotinfo[] slots) {
|
||||
int k = 0;
|
||||
long simpel = 0L;
|
||||
for (var n = 1; n < slots.length; n++) {
|
||||
if (slots[n].assign().w != X) {
|
||||
if (slots[n].assign.w != X) {
|
||||
k++;
|
||||
simpel += Lemma.simpel(slots[n].assign().w);
|
||||
simpel += Lemma.simpel(slots[n].assign.w);
|
||||
}
|
||||
}
|
||||
simpel = k == 0 ? 0 : simpel / k;
|
||||
@@ -176,52 +175,7 @@ public class SwedishGenerator {
|
||||
static int unpackLetters(long w) { return (int) (w & LETTER_MASK); }
|
||||
}
|
||||
|
||||
public static record Dict(
|
||||
DictEntry[] index,
|
||||
int length) {
|
||||
|
||||
public Dict(long[] wordz) {
|
||||
var index = new DictEntryDTO[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 = MIN_LEN; i < index.length; i++) if (index[i].words().size() <= 0) throw new RuntimeException("No words for length " + i);
|
||||
this(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());
|
||||
}
|
||||
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 new Dict(map.toArray());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Failed to load dictionary from " + wordsPath, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static record Dict(DictEntry[] index, int length) { }
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@@ -391,7 +345,7 @@ public class SwedishGenerator {
|
||||
"%s %d/%d slots | nodes=%d | backtracks=%d | mrv=%d | %s",
|
||||
bar, done, TOTAL, nodes, backtracks, lastMRV, elapsed
|
||||
);
|
||||
System.out.print("\r" + Strings.padRight(msg, 120));
|
||||
System.out.print("\r" + padRight(msg, 120));
|
||||
System.out.flush();
|
||||
}
|
||||
boolean placeWord(final int key, final long lo, final long hi, final long w) {
|
||||
@@ -548,22 +502,7 @@ public class SwedishGenerator {
|
||||
// final progress line
|
||||
grid.lo = solver.glo;
|
||||
grid.hi = solver.ghi;
|
||||
var res = new FillResult(ok,
|
||||
new FillStats(solver.nodes, solver.backtracks, (System.currentTimeMillis() - t0) / 1000.0, solver.lastMRV));
|
||||
if (!multiThreaded) {
|
||||
System.out.print("\r" + Strings.padRight("", 120) + "\r");
|
||||
System.out.flush();
|
||||
}
|
||||
// print a final progress line
|
||||
if (Main.VERBOSE && !multiThreaded) {
|
||||
System.out.println(
|
||||
String.format(Locale.ROOT,
|
||||
"[######################] %d/%d slots | nodes=%d | backtracks=%d | mrv=%d | %.1fs",
|
||||
Slotinfo.wordCount(0, slots), TOTAL, res.nodes(), res.backtracks(), res.lastMRV(), res.seconds()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return res;
|
||||
return new FillResult(ok, solver.nodes, solver.backtracks, new FillStats((System.currentTimeMillis() - t0) / 1000.0, solver.lastMRV));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user