Warning : session_start(): open(/var/lib/php/sessions/sess_a0m578md7cp2fj81f7k4j4pnlf, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning : session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
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 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.*;
public class main {
static class Puzzler {
List remainingTokens = new ArrayList();
List numbers = new ArrayList();
List vars = new ArrayList();
Puzzler(String tokens) {
for (String s : codeTokens(javaTok(tokens)))
if (eq(s, "i") || eq(s, "j"))
vars.add(s);
else if (isInteger(s))
numbers.add(s);
else
remainingTokens.add(s);
}
String var() {
return oneOf(vars);
}
String exp() {
/*int i = random(2);
S s = "?";
switch (i) {
case 0: s = "0";
case 1: s = "9";
}*/
String s = oneOf(concatLists(numbers, vars));
if (random(3) == 0) s = "get(" + s + ")";
return s;
}
String swap() {
return "swap(" + exp() + ", " + exp() + ")\n";
}
String _for() {
return "for " + var() + " = " + exp() + " to " + exp() + "-1\n"
+ indentx(code())
+ "end\n";
}
String ifless() {
return "if " + exp() + " < " + exp() + " then\n"
+ indentx(code())
+ "end\n";
}
String code() {
String s = choose("swap", "for", "ifless");
if (s == null) return "";
return (String) call(this, eq(s, "for") ? "_for" : s);
/*if (eq(s, "swap"))
ret swap();
if (eq(s, "for"))
ret for();*/
}
String choose(String... options) {
List l = new ArrayList();
for (String s : options)
if (remainingTokens.contains(s))
l.add(s);
String choice = oneOf(l);
if (choice != null)
remainingTokens.remove(choice);
return choice;
}
}
// Puzzler for Bubblesort
static class Grid {
int[] mem = new int[0];
void set(int addr, int x) {
if (addr < 0) return;
expandTo(addr);
mem[addr] = x;
}
void set(int addr, int[] x) {
for (int i = l(x)-1; i >= 0; i--)
set(addr+i, x[i]);
}
int get(int addr) {
if (addr < 0 || addr >= l(mem))
return 0;
return mem[addr];
}
void expandTo(int n) {
if (n >= l(mem)) {
int[] m = new int[max(n+1, l(mem)*2)];
arraycopy(mem, 0, m, 0, l(mem));
mem = m;
}
}
int lastNonZero() {
int i = l(mem)-1;
while (i > 0 && get(i) == 0) --i;
return i;
}
int[] getRange(int a, int b) {
return subArray(mem, a, b);
}
}
// opcodes
static final int
op_return = 0,
op_nop = 1,
op_jump = 2,
op_jump_rel = 16,
op_branchif = 3,
op_branchifnot = 4,
op_less = 5,
op_less_im = 17, // highest
op_equal = 6,
op_more = 7,
op_set = 8,
op_set_ind = 9,
op_copy = 10,
op_copy_ind = 11,
op_add = 12,
op_add_im = 13,
op_not = 14,
op_neg = 15,
op_illegal = 999;
static int runProgram_maxSteps = 1000*1000;
static void runProgram(Grid g, int pc) {
new Runner(g, pc, runProgram_maxSteps);
}
static class Runner {
Grid g;
int pc;
Runner(Grid g, int startAddress, int steps) {
this.g = g;
pc = startAddress;
boolean flag = false;
for (int step = 0; step < steps; step++) {
int opcode = g.get(pc++);
int a, b;
switch (opcode) {
case op_return: return;
case op_nop:
break; case op_jump: pc = g.get(pc);
break; case op_jump_rel: pc += g.get(pc)-1;
break; case op_branchif: if (flag) pc = g.get(pc); else ++pc;
break; case op_branchifnot: if (!flag) pc = g.get(pc); else ++pc;
break; case op_less: a = y(); b = y(); flag = a < b;
break; case op_less_im: a = y(); b = x(); flag = a < b;
break; case op_equal: a = y(); b = y(); flag = a == b;
break; case op_more: a = y(); b = y(); flag = a > b;
break; case op_set: a = x(); set(x(), a);
break; case op_set_ind: a = x(); set(y(), a);
break; case op_copy: a = y(); set(x(), a);
break; case op_copy_ind: a = y(); set(y(), a);
break; case op_add: a = x(); b = x(); set(a, get(a)+get(b));
break; case op_add_im: a = x(); b = x(); set(a, get(a)+b);
break; case op_not: a = x(); set(a, ~get(a));
break; case op_neg: a = x(); set(a, -get(a));
default: fail("Illegal opcode " + opcode + " at " + (pc-1));
}
}
}
int x() { return get(pc++); }
int y() { return get(get(pc++)); }
int get(int addr) { return g.get(addr); }
void set(int addr, int x) { g.set(addr, x); }
}
static void testProgram(Grid g, int startAddress, int... values) {
runProgram(g, startAddress);
for (int i = 0; i < l(values); i += 2)
assertEquals(values[i+1], g.get(values[i]));
//print("Program OK (" + n(l(program), "int") + ", " + n(l(values)/2, "value") + ")");
print("Program OK (" + n(l(values)/2, "value") + ")");
}
static void disassemble(Grid g, int pc) {
print(new Disassembler(g, pc).buf);
}
static class Disassembler {
Grid g;
int pc;
StringBuffer buf = new StringBuffer();
Disassembler(Grid g, int startAddress) {
this.g = g;
pc = startAddress;
int end = g.lastNonZero();
while (pc < end) {
int opcode = g.get(pc++);
int a, b;
String s = "?";
switch (opcode) {
case op_return: s = "return";
break; case op_nop: s = "nop";
break; case op_jump: s = "jump " + x();
break; case op_jump_rel: s = "jump rel " + x();
break; case op_branchif: s = "branch if " + x();
break; case op_branchifnot: s = "branch if not " + x();
break; case op_less: a = x(); b = x(); s = "less " + a + " " + b;
break; case op_less_im: a = x(); b = x(); s = "less im " + a + " " + b;
break; case op_equal: a = x(); b = x(); s = "equal " + a + " " + b;
break; case op_more: a = x(); b = x(); s = "more " + a + " " + b;
break; case op_set: a = x(); b = x(); s = "set " + a + " " + b;
break; case op_set_ind: a = x(); b = x(); s = "set ind " + a + " " + b;
break; case op_copy: a = x(); b = x(); s = "copy " + a + " " + b;
break; case op_copy_ind: a = x(); b = x(); s = "copy ind " + a + " " + b;
break; case op_add: a = x(); b = x(); s = "add " + a + " " + b;
break; case op_add_im: a = x(); b = x(); s = "add im " + a + " " + b;
break; case op_not: s = "not " + x();
break; case op_neg: s = "neg " + x();
default: s = "Unknown opcode " + opcode;
}
buf.append(s).append("\n");
}
}
int x() { return g.get(pc++); }
} // Assembly Machine
static class HighLevel {
Grid g;
int pc, startAddress;
Map vars = new TreeMap();
HighLevel(Grid g, int pc) {
this.pc = pc;
this.g = g; startAddress = pc; }
HighLevel(int pc) {
this.pc = pc; startAddress = pc; g = new Grid(); }
void emit(int... blubb) {
g.set(pc, blubb);
pc += l(blubb);
}
int newvar() {
emit(op_jump_rel, 3);
int addr = pc;
emit(0);
return addr;
}
int getvar(String name) {
Integer bla = vars.get(name);
if (bla == null)
vars.put(name, bla = newvar());
return bla;
}
// for (; i < to; i++) (to = im value)
class ForIm {
int var, loop, patch;
ForIm(int var, int to) {
this.var = var;
loop = pc;
emit(op_less_im, var, to);
patch = patch(op_branchifnot);
}
void end() {
emit(op_add_im, var, 1);
emit(op_jump, loop);
g.set(patch, pc);
}
}
int patch(int opcode) {
emit(opcode, 0);
return pc-1;
}
int[] getProgram() {
return g.getRange(startAddress, g.lastNonZero()+1);
}
void set(int x, String val) {
if (isInteger(val))
emit(op_set, parseInt(val), x);
else if (isIdentifier(val))
emit(op_copy, getvar(val), x);
else
fail(val);
}
} // HighLevel
static int[] makeProgram(int startAddress) {
String code = new Puzzler("0 10 i j for for ifless swap").code();
HighLevel h = new HighLevel(startAddress);
compile(code, h);
return h.getProgram();
}
static void compile(String code, HighLevel h) {
List stack = new ArrayList();
Matches m = new Matches();
for (String line : toLinesFullTrim(code)) {
if (flexMatch("if * < * then", line)) {
stack.add(h.new IfLess(m.get(0), m.get(1)));
} else if (flexMatch("for * = * to *-1", line, m)) {
// push for
int var = h.getvar(m.get(0));
h.set(var, m.get(1));
stack.add(h.new ForIm(var, parseInt(m.get(2))));
} else if (flexMatch("end", line)) {
Object x = liftLast(stack);
call(x, "end");
} else if (flexMatch("swap(*, *)", line)) {
h.swap(m.get(0), m.get(1));
} else
fail("bad instruction: " + line);
}
}
static boolean isIdentifier(String s) {
return isJavaIdentifier(s);
}
static void set(Object o, String field, Object value) {
if (o instanceof Class) set((Class) o, field, value);
else try {
Field f = set_findField(o.getClass(), field);
smartSet(f, o, value);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static void set(Class c, String field, Object value) {
try {
Field f = set_findStaticField(c, field);
smartSet(f, null, value);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field set_findField(Class> c, String field) {
for (Field f : c.getDeclaredFields())
if (f.getName().equals(field))
return f;
throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static Field set_findStaticField(Class> c, String field) {
for (Field f : c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
return f;
throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static A liftLast(List l) {
if (l.isEmpty()) return null;
int i = l(l)-1;
A a = l.get(i);
l.remove(i);
return a;
}
static List codeTokens(List tok) {
return codeTokensOnly(tok);
}
static boolean flexMatch_debug;
static boolean flexMatch(String pat, String s) {
return flexMatch(pat, s, null);
}
static boolean flexMatch(String pat, String s, Matches m) {
List tokpat = codeTokens(javaTok(pat));
List tokfull = joinBrackets(javaTok(s));
List tok = codeTokens(tokfull);
BitSet bla = new BitSet();
if (!flexMatch_impl(tokpat, 0, tok, 0, bla)) return false;
if (m != null) {
List l = new ArrayList();
for (int i = 1; i < l(tokfull); i += 2) {
if (bla.get(i/2)) {
int j = i;
while (j < l(tokfull) && bla.get(j/2)) j += 2;
l.add(join(subList(tokfull, i, j-1)));
i = j-2;
}
}
m.m = toStringArray(l);
}
return true;
}
static boolean flexMatch_impl(List pat, int ipat, List tok, int itok, BitSet bla) {
if (flexMatch_debug)
print("flexMatch " + structure(subList(pat, ipat)) + " " + structure(subList(tok, itok)) + " " + structure(bla));
if (ipat >= l(pat))
return itok >= l(tok);
String t = pat.get(ipat);
if (eq(t, "*"))
if (itok >= l(tok)) // nothing to consume - just advance in pattern
return flexMatch_impl(pat, ipat+1, tok, itok, bla);
else { // something to consume - try both continuing and ending to fill "*"
bla.set(itok);
if (flexMatch_impl(pat, ipat, tok, itok+1, bla)
|| flexMatch_impl(pat, ipat+1, tok, itok+1, bla))
return true; // success, leave mark
bla.clear(itok); // fail, undo marking
return false;
}
if (itok >= l(tok)) {
if (flexMatch_debug)
print("too much pattern");
return false;
}
if (neq(tok.get(itok), t)) {
if (flexMatch_debug)
print("mismatch");
return false;
}
// ok, consume and proceed
return flexMatch_impl(pat, ipat+1, tok, itok+1, bla);
}
static int max(int a, int b) {
return Math.max(a, b);
}
static long max(int a, long b) {
return Math.max((long) a, b);
}
static long max(long a, long b) {
return Math.max(a, b);
}
static double max(int a, double b) {
return Math.max((double) a, b);
}
static int max(Collection c) {
int x = Integer.MIN_VALUE;
for (int i : c) x = max(x, i);
return x;
}
static double max(double[] c) {
if (c.length == 0) return Double.MIN_VALUE;
double x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
// replacement for class JavaTok
// maybe incomplete, might want to add floating point numbers
// todo also: extended multi-line strings
static List javaTok(String s) {
List tok = new ArrayList();
int l = s.length();
int i = 0;
while (i < l) {
int j = i;
char c; String cc;
// scan for whitespace
while (j < l) {
c = s.charAt(j);
cc = s.substring(j, Math.min(j+2, l));
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
++j;
else if (cc.equals("/*")) {
do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/"));
j = Math.min(j+2, l);
} else if (cc.equals("//")) {
do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0);
} else
break;
}
tok.add(s.substring(i, j));
i = j;
if (i >= l) break;
c = s.charAt(i); // cc is not needed in rest of loop body
cc = s.substring(i, Math.min(i+2, l));
// scan for non-whitespace
if (c == '\'' || c == '"') {
char opener = c;
++j;
while (j < l) {
if (s.charAt(j) == opener || s.charAt(j) == '\n') { // end at \n to not propagate unclosed string literal errors
++j;
break;
} else if (s.charAt(j) == '\\' && j+1 < l)
j += 2;
else
++j;
}
} else if (Character.isJavaIdentifierStart(c))
do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't"
else if (Character.isDigit(c)) {
do ++j; while (j < l && Character.isDigit(s.charAt(j)));
if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L
} else if (cc.equals("[[")) {
do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]"));
j = Math.min(j+2, l);
} else if (cc.equals("[=") && i+2 < l && s.charAt(i+2) == '[') {
do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]"));
j = Math.min(j+3, l);
} else
++j;
tok.add(s.substring(i, j));
i = j;
}
if ((tok.size() % 2) == 0) tok.add("");
return tok;
}
static List javaTok(List tok) {
return javaTok(join(tok));
}
static void assertEquals(Object x, Object y) {
assertEquals(null, x, y);
}
static void assertEquals(String msg, Object x, Object y) {
if (!(x == null ? y == null : x.equals(y)))
fail((msg != null ? msg + ": " : "") + structure(x) + " != " + structure(y));
}
static boolean eq(Object a, Object b) {
if (a == null) return b == null;
if (a.equals(b)) return true;
if (a instanceof BigInteger) {
if (b instanceof Integer) return a.equals(BigInteger.valueOf((Integer) b));
if (b instanceof Long) return a.equals(BigInteger.valueOf((Long) b));
}
return false;
}
static int l(Object[] array) {
return array == null ? 0 : array.length;
}
static int l(byte[] array) {
return array == null ? 0 : array.length;
}
static int l(int[] array) {
return array == null ? 0 : array.length;
}
static int l(char[] array) {
return array == null ? 0 : array.length;
}
static int l(Collection c) {
return c == null ? 0 : c.size();
}
static int l(Map m) {
return m == null ? 0 : m.size();
}
static int l(String s) {
return s == null ? 0 : s.length();
}
static String n(long l, String name) {
return l + " " + (l == 1 ? name : getPlural(name));
}
// varargs assignment fixer for a single string array argument
static Object call(Object o, String method, String[] arg) {
return call(o, method, new Object[] {arg});
}
static Object call(Object o, String method, Object... args) {
try {
if (o instanceof Class) {
Method m = call_findStaticMethod((Class) o, method, args, false);
m.setAccessible(true);
return m.invoke(null, args);
} else {
Method m = call_findMethod(o, method, args, false);
m.setAccessible(true);
return m.invoke(o, args);
}
} catch (Exception e) {
throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
}
}
static Method call_findStaticMethod(Class c, String method, Object[] args, boolean debug) {
Class _c = c;
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (debug)
System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
if (!m.getName().equals(method)) {
if (debug) System.out.println("Method name mismatch: " + method);
continue;
}
if ((m.getModifiers() & Modifier.STATIC) == 0 || !call_checkArgs(m, args, debug))
continue;
return m;
}
c = c.getSuperclass();
}
throw new RuntimeException("Method '" + method + "' (static) with " + args.length + " parameter(s) not found in " + _c.getName());
}
static Method call_findMethod(Object o, String method, Object[] args, boolean debug) {
Class c = o.getClass();
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (debug)
System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
if (m.getName().equals(method) && call_checkArgs(m, args, debug))
return m;
}
c = c.getSuperclass();
}
throw new RuntimeException("Method '" + method + "' (non-static) with " + args.length + " parameter(s) not found in " + o.getClass().getName());
}
private static boolean call_checkArgs(Method m, Object[] args, boolean debug) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length) {
if (debug)
System.out.println("Bad parameter length: " + args.length + " vs " + types.length);
return false;
}
for (int i = 0; i < types.length; i++)
if (!(args[i] == null || isInstanceX(types[i], args[i]))) {
if (debug)
System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]);
return false;
}
return true;
}
static int parseInt(String s) {
return empty(s) ? 0 : Integer.parseInt(s);
}
static int random(int n) {
return new Random().nextInt(n);
}
static RuntimeException fail() {
throw new RuntimeException("fail");
}
static RuntimeException fail(Object msg) {
throw new RuntimeException(String.valueOf(msg));
}
static RuntimeException fail(String msg) {
throw new RuntimeException(unnull(msg));
}
static RuntimeException fail(String msg, Object... args) {
throw new RuntimeException(format(msg, args));
}
static boolean isInteger(String s) {
return s != null && Pattern.matches("\\-?\\d+", s);
}
static A oneOf(List l) {
return l.isEmpty() ? null : l.get(new Random().nextInt(l.size()));
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static volatile StringBuffer 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 void print() {
print("");
}
// slightly overblown signature to return original object...
static A print(A o) {
String s = String.valueOf(o) + "\n";
StringBuffer loc = local_log;
StringBuffer buf = print_log;
int loc_max = print_log_max;
if (buf != loc && buf != null) {
print_append(buf, s, print_log_max);
loc_max = local_log_max;
}
if (loc != null)
print_append(loc, s, loc_max);
System.out.print(s);
return o;
}
static void print(long l) {
print(String.valueOf(l));
}
static void print_append(StringBuffer buf, String s, int max) {
synchronized(buf) {
buf.append(s);
max /= 2;
if (buf.length() > max) try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
}
}
static List toLinesFullTrim(String s) {
List l = toLines(s);
for (ListIterator i = l.listIterator(); i.hasNext(); ) {
String line = i.next().trim();
if (line.length() == 0)
i.remove();
else
i.set(line);
}
return l;
}
static List concatLists(List ... lists) {
List l = new ArrayList ();
for (List list : lists)
if (list != null)
l.addAll(list);
return l;
}
static List concatLists(Collection> lists) {
List l = new ArrayList ();
for (List list : lists)
if (list != null)
l.addAll(list);
return l;
}
static void arraycopy(Object[] a, Object[] b) {
int n = min(a.length, b.length);
for (int i = 0; i < n; i++)
b[i] = a[i];
}
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int n) {
System.arraycopy(src, srcPos, dest, destPos, n);
}
// get purpose 1: access a list/array (safer version of x.get(y))
static A get(List l, int idx) {
return idx >= 0 && idx < l(l) ? l.get(idx) : null;
}
static A get(A[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : null;
}
// get purpose 2: access a field by reflection or a map
static Object get(Object o, String field) {
if (o instanceof Class) return get((Class) o, field);
if (o instanceof Map)
return ((Map) o).get(field);
if (o.getClass().getName().equals("main$DynamicObject"))
return call(get_raw(o, "fieldValues"), "get", field);
return get_raw(o, field);
}
static Object get_raw(Object o, String field) {
try {
Field f = get_findField(o.getClass(), field);
f.setAccessible(true);
return f.get(o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Object get(Class c, String field) {
try {
Field f = get_findStaticField(c, field);
f.setAccessible(true);
return f.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field get_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field get_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static String indentx(String s) {
return dropSuffix(repeat(' ', indent_default), indent(indent_default, s));
}
static int[] subArray(int[] b, int start, int end) {
int[] x = new int[end-start];
System.arraycopy(b, start, x, 0, end-start);
return x;
}
static int indent_default = 2;
static String indent(int indent) {
return repeat(' ', indent);
}
static String indent(int indent, String s) {
return indent(repeat(' ', indent), s);
}
static String indent(String indent, String s) {
return indent + s.replace("\n", "\n" + indent);
}
static String indent(String s) {
return indent(indent_default, s);
}
static List indent(String indent, List lines) {
List l = new ArrayList();
for (String s : lines)
l.add(indent + s);
return l;
}
static String unnull(String s) {
return s == null ? "" : s;
}
static List unnull(List l) {
return l == null ? emptyList() : l;
}
static boolean empty(Collection c) {
return isEmpty(c);
}
static boolean empty(String s) {
return isEmpty(s);
}
static boolean empty(Map map) {
return map == null || map.isEmpty();
}
static int min(int a, int b) {
return Math.min(a, b);
}
static double min(double[] c) {
double x = Double.MAX_VALUE;
for (double d : c) x = Math.min(x, d);
return x;
}
static String repeat(char c, int n) {
n = max(n, 0);
char[] chars = new char[n];
for (int i = 0; i < n; i++)
chars[i] = c;
return new String(chars);
}
static List repeat(A a, int n) {
List l = new ArrayList ();
for (int i = 0; i < n; i++)
l.add(a);
return l;
}
static List toLines(File f) {
return toLines(loadTextFile(f));
}
public static List toLines(String s) {
List lines = new ArrayList();
if (s == null) return lines;
int start = 0;
while (true) {
int i = toLines_nextLineBreak(s, start);
if (i < 0) {
if (s.length() > start) lines.add(s.substring(start));
break;
}
lines.add(s.substring(start, i));
if (s.charAt(i) == '\r' && i+1 < s.length() && s.charAt(i+1) == '\n')
i += 2;
else
++i;
start = i;
}
return lines;
}
private static int toLines_nextLineBreak(String s, int start) {
for (int i = start; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '\r' || c == '\n')
return i;
}
return -1;
}
public static String join(String glue, Iterable strings) {
StringBuilder buf = new StringBuilder();
Iterator i = strings.iterator();
if (i.hasNext()) {
buf.append(i.next());
while (i.hasNext())
buf.append(glue).append(i.next());
}
return buf.toString();
}
public static String join(String glue, String[] strings) {
return join(glue, Arrays.asList(strings));
}
public static String join(Iterable strings) {
return join("", strings);
}
public static String join(String[] strings) {
return join("", strings);
}
static boolean neq(Object a, Object b) {
return !eq(a, b);
}
// extended over Class.isInstance() to handle primitive types
static boolean isInstanceX(Class type, Object arg) {
if (type == boolean.class) return arg instanceof Boolean;
if (type == int.class) return arg instanceof Integer;
if (type == long.class) return arg instanceof Long;
if (type == float.class) return arg instanceof Float;
if (type == short.class) return arg instanceof Short;
if (type == char.class) return arg instanceof Character;
if (type == byte.class) return arg instanceof Byte;
if (type == double.class) return arg instanceof Double;
return type.isInstance(arg);
}
static List subList(List l, int startIndex) {
return subList(l, startIndex, l(l));
}
static List subList(List l, int startIndex, int endIndex) {
startIndex = max(0, min(l(l), startIndex));
endIndex = max(0, min(l(l), endIndex));
if (startIndex > endIndex) return litlist();
return l.subList(startIndex, endIndex);
}
static String getPlural(String s) {
if (s.endsWith("y")) return dropSuffix("y", s) + "ies";
return s + "s";
}
static List codeTokensOnly(List tok) {
List l = new ArrayList();
for (int i = 1; i < tok.size(); i += 2)
l.add(tok.get(i));
return l;
}
static String format(String pat, Object... args) {
return format3(pat, args);
}
static String dropSuffix(String suffix, String s) {
return s.endsWith(suffix) ? s.substring(0, l(s)-l(suffix)) : s;
}
static void smartSet(Field f, Object o, Object value) throws Exception {
f.setAccessible(true);
// take care of common case (long to int)
if (f.getType() == int.class && value instanceof Long)
value = ((Long) value).intValue();
f.set(o, value);
}
static List joinBrackets(List tok) {
List t = new ArrayList();
Map map = getBracketMap(tok);
for (int i = 0; i < l(tok); i++) {
Integer dest = map.get(i);
if (dest != null) {
t.add(join(subList(tok, i, dest+1)));
i = dest;
} else
t.add(tok.get(i));
}
return t;
}
static String[] toStringArray(List list) {
return list.toArray(new String[list.size()]);
}
static String[] toStringArray(Object o) {
if (o instanceof String[])
return (String[]) o;
else if (o instanceof List)
return toStringArray((List) o);
else
throw fail("Not a list or array: " + structure(o));
}
static String structure(Object o) {
HashSet refd = new HashSet();
return structure_2(structure_1(o, 0, new IdentityHashMap(), refd), refd);
}
// leave to false, unless unstructure() breaks
static boolean structure_allowShortening = false;
static String structure_1(Object o, int stringSizeLimit, IdentityHashMap seen, HashSet refd) {
if (o == null) return "null";
// these are never back-referenced (for readability)
if (o instanceof String)
return quote(stringSizeLimit != 0 ? shorten((String) o, stringSizeLimit) : (String) o);
if (o instanceof BigInteger)
return "bigint(" + o + ")";
if (o instanceof Double)
return "d(" + quote(str(o)) + ")";
if (o instanceof Long)
return o + "L";
if (o instanceof Integer)
return str(o);
if (o instanceof Boolean)
return ((Boolean) o).booleanValue() ? "t" : "f";
Integer ref = seen.get(o);
if (ref != null) {
refd.add(ref);
return "r" + ref;
}
ref = seen.size()+1;
seen.put(o, ref);
String r = "m" + ref + " "; // marker
String name = o.getClass().getName();
StringBuilder buf = new StringBuilder();
if (o instanceof HashSet)
return r + "hashset " + structure_1(new ArrayList((Set) o), stringSizeLimit, seen, refd);
if (o instanceof TreeSet)
return r + "treeset " + structure_1(new ArrayList((Set) o), stringSizeLimit, seen, refd);
if (o instanceof Collection) {
for (Object x : (Collection) o) {
if (buf.length() != 0) buf.append(", ");
buf.append(structure_1(x, stringSizeLimit, seen, refd));
}
return r + "[" + buf + "]";
}
if (o instanceof Map) {
for (Object e : ((Map) o).entrySet()) {
if (buf.length() != 0) buf.append(", ");
buf.append(structure_1(((Map.Entry) e).getKey(), stringSizeLimit, seen, refd));
buf.append("=");
buf.append(structure_1(((Map.Entry) e).getValue(), stringSizeLimit, seen, refd));
}
return r + (o instanceof HashMap ? "hashmap" : "") + "{" + buf + "}";
}
if (o.getClass().isArray()) {
int n = Array.getLength(o);
for (int i = 0; i < n; i++) {
if (buf.length() != 0) buf.append(", ");
buf.append(structure_1(Array.get(o, i), stringSizeLimit, seen, refd));
}
return r + "array{" + buf + "}";
}
if (o instanceof Class)
return r + "class(" + quote(((Class) o).getName()) + ")";
if (o instanceof Throwable)
return r + "exception(" + quote(((Throwable) o).getMessage()) + ")";
if (o instanceof BitSet) {
BitSet bs = (BitSet) o;
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
if (buf.length() != 0) buf.append(", ");
buf.append(i);
}
return "bitset{" + buf + "}";
}
// Need more cases? This should cover all library classes...
if (name.startsWith("java.") || name.startsWith("javax."))
return r + String.valueOf(o);
String shortName = o.getClass().getName().replaceAll("^main\\$", "");
if (shortName.equals("Lisp")) {
buf.append("l(" + structure_1(getOpt(o, "head"), stringSizeLimit, seen, refd));
List args = (List) ( getOpt(o, "args"));
if (nempty(args))
for (int i = 0; i < l(args); i++) {
buf.append(", ");
Object arg = args.get(i);
// sweet shortening
if (arg != null && eq(arg.getClass().getName(), "main$Lisp") && isTrue(call(arg, "isEmpty")))
arg = get(arg, "head");
buf.append(structure_1(arg, stringSizeLimit, seen, refd));
}
buf.append(")");
return r + str(buf);
}
int numFields = 0;
String fieldName = "";
if (shortName.equals("DynamicObject")) {
shortName = (String) get(o, "className");
Map fieldValues = (Map) get(o, "fieldValues");
for (String _fieldName : fieldValues.keySet()) {
fieldName = _fieldName;
Object value = fieldValues.get(fieldName);
if (value != null) {
if (buf.length() != 0) buf.append(", ");
buf.append(fieldName + "=" + structure_1(value, stringSizeLimit, seen, refd));
}
++numFields;
}
} else {
// regular class
Class c = o.getClass();
while (c != Object.class) {
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
if ((field.getModifiers() & Modifier.STATIC) != 0)
continue;
fieldName = field.getName();
// skip outer object reference
if (fieldName.indexOf("$") >= 0) continue;
Object value;
try {
field.setAccessible(true);
value = field.get(o);
} catch (Exception e) {
value = "?";
}
// put special cases here...
if (value != null) {
if (buf.length() != 0) buf.append(", ");
buf.append(fieldName + "=" + structure_1(value, stringSizeLimit, seen, refd));
}
++numFields;
}
c = c.getSuperclass();
}
}
String b = buf.toString();
if (numFields == 1 && structure_allowShortening)
b = b.replaceAll("^" + fieldName + "=", ""); // drop field name if only one
String s = shortName;
if (buf.length() != 0)
s += "(" + b + ")";
return r + s;
}
// drop unused markers
static String structure_2(String s, HashSet refd) {
List tok = javaTok(s);
StringBuilder out = new StringBuilder();
for (int i = 1; i < l(tok); i += 2) {
String t = tok.get(i);
if (t.startsWith("m") && isInteger(t.substring(1))
&& !refd.contains(parseInt(t.substring(1))))
continue;
out.append(t).append(tok.get(i+1));
}
return str(out);
}
static boolean isJavaIdentifier(String s) {
if (s.length() == 0 || !Character.isJavaIdentifierStart(s.charAt(0)))
return false;
for (int i = 1; i < s.length(); i++)
if (!Character.isJavaIdentifierPart(s.charAt(i)))
return false;
return true;
}
static String format3(String pat, Object... args) {
if (args.length == 0) return pat;
List tok = javaTokPlusPeriod(pat);
int argidx = 0;
for (int i = 1; i < tok.size(); i += 2)
if (tok.get(i).equals("*"))
tok.set(i, format3_formatArg(argidx < args.length ? args[argidx++] : "null"));
return join(tok);
}
static String format3_formatArg(Object arg) {
if (arg == null) return "null";
if (arg instanceof String) {
String s = (String) arg;
return isIdentifier(s) || isNonNegativeInteger(s) ? s : quote(s);
}
if (arg instanceof Integer || arg instanceof Long) return String.valueOf(arg);
return quote(structure(arg));
}
static Map getBracketMap(List tok) {
Map map = new HashMap();
List stack = new ArrayList();
for (int i = 1; i < l(tok); i+= 2) {
if (litlist("{", "(").contains(tok.get(i)))
stack.add(i);
else if (litlist("}", ")").contains(tok.get(i))) {
if (!empty(stack))
map.put(liftLast(stack), i);
}
}
return map;
}
static String quote(String s) {
if (s == null) return "null";
return "\"" + s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\r", "\\r").replace("\n", "\\n") + "\"";
}
static String quote(long l) {
return quote("" + l);
}
static String quote(char c) {
return quote("" + c);
}
static String shorten(String s, int max) {
if (s == null) return "";
return s.length() <= max ? s : s.substring(0, Math.min(s.length(), max)) + "...";
}
static String str(Object o) {
return String.valueOf(o);
}
static List emptyList() {
return Collections.emptyList();
}
static ArrayList litlist(A... a) {
return new ArrayList (Arrays.asList(a));
}
public static String loadTextFile(String fileName) {
try {
return loadTextFile(fileName, null);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String loadTextFile(String fileName, String defaultContents) throws IOException {
if (!new File(fileName).exists())
return defaultContents;
FileInputStream fileInputStream = new FileInputStream(fileName);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
return loadTextFile(inputStreamReader);
}
public static String loadTextFile(File fileName) {
try {
return loadTextFile(fileName, null);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String loadTextFile(File fileName, String defaultContents) throws IOException {
try {
return loadTextFile(fileName.getPath(), defaultContents);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String loadTextFile(Reader reader) throws IOException {
StringBuilder builder = new StringBuilder();
try {
char[] buffer = new char[1024];
int n;
while (-1 != (n = reader.read(buffer)))
builder.append(buffer, 0, n);
} finally {
reader.close();
}
return builder.toString();
}
static boolean isEmpty(Collection c) {
return c == null || c.isEmpty();
}
static boolean isEmpty(String s) {
return s == null || s.length() == 0;
}
static boolean nempty(Collection c) {
return !isEmpty(c);
}
static boolean nempty(String s) {
return !isEmpty(s);
}
static boolean isTrue(Object o) {
return booleanValue(o);
}
static Object getOpt(Object o, String field) {
if (o instanceof String) o = getBot ((String) o);
if (o == null) return null;
if (o instanceof Class) return getOpt((Class) o, field);
if (o.getClass().getName().equals("main$DynamicObject"))
return call(getOpt_raw(o, "fieldValues"), "get", field);
if (o instanceof Map) return ((Map) o).get(field);
return getOpt_raw(o, field);
}
static Object getOpt_raw(Object o, String field) {
try {
Field f = getOpt_findField(o.getClass(), field);
if (f == null) return null;
f.setAccessible(true);
return f.get(o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Object getOpt(Class c, String field) {
try {
Field f = getOpt_findStaticField(c, field);
if (f == null) return null;
f.setAccessible(true);
return f.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field getOpt_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static Field getOpt_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static Object getBot(String botID) {
return call(getMainBot(), "getBot", botID);
}
static boolean isNonNegativeInteger(String s) {
return s != null && Pattern.matches("\\d+", s);
}
// This is made for NL parsing.
// It's javaTok extended with "..." token, "$n" and "#n" and
// special quotes (which are converted to normal ones).
static List javaTokPlusPeriod(String s) {
List tok = new ArrayList();
int l = s.length();
int i = 0;
while (i < l) {
int j = i;
char c; String cc;
// scan for whitespace
while (j < l) {
c = s.charAt(j);
cc = s.substring(j, Math.min(j+2, l));
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
++j;
else if (cc.equals("/*")) {
do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/"));
j = Math.min(j+2, l);
} else if (cc.equals("//")) {
do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0);
} else
break;
}
tok.add(s.substring(i, j));
i = j;
if (i >= l) break;
c = s.charAt(i);
cc = s.substring(i, Math.min(i+2, l));
// scan for non-whitespace
if (c == '\u201C' || c == '\u201D') c = '"'; // normalize quotes
if (c == '\'' || c == '"') {
char opener = c;
++j;
while (j < l) {
char _c = s.charAt(j);
if (_c == '\u201C' || _c == '\u201D') _c = '"'; // normalize quotes
if (_c == opener) {
++j;
break;
} else if (s.charAt(j) == '\\' && j+1 < l)
j += 2;
else
++j;
}
if (j-1 >= i+1) {
tok.add(opener + s.substring(i+1, j-1) + opener);
i = j;
continue;
}
} else if (Character.isJavaIdentifierStart(c))
do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || s.charAt(j) == '\'')); // for things like "this one's"
else if (Character.isDigit(c))
do ++j; while (j < l && Character.isDigit(s.charAt(j)));
else if (cc.equals("[[")) {
do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]"));
j = Math.min(j+2, l);
} else if (cc.equals("[=") && i+2 < l && s.charAt(i+2) == '[') {
do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]"));
j = Math.min(j+3, l);
} else if (s.substring(j, Math.min(j+3, l)).equals("..."))
j += 3;
else if (c == '$' || c == '#')
do ++j; while (j < l && Character.isDigit(s.charAt(j)));
else
++j;
tok.add(s.substring(i, j));
i = j;
}
if ((tok.size() % 2) == 0) tok.add("");
return tok;
}
static boolean booleanValue(Object o) {
return eq(true, o);
}
static Object mainBot;
static Object getMainBot() {
return mainBot;
}
static class Matches {
String[] m;
String get(int i) { return m[i]; }
String unq(int i) { return unquote(m[i]); }
String fsi(int i) { return formatSnippetID(unq(i)); }
String fsi() { return fsi(0); }
String tlc(int i) { return unq(i).toLowerCase(); }
boolean bool(int i) { return "true".equals(unq(i)); }
String rest() { return m[m.length-1]; } // for matchStart
int psi(int i) { return Integer.parseInt(unq(i)); }
}
public static String unquote(String s) {
if (s.startsWith("[")) {
int i = 1;
while (i < s.length() && s.charAt(i) == '=') ++i;
if (i < s.length() && s.charAt(i) == '[') {
String m = s.substring(1, i);
if (s.endsWith("]" + m + "]"))
return s.substring(i+1, s.length()-i-1);
}
}
if (s.startsWith("\"") /*&& s.endsWith("\"")*/ && s.length() > 1) {
String st = s.substring(1, s.endsWith("\"") ? s.length()-1 : s.length());
StringBuilder sb = new StringBuilder(st.length());
for (int i = 0; i < st.length(); i++) {
char ch = st.charAt(i);
if (ch == '\\') {
char nextChar = (i == st.length() - 1) ? '\\' : st
.charAt(i + 1);
// Octal escape?
if (nextChar >= '0' && nextChar <= '7') {
String code = "" + nextChar;
i++;
if ((i < st.length() - 1) && st.charAt(i + 1) >= '0'
&& st.charAt(i + 1) <= '7') {
code += st.charAt(i + 1);
i++;
if ((i < st.length() - 1) && st.charAt(i + 1) >= '0'
&& st.charAt(i + 1) <= '7') {
code += st.charAt(i + 1);
i++;
}
}
sb.append((char) Integer.parseInt(code, 8));
continue;
}
switch (nextChar) {
case '\\':
ch = '\\';
break;
case 'b':
ch = '\b';
break;
case 'f':
ch = '\f';
break;
case 'n':
ch = '\n';
break;
case 'r':
ch = '\r';
break;
case 't':
ch = '\t';
break;
case '\"':
ch = '\"';
break;
case '\'':
ch = '\'';
break;
// Hex Unicode: u????
case 'u':
if (i >= st.length() - 5) {
ch = 'u';
break;
}
int code = Integer.parseInt(
"" + st.charAt(i + 2) + st.charAt(i + 3)
+ st.charAt(i + 4) + st.charAt(i + 5), 16);
sb.append(Character.toChars(code));
i += 5;
continue;
default:
ch = nextChar; // added by Stefan
}
i++;
}
sb.append(ch);
}
return sb.toString();
} else
return s; // return original
}
static String formatSnippetID(String id) {
return "#" + parseSnippetID(id);
}
static String formatSnippetID(long id) {
return "#" + id;
}
public static long parseSnippetID(String snippetID) {
long id = Long.parseLong(shortenSnippetID(snippetID));
if (id == 0) fail("0 is not a snippet ID");
return id;
}
static String shortenSnippetID(String snippetID) {
if (snippetID.startsWith("#"))
snippetID = snippetID.substring(1);
String httpBlaBla = "http://tinybrain.de/";
if (snippetID.startsWith(httpBlaBla))
snippetID = snippetID.substring(httpBlaBla.length());
return "" + parseLong(snippetID);
}
static long parseLong(String s) {
return Long.parseLong(s);
}
}