!7 sclass TreeEl { new ByteBuffer a; // characters new DoubleBuffer b; // frequencies new IntBuffer c; // indices into the tree } cmodule2 LetterPredictor > DynPrintLog { start-thread { ByteBuffer input2 = new(toUTF8("hello hello hello hello hello hello")); int de1 = 3; int de2 = 16; S decode = "0."; byte[] alphabet = allBytes(); double[] weights = { 0.916, 0.88, 0.78, 0.96, 0.9, 0.83, 0.82, 0.54, 0.49, 0.25, 0.25, 0.27, 0.33, 0.53, 0.5, 0.53, 0.72 }; double[] weights2 = { 0.72, 0.86, 0.95, 0.93, 0.97 }; L tree = ll(new TreeEl); int window_start = 1; int window_end = 15; double low = 1; double high = 1; double middle = 1; new StringBuilder compressed; for count2 to 50000: { ByteBuffer window = new ByteBuffer(input2.subArray(window_start - 1, window_end)); window_start++; window_end++; int char_location = 15; int remove = 2; int char_index = 1; LPair predictions = ll( pair(new ByteBuffer(alphabet), new DoubleBuffer(rep(0.00001, l(alphabet))))); int node = 0; while (!(char_index == 0 || char_location == 0) && window_end != 16) { if (char_location != 15) { byte _char = window.get(char_location - 1); char_index = tree.get(node).a.indexOf(_char) + 1; } char_location++; if (char_index != 0 && char_location == 16) { TreeEl el = tree.get(node); predictions.add(1, pair(el.a, el.b)); node = 0; char_location -= remove; remove++; } else if (char_index != 0) node = tree.get(node).c.get(char_index - 1); } Pair predict = pair(new ByteBuffer, new DoubleBuffer); int remaining = 1; for q over predictions: { Pair j = predictions.get(q); double sum2 = doubleSum(j.b); double w = sum2 / (l(j.b) == 226 ? 226 : l(j.b) < 6 ? 7 * l(j.b) * weights2[l(j.b) - 1] : l(j.b) * 7); w = w > 20 ? 0.96 : w > 10 ? 0.92 : w > 3 ? 0.89 : w> 1.5 ? 0.75 : w > 1 ? 0.64 : w > 0.7 ? 0.57 : w > 0.5 ? 0.5 : w > 0.4 ? 0.44 : w; double _25ofRoof = (w * weights[l(predictions) - 1 - q]) * remaining; remaining -= _25ofRoof; for (int g = 0; g < l(j.a); g++) { byte k = j.a.get(g); double freq = j.b.get(g); char_index = predict.a.indexOf(k) + 1; if (char_index == 0) { predict.a.add(k); predict.b.add((freq / sum2) * _25ofRoof); } else predict.b.set(char_index - 1, predict.b.get(char_index - 1) + (freq / sum2) * _25ofRoof); } } double summ = 1 - doubleSum(predict.b); int nPredict = l(predict.b); for n to nPredict: predict.b.set(n, predict.b.get(n) + summ / l(predict.b)); low = high; double decodepart = parseDouble("0." + substring(decode, de1 - 1, de2)); for (int m = 0; m < l(predict.a); m++) { byte x = predict.a.get(m); high = low; low -= predict.b.get(m) * middle; if (eq(decode, "0.") && x == last(window)) break; else if (high > decodepart && decodepart > low) { window.add(x); input2.add(x); break; } } char_location = lCommonPrefix(str(low), str(high)); compressed.append(substr(str(low), 2, char_location)); char_location -= 2; for count to char_location: { high *= 10; low *= 10; de1++; de2++; } middle = floor(low); high -= middle; low -= middle; middle = high - low; node = 0; for (byte i : window) { TreeEl el = tree.get(node); char_index = el.a.indexOf(i) + 1; if (char_index == 0) { el.a.add(i); el.b.add(1); el.c.add(node = l(tree)); tree.add(new TreeEl); } else { el.b.set(char_index - 1, el.b.get(char_index - 1) + 1); node = el.c.get(char_index - 1); } } } print(+compressed); } }