package puzzle; import module java.base; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import lombok.val; import puzzle.SwedishGenerator.Dict; import puzzle.SwedishGenerator.DictEntry; import puzzle.SwedishGenerator.Lemma; import static java.nio.charset.StandardCharsets.US_ASCII; public final class DictJavaGeneratorMulti { interface Dicts { static Dict makeDict(long[] wordz) { var index = new DictEntryDTO[SwedishGenerator.MAX_WORD_LENGTH_PLUS_ONE]; Arrays.setAll(index, DictEntryDTO::new); for (var lemma : wordz) { var L = Lemma.unpackSize(lemma) + 1;//Lemma.unpackSize(lemma) + 2; val entry = index[L]; val idx = entry.words().size(); val pos = entry.pos(); entry.words().add(lemma); var i = 0; for (var w = lemma & Lemma.LETTER_MASK; w != 0; w >>>= 5, i++) { pos[i][(int) ((w & 31) - 1)].add(idx); } } for (var i = 2; 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(); var numWords = words.length; var numLongs = (numWords + 63) >>> 6; var bitsets = new long[i.pos().length * 26][numLongs]; for (var p = 0; p < i.pos().length; p++) { for (var l = 0; l < 26; l++) { var list = i.pos()[p][l]; var bs = bitsets[p * 26 + l]; for (var k = 0; k < list.size(); k++) { var 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) { this(new LongArrayList(1024), new IntListDTO[L][26]); for (var i = 0; i < L; i++) for (var j = 0; j < 26; j++) pos[i][j] = new IntListDTO(); } @Getter @Accessors(fluent = true) @NoArgsConstructor static final class IntListDTO { int[] data = new int[8]; int size = 0; void add(int v) { if (size >= data.length) data = Arrays.copyOf(data, data.length * 2); data[size++] = v; } } } static final class LongArrayList { long[] a; int size; LongArrayList(int initialCapacity) { if (initialCapacity < 0) throw new IllegalArgumentException(); a = new long[initialCapacity]; } int size() { return size; } void add(long v) { if (size == a.length) grow(); a[size++] = v; } void grow() { var newCap = a.length == 0 ? 1 : a.length * 2; var n = new long[newCap]; System.arraycopy(a, 0, n, 0, size); a = n; } long[] toArray() { return Arrays.copyOf(a, this.size); } } }