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.*;
import java.text.NumberFormat;
import static x30_pkg.x30_util.DynamicObject;
class main {
interface ICompressionStrategy {
AbstractCompressor makeSearcher(CompressionSearch search);
}
abstract static class AbstractCompressor extends Probabilistic {
CompressionSearch search;
AbstractCompressor() {}
AbstractCompressor(CompressionSearch search) {
this.search = search;}
void setSearch(CompressionSearch search) {
if (this.search != null && this.search != search) throw fail();
this.search = search;
}
CompressionRegime regime() { return search == null ? null : search.regime(); }
// get current best compressed representation
//abstract A currentBestDecompressor aka get();
}
// CompressionSearch
// The terms are flying all over the place with this one
// (compressor, decompressor, compression, decompression, ...)
// Basic idea: INPUT DATA (byte list) is compressed into a
// CUSTOM OBJECT (called the "COMPRESSION"), which, when run
// under a fitting COMPRESSION REGIME produces the INPUT DATA.
//
// Every compression can also be converted to and from a byte array
// (the compression regime does this).
static class CompressionSearch extends Probabilistic {
// user-set
CompressionSearch regime(CompressionRegime regime) { this.regime = regime; return this; } CompressionRegime regime() { return regime; } CompressionRegime regime;
CompressionSearch inputData(List inputData) { this.inputData = inputData; return this; } List inputData() { return inputData; } List inputData;
// public output variables
Best best = new Best();
CompressionSearch(CompressionRegime regime) {
this.regime = regime;}
CompressionSearch(CompressionRegime regime, List inputData) {
this.inputData = inputData;
this.regime = regime;}
CompressionSearch(CompressionRegime regime, byte[] inputData) { this.inputData = byteArrayToList(inputData);
this.regime = regime; }
// can submit concurrently!
Submission submit(A compression) { return _submit(compression); }
// private (although Submission is returned)
class Submission {
public String toString() {
return linesLL(
"Compressor " + (correct() ? "correct" : "incorrect"),
"Compression factor " + score(),
"Code:",
indentx(str(decompressor())),
"Code as bytes:",
indentx(bytesToHex(compressed()))
);
}
void setDecompressor(A decompressor) {
this.decompressor_cache = decompressor;
}
List inputData() { return inputData; }
byte[] inputDataAsArray() { return byteListToArray(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);
}
int compressedSize() { return l(compressed()); }
Double score_cache;
double score() { if (score_cache == null) score_cache = score_load(); return score_cache; }
Double score_load() {
return doubleRatio(inputDataSize(), compressedSize());
}
boolean decompressed = false;
Object decompressedValue;
Object decompressed() {
if (!decompressed) {
decompressedValue = regime.runDecompressor(decompressor());
decompressed = true;
}
return decompressedValue;
}
Boolean correct_cache;
Boolean correct() { if (correct_cache == null) correct_cache = correct_load(); return correct_cache; }
Boolean correct_load() {
return eq(toByteList(decompressed()), inputData());
}
}
int inputDataSize() { return l(inputData); }
Submission _submit(A compression) {
if (compression == null) return null;
Submission s = new Submission();
s.setDecompressor(compression);
if (s.score() > best.score())
if (!s.correct())
warn("Compressor didn't verify");
else
best.put(s, s.score());
return s;
}
final A get(){ return bestCompression(); }
A bestCompression() {
var s = best.get();
return s == null ? null : s.decompressor();
}
void addStrategy(AbstractCompressor compressor) {
if (compressor == null) return;
initAction(compressor);
compressor.setSearch(this);
compressor.run();
}
public void run() { try {} catch (Exception __e) { throw rethrow(__e); } }
}
interface CompressionRegime {
byte[] decompressorToBytes(A decompressor);
A decompressorFromBytes(byte[] compressed);
// return byte array, byte list or byte iterator
Object runDecompressor(A a);
default byte[] runDecompressorToBytes(A a) {
return toByteArray(runDecompressor(a));
}
default byte[] decompress(byte[] compressed) {
return toByteArray(runDecompressor(decompressorFromBytes(compressed)));
}
default List decompressToByteList(byte[] compressed) {
return toByteList(runDecompressor(decompressorFromBytes(compressed)));
}
default Iterator decompressToByteIterator(byte[] compressed) {
return toByteIterator(runDecompressor(decompressorFromBytes(compressed)));
}
}
// "Probabilistic" - a probabilistic runnable
// subclass must implement run {} to do first action and schedule
// next steps with at() or atRelative()
// Creates its own scheduler if none is set
// Steppable is implemented only as convenience
// (it steps the whole scheduler)
// TODO: This is not very clear
abstract static class Probabilistic implements IProbabilistic, Steppable {
IProbabilisticScheduler ps;
void initScheduler() {
if (ps == null) ps = new ProbabilisticScheduler();
}
public void setScheduler(IProbabilisticScheduler ps) {
this.ps = ps;
}
public IProbabilisticScheduler scheduler() {
initScheduler();
return ps;
}
// Breaking change: Made this relative
final void at(Runnable action){ schedule(action); }
void schedule(Runnable action) {
scheduleRelative(1.0, action);
}
final void at(double probability, Runnable action){ schedule(probability, action); }
void schedule(double probability, Runnable action) {
initScheduler();
ps.at(probability, action);
}
final void atRelative(double probability, Runnable action){ scheduleRelative(probability, action); }
void scheduleRelative(double probability, Runnable action) {
initScheduler();
ps.atRelative(probability, action);
}
void scheduleAll(Iterable extends Runnable> actions) {
forEach(__21 -> schedule(__21), actions);
}
void scheduleAll(double probability, Iterable extends Runnable> actions) {
forEach(actions, a -> schedule(probability, a));
}
void scheduleAllRelative(double probability, Iterable extends Runnable> actions) {
forEach(actions, a -> scheduleRelative(probability, a));
}
A initAction(A a) {
scheduler().initAction(a);
return a;
}
////// the "weird" convenience stuff
// call run() before
void stepAll() {
main.stepAll(ps);
}
// call run() before
public boolean step() {
return ps.step();
}
}
static class Best {
A best;
double score;
boolean verboseNewBest, replaceIfSameScore;
transient Object onChange;
transient Object stringifier; // func(A) -> S
synchronized boolean isNewBest(double score) {
return best == null || !isNaN(score)
&& (replaceIfSameScore
? score >= this.score
: score > this.score);
}
synchronized double bestScore() {
return best == null ? minusInfinity() : score;
}
double score() { return bestScore(); }
double getScore() { return bestScore(); }
synchronized float floatScoreOr(float defaultValue) {
return best == null ? defaultValue : (float) score;
}
boolean put(Pair extends A, Double> p) {
return p != null && put(p.a, p.b);
}
boolean put(Best extends A> b) {
return b != null && put(b.get(), b.score);
}
boolean put(A a, double score) {
ping();
boolean change = false;
if (a != null) synchronized(this) {
if (isNewBest(score)) {
best = a;
this.score = score;
change = true;
}
}
if (change) {
if (verboseNewBest) print("New best! " + this);
pcallF(onChange);
}
return change;
}
synchronized A get() { return best; }
synchronized boolean has() { return best != null; }
synchronized Pair pair() { return main.pair(best, bestScore()); }
synchronized Scored scored() { return best == null ? null : new Scored(best, bestScore()); }
synchronized A getIfScoreAbove(double x) { return score() >= x ? best : null; }
public String toString() {
return "Score " + formatDouble_significant2(score, 4) + ": " + callStringifier(stringifier, best);
}
boolean putAndPrintIfNewBest(A a, double score) {
if (!put(a, score)) return false;
{ print(this); return true; }
}
synchronized void clear() { best = null; score = 0; }
}
// Note: Service providers schedule actions.
// Only puzzle runners call step().
// interface for ProbabilisticScheduler (#1031949)
static interface IProbabilisticScheduler extends Steppable {
// schedule an action at an absolute probability
void at(double probability, Runnable action);
// schedule an action at a probability relative to
// currentProbability()
default void schedule(double probability, Runnable action){ atRelative(probability, action); }
default void atRelative(double probability, Runnable action) {
at(currentProbability()*probability, action);
}
double currentProbability(); // for thread, only while running a step
long stepCount();
double lastExecutedProbability();
default void schedule(Runnable x){ run(x); }
default void at(Runnable x){ run(x); }
default void run(Runnable x) {
if (x == null) return;
initAction(x);
x.run();
}
default void scheduleAll(Iterable> l) {
for (var x : unnullForIteration(l))
at(x.probability(), x.get());
}
default void initAction(Runnable action) {
if (action instanceof IProbabilistic)
((IProbabilistic) action).setScheduler(this);
}
}
static class ProbabilisticScheduler implements IProbabilisticScheduler, Steppable {
TreeSetWithDuplicates < Entry > entries = new TreeSetWithDuplicates<>(byProbability());
long stepCount;
boolean verbose = false;
// must be >= 0. probability 0 is never executed
double cutoffProbabilityOnAdd = 0;
double cutoffProbabilityOnExecute = 0;
Comparator byProbability() { return (a, b) -> cmp(b.probability, a.probability); }
double lastExecutedProbability = 1.0;
ThreadLocal threadProbability = new ThreadLocal();
class Entry {
Entry() {}
double probability;
Runnable action;
Entry(double probability, Runnable action) {
this.action = action;
this.probability = probability;}
public void run() { try {
initAction(action);
AutoCloseable __1 = tempSetTL(threadProbability, probability); try {
action.run();
} finally { _close(__1); }} catch (Exception __e) { throw rethrow(__e); } }
public String toString() {
return str(new WithProbability(probability, action));
}
}
final public void at(double probability, Runnable action){ add(probability, action); }
public void add(double probability, Runnable action) {
if (action == null) return;
if (probability <= cutoffProbabilityOnAdd) return;
entries.add(new Entry(probability, action));
}
public boolean step() {
return stepFirstUnstepped();
}
Entry nextSteppable() {
Entry s = first(entries);
if (s != null && s.probability <= cutoffProbabilityOnExecute) return null;
return s;
}
// returns false when done stepping
boolean stepFirstUnstepped() {
Entry s = nextSteppable(); if (s == null) return false;
if (verbose) print("Current scheduler probability: " + s.probability);
entries.remove(s);
++stepCount;
lastExecutedProbability = s.probability;
s.run();
return true;
}
void reset() {
entries.clear();
}
public void run() { try {
stepAll(this);
} catch (Exception __e) { throw rethrow(__e); } }
void run(int maxSteps) {
stepMax(maxSteps, this);
}
void printStats() {
Entry first = entries.first(), last = entries.last();
Entry next = nextSteppable();
print("ProbabilisticScheduler. "
+ nEntries(entries)
+ ", highest probability in queue: " + (first == null ? "-" : first.probability)
+ ", lowest probability in queue: " + (last == null ? "-" : last.probability)
+ ", cutoff probability: " + cutoffProbabilityOnAdd + "/" + cutoffProbabilityOnExecute
+ ", " + (next == null ? "done" : "next step: " + next.action));
}
// Get probability of this thread's Runnable.
// Or 1.0 when we are coming from "outside" (so you don't _have_ to
// run your first step through the scheduler).
final public double current(){ return currentProbability(); }
public double currentProbability() {
return or(threadProbability.get(), 1.0);
}
/*IProbabilisticScheduler freeze() {
double prob = currentProbability();
ret new IProbabilisticScheduler {
public void at(double probability, Runnable action) {
ProbabilisticScheduler.this.at(prob*probability, action);
}
public double currentProbability() {
ret prob;
}
public long stepCount() { ret stepCount; }
};
}*/
double remainingProbability() {
Entry s = nextSteppable();
return s == null ? 0.0 : s.probability;
}
public double lastExecutedProbability() { return lastExecutedProbability; }
public long stepCount() { return stepCount; }
}
// "IProbabilistic" - a probabilistic runnable
static interface IProbabilistic extends Runnable {
public void setScheduler(IProbabilisticScheduler ps);
public IProbabilisticScheduler scheduler();
default void run(IProbabilisticScheduler ps) {
setScheduler(ps);
run();
}
}
static interface Steppable {
public boolean step(); // return false if done
}
static class Scored extends Var {
float score;
Scored() {}
Scored(A a, float score) { super(a); this.score = score; }
Scored(A a, double score) { super(a); this.score = (float) score; }
float score() { return score; }
public String toString() {
return toIntPercent(score) + "%: " + str(get());
}
}
static class Pair implements Comparable> {
A a;
B b;
Pair() {}
Pair(A a, B b) {
this.b = b;
this.a = a;}
public int hashCode() {
return hashCodeFor(a) + 2*hashCodeFor(b);
}
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Pair)) return false;
Pair t = (Pair) o;
return eq(a, t.a) && eq(b, t.b);
}
public String toString() {
return "<" + a + ", " + b + ">";
}
public int compareTo(Pair p) {
if (p == null) return 1;
int i = ((Comparable) a).compareTo(p.a);
if (i != 0) return i;
return ((Comparable) b).compareTo(p.b);
}
}
// TreeSet variant allowing multiple elements which are considered
// equal by the comparator but not by eq().
// All operations O(log n) with n being the number of _different_ elements.
static class TreeSetWithDuplicates extends AbstractSet {
NavigableSet> sets;
Comparator comparator;
int size;
TreeSetWithDuplicates() { this((Comparator) null); }
TreeSetWithDuplicates(Comparator comparator) {
this.comparator = comparator;
sets = new TreeSet>(
comparator == null
? (setA, setB) -> cmp(main.first(setA), main.first(setB))
: (setA, setB) -> comparator.compare(main.first(setA), main.first(setB))
);
}
protected TreeSetWithDuplicates(NavigableSet> sets) {
this.sets = sets;}
/*swappable*/ CompactLinkedHashSet makeInnerSet() {
return new CompactLinkedHashSet();
}
public boolean add(A a) {
var probe = probe(a);
CompactLinkedHashSet found = navigableSet_find(sets, probe);
if (found != null) {
if (!found.add(a)) return false;
} else
sets.add(probe);
++size;
return true;
}
public boolean remove(Object a) {
CompactLinkedHashSet newSet = makeInnerSet();
newSet.add((A) a);
CompactLinkedHashSet found = navigableSet_find(sets, newSet);
if (found == null) return false;
if (l(found) == 1)
sets.remove(found);
else
found.remove(a);
--size;
return true;
}
A first() {
return main.first(main.first(sets));
}
A last() {
var last = sets.last();
return last == null ? null : last.last();
}
public IterableIterator iterator() {
return nestedIterator(sets, __1 -> __1.iterator());
}
public int size() { return size; }
// may return null
Set tiedForFirst() { return main.first(sets); }
CompactLinkedHashSet probe(Object a) {
return addAndReturnCollection(makeInnerSet(), (A) a);
}
public boolean contains(Object a) {
return navigableSet_find(sets, probe(a)) != null;
}
}
static class Var implements IVar, ISetter {
Var() {}
Var(A v) {
this.v = v;}
A v; // you can access this directly if you use one thread
public synchronized void set(A a) {
if (v != a) {
v = a;
notifyAll();
}
}
public synchronized A get() { return v; }
public synchronized boolean has() { return v != null; }
public synchronized void clear() { v = null; }
public String toString() { return str(this.get()); }
}
static class WithProbability extends Var implements Comparable> {
double probability; // assumed between 0 and 1
WithProbability() {}
WithProbability(A a) { this(1, a); }
WithProbability(double probability, A a) { super(a);
this.probability = probability; }
public String toString() {
return "p=" + renderedProbability() + ": " + str(get());
}
String renderedProbability() {
return formatDouble_noLeadingZero(probability, 2);
}
double probability() { return probability; }
public int hashCode() {
return boostHashCombine(main.hashCode(probability), main.hashCode(get()));
}
public boolean equals(Object o) {
if (o instanceof WithProbability) {
return probability == ((WithProbability) o).probability && eq(get(), ((WithProbability) o).get());
}
return false;
}
// Higher probability comes first!
public int compareTo(WithProbability wp) {
return wp == null ? 1
: cmp(wp.probability, probability);
}
}
static interface ISetter {
void set(A a);
}
// -has fast nextElement() and prevElement()
// -design allows for more functions like reordering the list
// -Saves up to 34% in space over LinkedHashSet
// (e.g. 22% for a set of 1,000 Ints)
static class CompactLinkedHashSet extends AbstractSet {
UnsynchronizedCompactHashSet> entries = new UnsynchronizedCompactHashSet();
Entry head, tail;
static class Entry {
A value;
Entry prev, next;
public int hashCode() {
return _hashCode(value);
}
// "magic" equals function for CompactHashSet lookup without temp object
public boolean equals(Object o) {
return o == this || eq(value, o);
}
}
public boolean add(A a) {
if (entries.contains(a)) return false;
Entry n = new Entry();
n.value = a;
n.prev = tail;
if (tail != null) tail.next = n;
tail = n;
if (head == null) head = n;
entries.add(n);
return true;
}
public boolean remove(Object a) {
return remove(entries.find(a));
}
public boolean remove(Entry node) {
if (node == null) return false;
if (node.next != null) node.next.prev = node.prev; else tail = node.prev;
if (node.prev != null) node.prev.next = node.next; else head = node.next;
entries.remove(node);
return true;
}
public int size() { return entries.size(); }
public IterableIterator iterator() {
return new IterableIterator() {
Entry entry = head, prev = null;
public boolean hasNext() { return entry != null; }
public A next() {
A a = entry.value;
prev = entry;
entry = entry.next;
return a;
}
// untested
public void remove() {
if (prev == null) throw new IllegalStateException();
CompactLinkedHashSet.this.remove(prev);
prev = null;
}
};
}
public void clear() {
entries.clear();
head = tail = null;
}
public boolean contains(Object a) {
return entries.contains(a);
}
public A find(Object o) {
Entry e = entries.find(o);
return e == null ? null : e.value;
}
public A prevElement(A a) {
Entry e = entries.find(a);
if (e == null || e.prev == null) return null;
return e.prev.value;
}
public A nextElement(A a) {
Entry e = entries.find(a);
if (e == null || e.next == null) return null;
return e.next.value;
}
public A first() { return head == null ? null : head.value; }
public A last() { return tail == null ? null : tail.value; }
boolean removeIfSame(Object o) {
A value = find(o);
if (value == o) {
remove(value);
return true;
}
return false;
}
}
// you still need to implement hasNext() and next()
static abstract class IterableIterator implements Iterator, Iterable {
public Iterator iterator() {
return this;
}
public void remove() {
unsupportedOperation();
}
}
static interface IVar extends IF0 {
void set(A a);
A get();
default boolean has() { return get() != null; }
default void clear() { set(null); }
}
static interface IF0 {
A get();
}
/*
* #!
* Ontopia Engine
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* !#
*/
// modified by Stefan Reich
// Implements the Set interface more compactly than
// java.util.HashSet by using a closed hashtable.
// Note: equals is always called on the _stored_ object, not the one
// passed as an argument to find(), contains() etc.
// (In case you want to put special magic in your equals() function)
static class UnsynchronizedCompactHashSet extends java.util.AbstractSet {
protected final static int INITIAL_SIZE = 3;
public final static double LOAD_FACTOR = 0.75;
protected final static Object nullObject = new Object();
protected final static Object deletedObject = new Object();
protected int elements;
protected int freecells;
protected A[] objects;
protected int modCount;
UnsynchronizedCompactHashSet() {
this(INITIAL_SIZE);
}
UnsynchronizedCompactHashSet(int size) {
// NOTE: If array size is 0, we get a
// "java.lang.ArithmeticException: / by zero" in add(Object).
objects = (A[]) new Object[(size==0 ? 1 : size)];
elements = 0;
freecells = objects.length;
modCount = 0;
}
UnsynchronizedCompactHashSet(Collection c) {
this(c.size());
addAll(c);
}
@Override
public Iterator iterator() {
return new CompactHashIterator();
}
@Override
public int size() {
return elements;
}
@Override
public boolean isEmpty() {
return elements == 0;
}
@Override
public boolean contains(Object o) {
return find(o) != null;
}
A find(Object o) {
if (o == null) o = nullObject;
int hash = o.hashCode();
int index = (hash & 0x7FFFFFFF) % objects.length;
int offset = 1;
// search for the object (continue while !null and !this object)
while(objects[index] != null &&
!(objects[index].hashCode() == hash &&
objects[index].equals(o))) {
index = ((index + offset) & 0x7FFFFFFF) % objects.length;
offset = offset*2 + 1;
if (offset == -1)
offset = 2;
}
return objects[index];
}
boolean removeIfSame(Object o) {
A value = find(o);
if (value == o) {
remove(value);
return true;
}
return false;
}
@Override
public boolean add(Object o) {
if (o == null) o = nullObject;
int hash = o.hashCode();
int index = (hash & 0x7FFFFFFF) % objects.length;
int offset = 1;
int deletedix = -1;
// search for the object (continue while !null and !this object)
while(objects[index] != null &&
!(objects[index].hashCode() == hash &&
objects[index].equals(o))) {
// if there's a deleted object here we can put this object here,
// provided it's not in here somewhere else already
if (objects[index] == deletedObject)
deletedix = index;
index = ((index + offset) & 0x7FFFFFFF) % objects.length;
offset = offset*2 + 1;
if (offset == -1)
offset = 2;
}
if (objects[index] == null) { // wasn't present already
if (deletedix != -1) // reusing a deleted cell
index = deletedix;
else
freecells--;
modCount++;
elements++;
// here we face a problem regarding generics:
// add(A o) is not possible because of the null Object. We cant do 'new A()' or '(A) new Object()'
// so adding an empty object is a problem here
// If (! o instanceof A) : This will cause a class cast exception
// If (o instanceof A) : This will work fine
objects[index] = (A) o;
// do we need to rehash?
if (1 - (freecells / (double) objects.length) > LOAD_FACTOR)
rehash();
return true;
} else // was there already
return false;
}
@Override
public boolean remove(Object o) {
if (o == null) o = nullObject;
int hash = o.hashCode();
int index = (hash & 0x7FFFFFFF) % objects.length;
int offset = 1;
// search for the object (continue while !null and !this object)
while(objects[index] != null &&
!(objects[index].hashCode() == hash &&
objects[index].equals(o))) {
index = ((index + offset) & 0x7FFFFFFF) % objects.length;
offset = offset*2 + 1;
if (offset == -1)
offset = 2;
}
// we found the right position, now do the removal
if (objects[index] != null) {
// we found the object
// same problem here as with add
objects[index] = (A) deletedObject;
modCount++;
elements--;
return true;
} else
// we did not find the object
return false;
}
@Override
public void clear() {
elements = 0;
for (int ix = 0; ix < objects.length; ix++)
objects[ix] = null;
freecells = objects.length;
modCount++;
}
@Override
public Object[] toArray() {
Object[] result = new Object[elements];
Object[] objects = this.objects;
int pos = 0;
for (int i = 0; i < objects.length; i++)
if (objects[i] != null && objects[i] != deletedObject) {
if (objects[i] == nullObject)
result[pos++] = null;
else
result[pos++] = objects[i];
}
// unchecked because it should only contain A
return result;
}
// not sure if this needs to have generics
@Override
public T[] toArray(T[] a) {
int size = elements;
if (a.length < size)
a = (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);
A[] objects = this.objects;
int pos = 0;
for (int i = 0; i < objects.length; i++)
if (objects[i] != null && objects[i] != deletedObject) {
if (objects[i] == nullObject)
a[pos++] = null;
else
a[pos++] = (T) objects[i];
}
return a;
}
protected void rehash() {
int garbagecells = objects.length - (elements + freecells);
if (garbagecells / (double) objects.length > 0.05)
// rehash with same size
rehash(objects.length);
else
// rehash with increased capacity
rehash(objects.length*2 + 1);
}
protected void rehash(int newCapacity) {
int oldCapacity = objects.length;
@SuppressWarnings("unchecked")
A[] newObjects = (A[]) new Object[newCapacity];
for (int ix = 0; ix < oldCapacity; ix++) {
Object o = objects[ix];
if (o == null || o == deletedObject)
continue;
int hash = o.hashCode();
int index = (hash & 0x7FFFFFFF) % newCapacity;
int offset = 1;
// search for the object
while(newObjects[index] != null) { // no need to test for duplicates
index = ((index + offset) & 0x7FFFFFFF) % newCapacity;
offset = offset*2 + 1;
if (offset == -1)
offset = 2;
}
newObjects[index] = (A) o;
}
objects = newObjects;
freecells = objects.length - elements;
}
private class CompactHashIterator implements Iterator {
private int index;
private int lastReturned = -1;
private int expectedModCount;
@SuppressWarnings("empty-statement")
public CompactHashIterator() {
for (index = 0; index < objects.length &&
(objects[index] == null ||
objects[index] == deletedObject); index++)
;
expectedModCount = modCount;
}
@Override
public boolean hasNext() {
return index < objects.length;
}
@SuppressWarnings("empty-statement")
@Override
public T next() {
/*if (modCount != expectedModCount)
throw new ConcurrentModificationException();*/
int length = objects.length;
if (index >= length) {
lastReturned = -2;
throw new NoSuchElementException();
}
lastReturned = index;
for (index += 1; index < length &&
(objects[index] == null ||
objects[index] == deletedObject); index++)
;
if (objects[lastReturned] == nullObject)
return null;
else
return (T) objects[lastReturned];
}
@Override
public void remove() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (lastReturned == -1 || lastReturned == -2)
throw new IllegalStateException();
// delete object
if (objects[lastReturned] != null && objects[lastReturned] != deletedObject) {
objects[lastReturned] = (A) deletedObject;
elements--;
modCount++;
expectedModCount = modCount; // this is expected; we made the change
}
}
}
int capacity() { return objects.length; }
// returns true if there was a shrink
boolean shrinkToFactor(double factor) {
if (factor > LOAD_FACTOR)
throw fail("Shrink factor must be equal to or smaller than load factor: " + factor + " / " + LOAD_FACTOR);
int newCapacity = max(INITIAL_SIZE, iround(size()/factor));
if (newCapacity >= capacity()) return false;
rehash(newCapacity);
return true;
}
}
static RuntimeException fail() { throw new RuntimeException("fail"); }
static RuntimeException fail(Throwable e) { throw asRuntimeException(e); }
static RuntimeException fail(Object msg) { throw new RuntimeException(String.valueOf(msg)); }
static RuntimeException fail(Object... objects) { throw new Fail(objects); }
static RuntimeException fail(String msg) { throw new RuntimeException(msg == null ? "" : msg); }
static RuntimeException fail(String msg, Throwable innerException) { throw new RuntimeException(msg, innerException); }
static ArrayList byteArrayToList(byte[] a) {
if (a == null) return null;
return byteArrayToList(a, 0, a.length);
}
// no range checking on from/to in the interest of speed
static ArrayList byteArrayToList(byte[] a, int from, int to) {
if (a == null) return null;
ArrayList < Byte > l = new ArrayList<>(to-from);
for (int i = from; i < to; i++) l.add(a[i]);
return l;
}
static String linesLL(Object... x) {
return lines(ll(x));
}
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 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 byte[] byteListToArray(List l) {
if (l == null) return null;
int n = l(l), i = 0;
byte[] a = new byte[n];
for (var x : l)
a[i++] = x;
return a;
}
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 double doubleRatio(double x, double y) {
return y == 0 ? 0 : x/y;
}
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 boolean warn_on = true;
static ThreadLocal> warn_warnings = new ThreadLocal();
static void warn(String s) {
if (warn_on)
print("Warning: " + s);
}
static void warn(String s, List warnings) {
warn(s);
if (warnings != null)
warnings.add(s);
addToCollection(warn_warnings.get(), s);
}
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 byte[] toByteArray(ByteArrayOutputStream baos) {
return baos == null ? null : baos.toByteArray();
}
static byte[] toByteArray(Iterator extends Number> it) {
ByteBuffer buf = new ByteBuffer();
while (it.hasNext())
buf.add((byte) it.next().intValue());
return buf.toByteArray();
}
static byte[] toByteArray(Collection extends Number> it) {
int n = l(it), i = 0;
byte[] a = new byte[n];
for (var x : it)
a[i++] = (byte) x.intValue();
return a;
}
static byte[] toByteArray(Object o) {
if (o == null) return null;
if (o instanceof byte[]) return ((byte[]) o);
if (o instanceof Iterator)
return toByteArray((Iterator) o);
if (o instanceof Collection)
return toByteArray((Collection) ((Collection) o));
// not sure what else to put here
throw fail("toByteArray", o);
}
static Iterator toByteIterator(Object o) {
if (o == null) return null;
if (o instanceof Iterator) return ((Iterator) o);
if (o instanceof Iterable) return iterator((Iterable) o);
if (o instanceof byte[]) return iterator(wrapPrimitiveArrayAsImmutableList((byte[]) o));
throw fail();
}
static void forEach(Iterable l, IVF1 f) {
if (f != null && l != null) for (A a : l)
callF(f, a);
}
static void forEach(IVF1 f, Iterable l) {
forEach(l, f);
}
static void forEach(A[] l, IVF1 f) {
if (f != null && l != null) for (A a : l)
callF(f, a);
}
static void forEach(Map map, IVF2 f) {
for (Map.Entry extends A, ? extends B> __0 : _entrySet( map))
{ A a = __0.getKey(); B b = __0.getValue(); f.get(a, b); }
}
static void stepAll(Steppable s) {
if (s != null) while (s.step()) { ping(); }
}
static boolean isNaN(double d) {
return Double.isNaN(d);
}
static boolean isNaN(float f) {
return Float.isNaN(f);
}
static double minusInfinity() {
return negativeInfinity();
}
static void put(Map map, A a, B b) {
if (map != null) map.put(a, b);
}
static void put(List l, int i, A a) {
if (l != null && i >= 0 && i < l(l)) l.set(i, a);
}
//sbool ping_actions_shareable = true;
static volatile boolean ping_pauseAll = false;
static int ping_sleep = 100; // poll pauseAll flag every 100
static volatile boolean ping_anyActions = false;
static Map ping_actions = newWeakHashMap();
static ThreadLocal ping_isCleanUpThread = new ThreadLocal();
// always returns true
static boolean ping() {
//ifdef useNewPing
newPing();
//endifdef
if (ping_pauseAll || ping_anyActions) ping_impl(true /* XXX */);
//ifndef LeanMode ping_impl(); endifndef
return true;
}
// returns true when it slept
static boolean ping_impl(boolean okInCleanUp) { try {
if (ping_pauseAll && !isAWTThread()) {
do
Thread.sleep(ping_sleep);
while (ping_pauseAll);
return true;
}
if (ping_anyActions) { // don't allow sharing ping_actions
if (!okInCleanUp && !isTrue(ping_isCleanUpThread.get()))
failIfUnlicensed();
Object action = null;
synchronized(ping_actions) {
if (!ping_actions.isEmpty()) {
action = ping_actions.get(currentThread());
if (action instanceof Runnable)
ping_actions.remove(currentThread());
if (ping_actions.isEmpty()) ping_anyActions = false;
}
}
if (action instanceof Runnable)
((Runnable) action).run();
else if (eq(action, "cancelled"))
throw fail("Thread cancelled.");
}
return false;
} catch (Exception __e) { throw rethrow(__e); } }
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