import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import java.math.*;
// A = compressor type (e.g. s), Data = data type
import java.text.NumberFormat;
import static x30_pkg.x30_util.DynamicObject;
class main {
static class CompressionSearch_AnyType extends Probabilistic {
// user-set
final public CompressionSearch_AnyType setRegime(CompressionRegime_AnyType regime){ return regime(regime); }
public CompressionSearch_AnyType regime(CompressionRegime_AnyType regime) { this.regime = regime; return this; } final public CompressionRegime_AnyType getRegime(){ return regime(); }
public CompressionRegime_AnyType regime() { return regime; } CompressionRegime_AnyType regime;
final public Data getInputData(){ return inputData(); }
public Data inputData() { return inputData; } Data inputData;
final public CompressionSearch_AnyType setInputSize(long inputSize){ return inputSize(inputSize); }
public CompressionSearch_AnyType inputSize(long inputSize) { this.inputSize = inputSize; return this; } final public long getInputSize(){ return inputSize(); }
public long inputSize() { return inputSize; } long inputSize; // in bytes
final public CompressionSearch_AnyType setDoFullTesting(boolean doFullTesting){ return doFullTesting(doFullTesting); }
public CompressionSearch_AnyType doFullTesting(boolean doFullTesting) { this.doFullTesting = doFullTesting; return this; } final public boolean getDoFullTesting(){ return doFullTesting(); }
public boolean doFullTesting() { return doFullTesting; } boolean doFullTesting = false; // go full javaEval [VERY SLOW]
transient List onNewBest;
CompressionSearch_AnyType onNewBest(Runnable r) { onNewBest = syncAddOrCreate(onNewBest, r); return this; }
void newBest() { pcallFAll(onNewBest); }
transient List> onDisqualified;
CompressionSearch_AnyType onDisqualified(IVF1 f) { onDisqualified = syncAddOrCreate(onDisqualified, f); return this; }
void disqualified(Submission s) { pcallFAll(onDisqualified, s); }
// public output variables
Best best = new Best();
List strategies = new ArrayList();
CompressionSearch_AnyType() { init(); }
CompressionSearch_AnyType(CompressionRegime_AnyType regime) {
this.regime = regime; init(); }
CompressionSearch_AnyType(CompressionRegime_AnyType regime, Data inputData, long inputSize) {
this.inputSize = inputSize;
this.inputData = inputData;
this.regime = regime; init(); }
void init() {
best.onChange = new Runnable() { public void run() { try { newBest();
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "newBest();"; }};
}
// can submit concurrently!
Submission submit(A compression) { return submit(compression, null); }
Submission submit(A compression, Object notes) {
return _submit(compression, notes);
}
// private (although Submission is returned)
class Submission {
final public Submission setNotes(Object notes){ return notes(notes); }
public Submission notes(Object notes) { this.notes = notes; return this; } final public Object getNotes(){ return notes(); }
public Object notes() { return notes; } Object notes;
public String toString() {
if (!correct()) return linesLL("BAD");
return linesLL(
(isTrue(isFullChecked()) ? "FULLCHECKED"
: " ") + " " + ifloor(score()*100),
"Exact compression ratio: " + scoreRatio(),
"Code:",
indentx(shorten(500, str(decompressor()))),
"Code as bytes:",
indentx(shorten(500, bytesToHex(compressed())))
);
}
void setDecompressor(A decompressor) {
this.decompressor_cache = decompressor;
}
Data inputData() { return inputData; }
byte[] compressed_cache;
byte[] compressed() { if (compressed_cache == null) compressed_cache = compressed_load(); return compressed_cache; }
byte[] compressed_load() {
return decompressor_cache == null ? null : regime.decompressorToBytes(decompressor_cache);
}
A decompressor_cache;
A decompressor() { if (decompressor_cache == null) decompressor_cache = decompressor_load(); return decompressor_cache; }
A decompressor_load() {
return compressed_cache == null ? null : regime.decompressorFromBytes(compressed_cache);
}
String decompressor_str_cache;
String decompressor_str() { if (decompressor_str_cache == null) decompressor_str_cache = decompressor_str_load(); return decompressor_str_cache; }
String decompressor_str_load() {
return strOrNull(decompressor());
}
final int nBytes(){ return compressedSize(); }
int compressedSize() { return l(compressed()); }
Ratio scoreRatio_cache;
Ratio scoreRatio() { if (scoreRatio_cache == null) scoreRatio_cache = scoreRatio_load(); return scoreRatio_cache; }
Ratio scoreRatio_load() {
return new Ratio(inputSize(), compressedSize());
}
Double score_cache;
double score() { if (score_cache == null) score_cache = score_load(); return score_cache; }
Double score_load() {
return scoreRatio().get();
}
boolean decompressed = false;
Object decompressedValue;
Object decompressed() {
if (!decompressed) {
decompressedValue = regime.runDecompressor(decompressor());
decompressed = true;
}
return decompressedValue;
}
boolean checkUnder(CompressionRegime_AnyType regime) {
return checkResult(regime.runDecompressor(decompressor()));
}
Boolean isFullChecked_cache;
Boolean isFullChecked() { if (isFullChecked_cache == null) isFullChecked_cache = isFullChecked_load(); return isFullChecked_cache; }
Boolean isFullChecked_load() {
if (!isTrue(correct())) return false;
var fullRegime = fullRegime();
if (fullRegime == null) return true;
return checkUnder(fullRegime);
}
boolean checkResult(Object decompressed) {
return eq(toByteList(decompressed), inputData());
}
Boolean correct_cache;
Boolean correct() { if (correct_cache == null) correct_cache = correct_load(); return correct_cache; }
Boolean correct_load() {
return eq(toByteList(decompressed()), inputData());
}
} // end of Submission
Submission _submit(A compression, Object notes) {
if (compression == null) return null;
print("Received submission");
print("Code: " + takeFirst(500, str(compression)));
Submission s = new Submission();
s.notes(notes);
print("Notes: " + takeFirst(500, str(notes)));
s.setDecompressor(compression);
print("Size: " + nBytes(s.nBytes()));
if (s.score() > best.score())
if (!s.correct()) {
warn("Compressor didn't verify");
disqualified(s);
} else {
print("Score: " + s.score());
best.put(s, s.score());
}
return s;
}
Submission bestSubmission() {
methodForEach(__19 -> __19.flush(), strategies);
return best.get();
}
final A get(){ return bestCompression(); }
A bestCompression() {
var s = bestSubmission();
return s == null ? null : s.decompressor();
}
boolean has() { return bestSubmission() != null; }
void addStrategy(AbstractCompressor_AnyType compressor) {
if (compressor == null) return;
initAction(compressor);
compressor.setSearch(this);
strategies.add(compressor);
compressor.step0();
}
transient IF0 fullRegime;
CompressionRegime_AnyType fullRegime() { return fullRegime != null ? fullRegime.get() : fullRegime_base(); }
final CompressionRegime_AnyType fullRegime_fallback(IF0 _f) { return _f != null ? _f.get() : fullRegime_base(); }
CompressionRegime_AnyType fullRegime_base() {
if (doFullTesting)
return regime.fullRegime();
return null;
}
// actually not needed, addStrategy schedules a strategy immediately
public void step0() {}
}
static List syncAddOrCreate(List l, A a) {
if (l == null) l = syncList();
l.add(a);
return l;
}
static void pcallFAll(Collection l, Object... args) {
if (l != null) for (Object f : cloneList(l)) pcallF(f, args);
}
static void pcallFAll(Iterator it, Object... args) {
while (it.hasNext()) pcallF(it.next(), args);
}
static RuntimeException rethrow(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static RuntimeException rethrow(String msg, Throwable t) {
throw new RuntimeException(msg, t);
}
static String linesLL(Object... x) {
return lines(ll(x));
}
static boolean isTrue(Object o) {
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
if (o == null) return false;
if (o instanceof ThreadLocal) // TODO: remove this
return isTrue(((ThreadLocal) o).get());
throw fail(getClassName(o));
}
static boolean isTrue(Boolean b) {
return b != null && b.booleanValue();
}
static int ifloor(double d) {
return (int) Math.floor(d);
}
static IntRange ifloor(DoubleRange r) {
return r == null ? null : intRange(ifloor(r.start), ifloor(r.end));
}
static float score(Scored s) {
return s == null ? 0 : s.score();
}
static String indentx(String s) {
return indentx(indent_default, s);
}
static String indentx(int n, String s) {
return dropSuffix(repeat(' ', n), indent(n, s));
}
static String indentx(String indent, String s) {
return dropSuffix(indent, indent(indent, s));
}
static int shorten_default = 100;
static String shorten(CharSequence s) { return shorten(s, shorten_default); }
static String shorten(CharSequence s, int max) {
return shorten(s, max, "...");
}
static String shorten(CharSequence s, int max, String shortener) {
if (s == null) return "";
if (max < 0) return str(s);
return s.length() <= max ? str(s) : subCharSequence(s, 0, min(s.length(), max-l(shortener))) + shortener;
}
static String shorten(int max, CharSequence s) { return shorten(s, max); }
static String str(Object o) {
return o == null ? "null" : o.toString();
}
static String str(char[] c) {
return new String(c);
}
public static String bytesToHex(byte[] bytes) {
return bytesToHex(bytes, 0, bytes.length);
}
public static String bytesToHex(byte[] bytes, int ofs, int len) {
StringBuilder stringBuilder = new StringBuilder(len*2);
for (int i = 0; i < len; i++) {
String s = "0" + Integer.toHexString(bytes[ofs+i]);
stringBuilder.append(s.substring(s.length()-2, s.length()));
}
return stringBuilder.toString();
}
static String strOrNull(Object o) {
return o == null ? null : str(o);
}
static int l(Object[] a) { return a == null ? 0 : a.length; }
static int l(boolean[] a) { return a == null ? 0 : a.length; }
static int l(byte[] a) { return a == null ? 0 : a.length; }
static int l(short[] a) { return a == null ? 0 : a.length; }
static int l(long[] a) { return a == null ? 0 : a.length; }
static int l(int[] a) { return a == null ? 0 : a.length; }
static int l(float[] a) { return a == null ? 0 : a.length; }
static int l(double[] a) { return a == null ? 0 : a.length; }
static int l(char[] a) { return a == null ? 0 : a.length; }
static int l(Collection c) { return c == null ? 0 : c.size(); }
static int l(Iterator i) { return iteratorCount_int_close(i); } // consumes the iterator && closes it if possible
static int l(Map m) { return m == null ? 0 : m.size(); }
static int l(CharSequence s) { return s == null ? 0 : s.length(); }
static long l(File f) { return f == null ? 0 : f.length(); }
static int l(Object o) {
return o == null ? 0
: o instanceof String ? l((String) o)
: o instanceof Map ? l((Map) o)
: o instanceof Collection ? l((Collection) o)
: o instanceof Object[] ? l((Object[]) o)
: o instanceof boolean[] ? l((boolean[]) o)
: o instanceof byte[] ? l((byte[]) o)
: o instanceof char[] ? l((char[]) o)
: o instanceof short[] ? l((short[]) o)
: o instanceof int[] ? l((int[]) o)
: o instanceof float[] ? l((float[]) o)
: o instanceof double[] ? l((double[]) o)
: o instanceof long[] ? l((long[]) o)
: (Integer) call(o, "size");
}
static int l(IntRange r) { return r == null ? 0 : r.length(); }
static double l(DoubleRange r) { return r == null ? 0 : r.length(); }
static boolean eq(Object a, Object b) {
return a == b || a != null && b != null && a.equals(b);
}
// a little kludge for stuff like eq(symbol, "$X")
static boolean eq(Symbol a, String b) {
return eq(str(a), b);
}
static List toByteList(Object o) {
if (o == null) return null;
if (o instanceof List) return ((List) o);
if (o instanceof Iterable) return toList((Iterable) o);
if (o instanceof byte[]) return wrapPrimitiveArrayAsImmutableList((byte[]) o);
throw fail();
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static volatile Appendable print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
static boolean print_silent = false; // total mute if set
static Object print_byThread_lock = new Object();
static volatile ThreadLocal