introduce bitloops
This commit is contained in:
@@ -52,7 +52,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
static final int SIZE = C * R;// ~18
|
||||
static final int SIZE_MIN_1 = SIZE - 1;// ~18
|
||||
static final double SIZED = (double) SIZE;// ~18
|
||||
static final int TARGET_CLUES = SIZE >> 2;
|
||||
static final int TARGET_CLUES = SIZE >>> 2;
|
||||
static final int MAX_WORD_LENGTH = C <= R ? C : R;
|
||||
static final int MAX_WORD_LENGTH_PLUS_ONE = MAX_WORD_LENGTH + 1;
|
||||
static final int MIN_LEN = Config.MIN_LEN;
|
||||
@@ -192,19 +192,10 @@ public record SwedishGenerator(Rng rng) {
|
||||
else hi &= ~(1L << (idx & 63));
|
||||
}
|
||||
static boolean isDigit(byte b) { return (b & B48) == B48; }
|
||||
boolean isClue(long index) {
|
||||
if ((index & 64) == 0) return ((lo >> index) & 1L) != X;
|
||||
return ((hi >> (index & 63)) & 1L) != X;
|
||||
}
|
||||
boolean isClue(int index) {
|
||||
if ((index & 64) == 0) return ((lo >> index) & 1L) != 0;
|
||||
return ((hi >> (index & 63)) & 1L) != 0;
|
||||
}
|
||||
boolean notClue(long index) {
|
||||
if ((index & 64) == 0) return ((lo >> index) & 1L) == X;
|
||||
return ((hi >> (index & 63)) & 1L) == X;
|
||||
}
|
||||
boolean notClue(int index) { return ((index & 64) == 0) ? ((lo >> index) & 1L) == X : ((hi >> (index & 63)) & 1L) == X; }
|
||||
boolean isClue(long index) { return ((index & 64) == 0) ? ((lo >>> index) & 1L) != X : ((hi >>> (index & 63)) & 1L) != X; }
|
||||
boolean isClue(int index) { return ((index & 64) == 0) ? ((lo >>> index) & 1L) != X : ((hi >>> (index & 63)) & 1L) != X; }
|
||||
boolean notClue(long index) { return ((index & 64) == 0) ? ((lo >>> index) & 1L) == X : ((hi >>> (index & 63)) & 1L) == X; }
|
||||
boolean notClue(int index) { return ((index & 64) == 0) ? ((lo >>> index) & 1L) == X : ((hi >>> (index & 63)) & 1L) == X; }
|
||||
boolean clueless(int idx) {
|
||||
if ((idx & 64) == 0) {
|
||||
val test = (1L << idx);
|
||||
@@ -236,7 +227,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,25 +238,19 @@ public record SwedishGenerator(Rng rng) {
|
||||
static final long LETTER_MASK = (1L << 40) - 1; // low 40 bits
|
||||
static final long INDEX_MASK = (1L << 24) - 1; // 24 bits
|
||||
static int LEMMA_COUNTER = 0;
|
||||
static long pack(String word) { return pack(word.getBytes(US_ASCII)); }
|
||||
static long pack(int index, byte[] b) {
|
||||
return pack(b) | ((long) index << 40);
|
||||
}
|
||||
static long pack(String word) { return pack(word.getBytes(US_ASCII)); }
|
||||
static long pack(int index, byte[] b) { return pack(b) | ((long) index << 40); }
|
||||
static long pack(byte[] b) {
|
||||
long w = 0;
|
||||
for (var i = 0; i < b.length; i++) w |= ((long) b[i] & ~64) << (i * 5);
|
||||
return w;
|
||||
}
|
||||
public Lemma(int index, String word) { this(pack(index, word.getBytes(US_ASCII))); }
|
||||
public Lemma(String word) { this(LEMMA_COUNTER++, word); }
|
||||
byte byteAt(int idx) { return Lemma.byteAt(word, idx); }// word[]; }
|
||||
static byte byteAt(long word, int idx) { return (byte) ((word >>> (idx * 5)) & 0b11111 | B64); }// word[]; }
|
||||
int intAt(int idx) { return (int) (((word >>> (idx * 5))) & 0b11111); }// word[]; }
|
||||
@Override public int hashCode() { return unpackIndex(word); }
|
||||
@Override public boolean equals(Object o) { return (o == this) || (o instanceof Lemma l && l.word == word); }
|
||||
static String[] clue(long w) { return CsvIndexService.clues(unpackIndex(w)); }
|
||||
static int simpel(long w) { return CsvIndexService.simpel(unpackIndex(w)); }
|
||||
int length() { return Lemma.length(word); }
|
||||
public Lemma(int index, String word) { this(pack(index, word.getBytes(US_ASCII))); }
|
||||
public Lemma(String word) { this(LEMMA_COUNTER++, word); }
|
||||
static byte byteAt(long word, int idx) { return (byte) ((word >>> (idx * 5)) & 0b11111 | B64); }// word[]; }
|
||||
static int intAt(long word, int idx) { return (int) (((word >>> (idx * 5))) & 0b11111); }// word[]; }
|
||||
static String[] clue(long w) { return CsvIndexService.clues(unpackIndex(w)); }
|
||||
static int simpel(long w) { return CsvIndexService.simpel(unpackIndex(w)); }
|
||||
static int length(long word) {
|
||||
if (word == 0) return 0;
|
||||
int highestBit = 63 - Long.numberOfLeadingZeros(word & LETTER_MASK);
|
||||
@@ -293,25 +278,25 @@ public record SwedishGenerator(Rng rng) {
|
||||
DictEntry[] index,
|
||||
int length) {
|
||||
|
||||
public Dict(Lemma[] wordz) {
|
||||
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();
|
||||
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++) {
|
||||
var letter = lemma.intAt(i) - 1;
|
||||
var letter = Lemma.intAt(lemma, i) - 1;
|
||||
if (letter < 0 || letter >= 26) throw new RuntimeException("Illegal letter: " + letter + " in word " + lemma);
|
||||
entry.pos()[i][letter].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().stream().mapToLong(ww -> ww.word).toArray();
|
||||
var words = i.words().toArray();
|
||||
int numWords = words.length;
|
||||
int numLongs = (numWords + 63) >>> 6;
|
||||
var bitsets = new long[i.pos().length * 26][numLongs];
|
||||
@@ -331,9 +316,9 @@ public record SwedishGenerator(Rng rng) {
|
||||
}
|
||||
static Dict loadDict(String wordsPath) {
|
||||
try {
|
||||
var map = new ArrayList<Lemma>();
|
||||
var map = new LongArrayList(100_000);
|
||||
Files.lines(Path.of(wordsPath), UTF_8).forEach(line -> CsvIndexService.lineToLemma(line, map::add));
|
||||
return new Dict(map.toArray(Lemma[]::new));
|
||||
return new Dict(map.toArray());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Failed to load dictionary from " + wordsPath, e);
|
||||
@@ -354,7 +339,7 @@ public record SwedishGenerator(Rng rng) {
|
||||
public boolean horiz() { return horiz(key); }
|
||||
public int pos(int i) { return offset(packedPos, i); }
|
||||
public static boolean horiz(int key) { return (key & 1) == 0; }
|
||||
public static int offset(long packedPos, int i) { return (int) ((packedPos >> (i * 7)) & 127); }
|
||||
public static int offset(long packedPos, int i) { return (int) ((packedPos >>> (i * 7)) & 127); }
|
||||
public static int packSlotDir(int idx, int d) { return (idx << BIT_FOR_DIR) | d; }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user