Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

1742
LINES

< > BotCompany Repo | #695 // IOIOI Processor (v10)

JavaX source code [tags: use-pretranspiled] - run with: x30.jar

Libraryless. Click here for Pure Java version (4798L/32K/89K).

1  
!636
2  
!quickmain
3  
!auto-import
4  
!standard functions
5  
!quicknew
6  
!1000346 // use "case" as a variable name
7  
!688 // buf.isEmpty
8  
!class JavaTok
9  
!1000381 // L<S>
10  
!697 // "*()" constructor syntax, v2
11  
12  
import java.lang.reflect.*;
13  
import java.math.*; // BigInteger
14  
import java.text.DecimalFormat;
15  
import java.lang.management.*; // for time measurement
16  
17  
!include #2000470 // class _x16
18  
19  
interface Function {
20  
  public Object process(Object in);
21  
  public void toJava_process(Code code);
22  
}
23  
24  
interface ReversibleFunction extends Function {
25  
  public Object unprocess(Object in);
26  
  public void toJava_unprocess(Code code);
27  
}
28  
29  
// generic learner (works on objects)
30  
interface Learner {
31  
  public void processInOut(Object in, Object out);
32  
  public Object processIn(Object in);
33  
  public void toJava(Code code);
34  
  public void tryAgain();
35  
}
36  
37  
abstract class Base {
38  
  void printVars() {
39  
    new StringBuilder buf;
40  
    Field[] fields = getClass().getDeclaredFields();
41  
    for (Field field : fields) {
42  
      if ((field.getModifiers() & Modifier.STATIC) != 0)
43  
        continue;
44  
      Object value;
45  
      try {
46  
        value = field.get(this);
47  
      } catch (Exception e) {
48  
        value = "?";
49  
      }
50  
      
51  
      if (!buf.isEmpty()) buf.append(", ");
52  
      buf.append(field.getName() + "=" + value);
53  
    }
54  
    System.out.println(buf.toString());
55  
  }
56  
}
57  
58  
abstract class LearnerImpl extends Base implements Learner {
59  
  public void tryAgain() {
60  
    throw new RuntimeException("No try again");
61  
  }
62  
}
63  
64  
class Code {
65  
  new StringBuilder buf;
66  
  String var = "in";
67  
  String indent = "";
68  
  new List<String> translators;
69  
  new List<String> varStack;
70  
  int varCounter;
71  
  
72  
  *() {
73  
    translators.add("!636");
74  
  }
75  
  
76  
  void line(String line) {
77  
    buf.append(indent).append(line).append('\n');
78  
  }
79  
  
80  
  void indent() {
81  
    indent += "  ";
82  
  }
83  
  
84  
  void unindent() {
85  
    indent = indent.substring(0, indent.length()-2);
86  
  }
87  
  
88  
  void translators(String... ids) {
89  
    for (String id : ids)
90  
      if (! translators.contains(id)) // space is needed otherwise translator 636 is fooled :)
91  
        translators.add(id);
92  
  }
93  
  
94  
  String getTranslators() {
95  
    // TODO: We should really fix the "standard functions" translator
96  
    // to properly find the main class.
97  
    //
98  
    // As a hack, we move it upwards (before classes adding)
99  
    int i = translators.indexOf("!standard functions");
100  
    if (i >= 0) {
101  
      translators.remove(i);
102  
      translators.add(0, "!standard functions");
103  
    }
104  
    
105  
    return main.fromLines(translators);
106  
  }
107  
108  
  String s() {
109  
    return "((String) " + var + ")";
110  
  }
111  
  
112  
  String list() {
113  
    return "((List) " + var + ")";
114  
  }
115  
  
116  
  void assign(String exp) {
117  
    line(var + " = " + exp + ";");
118  
  }
119  
  
120  
  void newVar() {
121  
    varStack.add(var);
122  
    var = "_v" + (++varCounter);
123  
    line("Object " + var + ";");
124  
  }
125  
  
126  
  void oldVar() {
127  
    var = varStack.get(varStack.size()-1);
128  
    varStack.remove(varStack.size()-1);
129  
  }
130  
}
131  
132  
main {
133  
  static new List<Case> cases;
134  
  static new HashMap<String, Case> casesByID;
135  
  static boolean testJava = true, showFails;
136  
  static new (Hash)Set<String> parseErrors;
137  
  static int caseIdx;
138  
  
139  
  psvm {
140  
    new List<String> snippetIDs;
141  
    new List<String> inputs;
142  
    
143  
    for (int i = 0; i < args.length; i++) {
144  
      String arg = args[i];
145  
      if (arg.equals("debug"))
146  
        debugOn(args[++i]);
147  
      else if (arg.equals("in")) {
148  
        String in = args[++i];
149  
        System.out.println("in=" + quote(in));
150  
        String quoteUnquote = unquote("\"" + in + "\"");
151  
        System.out.println("now in=" + quote(quoteUnquote));
152  
        inputs.add(quoteUnquote);
153  
      } else if (arg.equals("-notestjava"))
154  
        testJava = false;
155  
      else if (arg.equals("-testjava"))
156  
        testJava = true;
157  
      else if (arg.equals("-showfails"))
158  
        showFails = true;
159  
      else if (isSnippetID(arg))
160  
        snippetIDs.add(arg);
161  
      else
162  
        System.err.println("Unknown argument: " + arg + ", ignoring");
163  
    }
164  
    
165  
    if (snippetIDs.isEmpty())
166  
      parse(null);
167  
    
168  
    for (String snippetID : snippetIDs)
169  
      try {
170  
        Case case = parse(snippetID);
171  
        case.halfExamples.addAll(inputs);
172  
      } catch (Throwable e) {
173  
        e.printStackTrace();
174  
        parseErrors.add(snippetID);
175  
      }
176  
    
177  
    int solved = 0, n = cases.size(), goodJava = 0;
178  
    for (caseIdx = 0; caseIdx < n; caseIdx++) {
179  
      Case case = cases.get(caseIdx);
180  
      try {
181  
        calculate(case);
182  
      } catch (Throwable e) {
183  
        e.printStackTrace();
184  
      }
185  
      if (case.winner != null)
186  
        ++solved;
187  
      if (case.goodJava)
188  
        ++goodJava;
189  
      if (caseIdx+1 == solved)
190  
        System.out.println((caseIdx+1) + " case(s) processed & solved.");
191  
      else
192  
        System.out.println((caseIdx+1) + " case(s) processed, " + solved + " solved.");
193  
      if (testJava && goodJava < solved)
194  
        System.out.println((solved-goodJava) + " case(s) with BAD JAVA.");
195  
    }
196  
197  
    print ""    
198  
    print "----"
199  
200  
    boolean allSolved = solved == n;
201  
    if (solved != 0) {
202  
      System.out.println();
203  
      System.out.print("Solved: ");
204  
      for (Case case : cases)
205  
        if (case.winner != null)
206  
          System.out.print(case.id + " ");
207  
      System.out.println();
208  
    }
209  
    if (testJava && solved > goodJava) {
210  
      System.out.println();
211  
      System.out.print("Bad Java: ");
212  
      for (Case case : cases)
213  
        if (case.winner != null && !case.goodJava)
214  
          System.out.print(case.id + " ");
215  
      System.out.println();
216  
    }
217  
    if (!allSolved) {
218  
      System.out.println();
219  
      System.out.print("Unsolved: ");
220  
      for (Case case : cases)
221  
        if (case.winner == null)
222  
          System.out.print(case.id + " ");
223  
      System.out.println();
224  
    }
225  
    if (!parseErrors.isEmpty()) {
226  
      System.out.print("\nParse errors: ");
227  
      for (String id : parseErrors)
228  
          System.out.print(id + " ");
229  
      System.out.println();
230  
    }
231  
    System.out.println();
232  
    if (allSolved && testJava && goodJava < solved)
233  
      System.out.println("ALL SOLVED (" + solved + "), but some BAD JAVA.");
234  
    else {
235  
      System.out.println(allSolved ? "ALL SOLVED (" + solved + ")" : "Solved " + solved + " out of " + n + ".");
236  
      if (testJava)
237  
        if (goodJava == solved)
238  
          System.out.println("All Java code OK" + (allSolved ? "" : " (for solved cases)") + ".");
239  
        else
240  
          System.out.println("Some bad Java.");
241  
      else
242  
        System.out.println("Java not tested.");
243  
    }
244  
    print ""
245  
    long time = getUserTime();
246  
    if (time >= 0)
247  
      System.out.println("User time: " + formatDouble(time/1e9, 3) + "s");
248  
  }
249  
  
250  
  public static String formatDouble(double d, int digits) {
251  
    String format = "0.";
252  
    for (int i = 0; i < digits; i++) format += "#";
253  
    String s = new DecimalFormat(format).format(d);
254  
    return s.replace(',', '.'); // hack german -> english
255  
  }
256  
  
257  
  /** Get user time in nanoseconds. */
258  
  public static long getUserTime( ) {
259  
    ThreadMXBean bean = ManagementFactory.getThreadMXBean();
260  
    return bean.isCurrentThreadCpuTimeSupported() ?
261  
      bean.getCurrentThreadUserTime() : -1L;
262  
  }
263  
  
264  
  static class Case {
265  
    String id;
266  
    new List<String[]> fullExamples;
267  
    new List<String> halfExamples;
268  
    List<String[]> examples1, examples2;
269  
    Learner winner;
270  
    new RunnersUp runnersUp;
271  
    boolean goodJava;
272  
    List<Case> combined;
273  
    int splitPoint = -1;
274  
    
275  
    // stats
276  
    int learnersTried, retries;
277  
278  
    void split() {    
279  
      if (examples1 != null)
280  
        return; // already done
281  
      if (fullExamples.size() < 2)
282  
        throw new RuntimeException("Too few examples (" + fullExamples.size() + ")");
283  
      if (splitPoint < 0)
284  
        splitPoint = fullExamples.size()-1;
285  
      System.out.println("Full examples: " + fullExamples.size() + ", splitPoint: " + splitPoint + ", half examples: " + halfExamples.size());
286  
      examples1 = fullExamples.subList(0, splitPoint);
287  
      examples2 = fullExamples.subList(splitPoint, fullExamples.size());
288  
    }
289  
    
290  
    void add(Case case) {
291  
      combined.add(case);
292  
      fullExamples.addAll(case.fullExamples);
293  
      halfExamples.addAll(case.halfExamples);
294  
    }
295  
    
296  
    Object processIn(Object in) {
297  
      return winner.processIn(in);
298  
    }
299  
  }
300  
301  
  static Case parse(String arg) tex {
302  
    new Case case;
303  
    String text;
304  
    if (arg != null) {
305  
      if (casesByID.containsKey(arg))
306  
        return casesByID.get(arg);
307  
        
308  
      if (arg.startsWith("Combine")) {
309  
        case.id = "Combine";
310  
        case.combined = new ArrayList<Case>();
311  
        List<String> tok = JavaTok.split(arg);
312  
        new List<String> ids;
313  
        for (int i = 5; i < tok.size(); i += 6) { // skip # and "and"
314  
          Case case2 = parse("#" + tok.get(i));
315  
          case.id += " #" + tok.get(i);
316  
          cases.remove(case2);
317  
          case.add(case2);
318  
        }
319  
        addCase(case);
320  
        return case;
321  
      } else if (isSnippetID(arg)) {
322  
        case.id = arg;
323  
        text = loadSnippet(arg);
324  
      } else {
325  
        case.id = "direct";
326  
        text = arg;
327  
      }
328  
    } else {
329  
      case.id = "input.txt";
330  
      text = loadTextFile("input/input.txt", null);
331  
      if (text == null) {
332  
        //case.id = "#2000455";  // example input
333  
        case.id = "#681"; // a collection of "all cases"!
334  
        text = loadSnippet(case.id);
335  
      }
336  
    }
337  
    
338  
    // it's a collection of cases!
339  
    if (text.trim().startsWith("#") || text.trim().startsWith("Combine")) {
340  
      for (String line : toLines(text))
341  
        parse(line);
342  
      return null;
343  
    }
344  
    
345  
    // it's a "Continue:" task - transform to I/O format
346  
    if (text.trim().startsWith("Continue:")) {
347  
      List<String> lines = toLines(text);
348  
      new StringBuilder buf;
349  
      for (int i = 1; i < lines.size(); i++) {
350  
        buf.append("In: " + quote("" + i) + "\n");
351  
        buf.append("Out: " + quote(lines.get(i)) + "\n");
352  
      }
353  
      int numAsking = 3;
354  
      for (int i = lines.size(); i < lines.size()+numAsking; i++)
355  
        buf.append("In: " + quote("" + i) + "\n");
356  
      text = buf.toString();
357  
    }
358  
      
359  
    // it's an "Execute." task - run Java(X) and transform to I/O format
360  
    if (text.trim().startsWith("Execute.")) {
361  
      List<String> tok = JavaTok.split(text);
362  
      new StringBuilder buf;
363  
      for (int i = 5; i < tok.size(); i += 2) {
364  
        if (tok.get(i).equals("-") && tok.get(i+2).equals("-")) {
365  
          i += 2;
366  
          buf.append("--\n");
367  
        } else {
368  
          String code = unquote_fixSpaces(tok.get(i));
369  
          String result = execute("!636\n" + code);
370  
          buf.append("In: " + quote(code) + "\n");
371  
          buf.append("Out: " + quote(result) + "\n");
372  
        }
373  
      }
374  
      text = buf.toString();
375  
    }
376  
      
377  
    System.out.println(text);
378  
    String in = null, out = null;
379  
    
380  
    List<String> tok = JavaTok.split(text);
381  
    for (int i = 1; i < tok.size(); i += 2) {
382  
      String t = tok.get(i), t2 = i+2 < tok.size() ? tok.get(i+2) : "";
383  
      if (t.equals("-") && t2.equals("-")) {
384  
        i += 2;
385  
        case.splitPoint = case.fullExamples.size();
386  
      } else if (t.toUpperCase().startsWith("I") && t2.equals(":")) { // "In: " or "I: "
387  
        if (in != null)
388  
          case.halfExamples.add(in);
389  
        i += 4;
390  
        int j = findNextLine(tok, i);
391  
        in = unquote_fixSpaces(JavaTok.join(tok.subList(i, j-1)));
392  
        i = j-2;
393  
        out = null;
394  
      } else if (t.toUpperCase().startsWith("O") && t2.equals(":")) { // "Out: " or "O: "
395  
        i += 4;
396  
        int j = findNextLine(tok, i);
397  
        out = unquote_fixSpaces(JavaTok.join(tok.subList(i, j-1)));
398  
        i = j-2;
399  
        if ((in + out).indexOf('\t') >= 0)
400  
          System.err.println("WARNING: Tab character used!");
401  
        System.out.println(quote(in) + " => " + quote(out));
402  
        case.fullExamples.add(new String[] {in, out});
403  
        in = out = null;
404  
      } else {
405  
        int j = findNextLine(tok, i);
406  
        String line = JavaTok.join(tok.subList(i, j-1));
407  
        i = j-2;
408  
        System.out.println("-- Ignoring line: " + line);
409  
      }
410  
    }
411  
    
412  
    if (in != null)
413  
      case.halfExamples.add(in);
414  
    addCase(case);
415  
    return case;
416  
  }
417  
  
418  
  static String unquote_fixSpaces(String s) {
419  
    String _ = unquote(s);
420  
    if (s.startsWith("[["))
421  
      _ = fixSpaces(_);
422  
    return _;
423  
  }
424  
  
425  
  // remove invisible spaces at end of line - this will otherwise confuse the engine(s) greatly...
426  
  static String fixSpaces(String s) {
427  
    System.out.println(quote(s));
428  
    s = s.replaceAll("[\t ]+(\r?\n)", "$1");
429  
    s = s.replaceAll("[\t ]+$", "");
430  
    //System.out.println("_fixSpaces => " + quote(s));
431  
    return s;
432  
  }
433  
  
434  
  // i is a code-token (odd index)
435  
  // return value is also a code token, or end of list
436  
  static int findNextLine(List<String> tok, int i) {
437  
    while (i < tok.size() && tok.get(i-1).indexOf('\n') < 0)
438  
      i += 2;
439  
    return i;
440  
  }
441  
  
442  
  static void addCase(Case case) {
443  
    cases.add(case);
444  
    casesByID.put(case.id, case);
445  
  }
446  
  
447  
  static void calculate(Case case) tex {
448  
    System.out.println("\n== CASE " + case.id + " ==");
449  
    
450  
    case.split();
451  
    Learner learner = findOKLearner(case);
452  
    if (learner == null) {
453  
      String stat = "";
454  
      if (case.retries != 0) stat = " + " + case.retries + " retries";
455  
      System.out.println("\nProblem not solved (" + case.learnersTried + " learners tried" + stat + ")");
456  
      RunnersUp ru = case.runnersUp;
457  
      if (ru != null && ru.winner != null)
458  
        System.out.println("Closest result: " + quote(ru.bestResult) + " instead of " + quote(ru.expected) + " (score " + ru.bestScore + ") by " + structure(ru.winner));
459  
    } else {
460  
      print "\nSolved!"
461  
      case.winner = learner;
462  
      new Code code;
463  
      try {
464  
        learner.toJava(code);
465  
466  
        if (testJava)
467  
          testJava(case, code); // prints "GOOD JAVA" or "BAD JAVA"
468  
        else
469  
          print "Java:"
470  
          
471  
        System.out.println(indent("  ", code.getTranslators()));
472  
        System.out.println(indent("  ", code.buf.toString()));
473  
      } catch (Throwable e) {
474  
        print "BAD JAVA"
475  
      }
476  
        
477  
      for (String in : case.halfExamples) {
478  
        Object out = learner.processIn(in);
479  
        System.out.println(quote(in) + " =>! " + quote((String) out));
480  
      }
481  
    }
482  
  }
483  
  
484  
  static Learner findOKLearner(Case case) tex {
485  
    for (Learner learner : makeLearners()) try {
486  
      if (learnerOK(learner, case))
487  
        return learner;
488  
    } catch (Throwable e) {
489  
      if (showFails)
490  
        e.printStackTrace();
491  
    }
492  
    
493  
    if (case.combined != null) {
494  
      Case switchCase = makeSwitchCase(case);
495  
      calculate(switchCase);
496  
      Learner learner = switchCase.winner;
497  
      if (learner != null)
498  
        return new LSwitch(case, learner);
499  
    }
500  
    
501  
    return null;
502  
  }
503  
  
504  
  static Case makeSwitchCase(Case case) {
505  
    int i = 0;
506  
    Case s = new Case();
507  
    s.id = "Switch " + case.id;
508  
    s.examples1 = new ArrayList<String[]>();
509  
    s.examples2 = new ArrayList<String[]>();
510  
    for (Case c : case.combined) {
511  
      ++i;
512  
      for (String[] e : c.examples1)
513  
        s.examples1.add(new String[] {e[0], String.valueOf(i)});
514  
      for (String[] e : c.examples2)
515  
        s.examples2.add(new String[] {e[0], String.valueOf(i)});
516  
      for (String[] e : c.fullExamples)
517  
        s.fullExamples.add(new String[] {e[0], String.valueOf(i)});
518  
    }
519  
    return s;
520  
  }
521  
  
522  
  static boolean learnerOK(Learner learner, Case case) {
523  
    String[] _e = null;
524  
    try {
525  
      if (case.examples1 == null)
526  
        fail("Case not calculated: " + case.id);
527  
        
528  
      ++case.learnersTried;
529  
      for (String[] e : case.examples1) {
530  
        _e = e;
531  
        learner.processInOut(e[0], e[1]);
532  
      }
533  
      
534  
      // full validation against all examples
535  
      int retry = 0;
536  
      retryLoop: while (true) {
537  
        for (String[] e : case.fullExamples) {
538  
          _e = e;
539  
          String out = (String) learner.processIn(e[0]);
540  
          if (!e[1].equals(out)) {
541  
          
542  
            if (case.runnersUp != null)
543  
              case.runnersUp.add(e[1], out, leven(out, e[1]), learner);
544  
              
545  
            if (showFails)
546  
              System.out.println("[fail] " + structure(learner) + " on " + quote(e[0]) + " - got: " + quote(out) + " rather than: " + quote(e[1]));
547  
            ++retry;
548  
            ++case.retries;
549  
            if (retry % 1000 == 0)
550  
              System.err.println("Retry " + retry);
551  
            learner.tryAgain();
552  
            continue retryLoop;
553  
          }
554  
        }
555  
        return true;  // all test examples passed
556  
      }
557  
    } catch (Throwable e) {
558  
      if (showFails) {
559  
        e.printStackTrace();
560  
        System.err.println("[fail] " + learner + " on " + (_e == null ? "?" : quote(_e[0])) + " - " + e);
561  
      }
562  
      return false;
563  
    }
564  
  }
565  
  
566  
  static boolean validate(String[] example, Learner learner) {
567  
    try {
568  
      String out = (String) learner.processIn(example[0]);
569  
      if (!example[1].equals(out)) {
570  
          //System.out.println("[fail] " + learner + " on " + quote(e[0]) + " - got: " + quote(out) + " rather than: " + quote(e[1]));
571  
          return false;
572  
        }
573  
      return true;
574  
    } catch (Throwable e) {
575  
      silentException(e);
576  
      return false;
577  
    }
578  
  }
579  
  
580  
  static void silentException(Throwable e) {
581  
  }
582  
  
583  
  /* XXX - important part */
584  
  static Iterable<Learner> makeLearners() {
585  
    new List<Learner> list;
586  
    list.addAll(level1());
587  
    list.add(new LBox(new LMulti(level1())));
588  
    list.add(new LBox2(new LMulti(level1())));
589  
    
590  
    list.add(new LChange(new FCommonPrefix(), new LOutPattern()));
591  
    list.add(new LChange(new FCommonSuffix(), new LOutPattern()));
592  
    
593  
    list.add(new LEmptyBox(new LMulti(level1())));
594  
    return list;
595  
  }
596  
  
597  
  static List<Learner> level1() {
598  
    new List<Learner> list;
599  
    list.add(new LId()); // always good to have as included learner
600  
    list.add(new LPrefixSuffix());
601  
    list.add(new LSplitInput(new LOutPattern()));
602  
    list.add(new LInputPattern());
603  
    list.add(new LFixed());
604  
    list.add(new LBoth(new RFJavaTok(), new LEach(new LFixedFunction(new EscapeCase()))));
605  
    list.add(new LCharShift());
606  
    list.add(new LOutSuffix(new LFirst(new LCharShift())));
607  
    
608  
    list.add(new LChange(new RFJavaTok(), new LMulti(
609  
      new LChange(new FStringsOnly(), new LGetListElement()),
610  
      new LChange(new FNumbersOnly(), new LMath()))
611  
    ));
612  
    
613  
    // TODO - for #1000378
614  
    list.add(new LChange(new RFJavaTok(), new LDistinguishList(new FIsString())));
615  
616  
    // of no use now it seems
617  
    // list.add(new LTryPrevious());
618  
    
619  
    return list;
620  
  }
621  
  
622  
  public static String unquote(String s) {
623  
    if (s.startsWith("[[") && s.endsWith("]]"))
624  
      return s.substring(2, s.length()-2);
625  
    else if (s.startsWith("\"") && s.endsWith("\"") && s.length() > 1)
626  
      //return s.substring(1, s.length()-1).replace("\\\"", "\"").replace("\\\\", "\\");
627  
      return unescapeJavaString(s.substring(1, s.length()-1));
628  
    else
629  
      return s; // return original
630  
  }
631  
  
632  
  /** from: http://stackoverflow.com/questions/3537706/howto-unescape-a-java-string-literal-in-java,
633  
      or: https://gist.github.com/uklimaschewski/6741769
634  
      
635  
      Thanks!
636  
  */
637  
  public static String unescapeJavaString(String st) {
638  
    StringBuilder sb = new StringBuilder(st.length());
639  
640  
    for (int i = 0; i < st.length(); i++) {
641  
        char ch = st.charAt(i);
642  
        if (ch == '\\') {
643  
            char nextChar = (i == st.length() - 1) ? '\\' : st
644  
                    .charAt(i + 1);
645  
            // Octal escape?
646  
            if (nextChar >= '0' && nextChar <= '7') {
647  
                String code = "" + nextChar;
648  
                i++;
649  
                if ((i < st.length() - 1) && st.charAt(i + 1) >= '0'
650  
                        && st.charAt(i + 1) <= '7') {
651  
                    code += st.charAt(i + 1);
652  
                    i++;
653  
                    if ((i < st.length() - 1) && st.charAt(i + 1) >= '0'
654  
                            && st.charAt(i + 1) <= '7') {
655  
                        code += st.charAt(i + 1);
656  
                        i++;
657  
                    }
658  
                }
659  
                sb.append((char) Integer.parseInt(code, 8));
660  
                continue;
661  
            }
662  
            switch (nextChar) {
663  
            case '\\':
664  
                ch = '\\';
665  
                break;
666  
            case 'b':
667  
                ch = '\b';
668  
                break;
669  
            case 'f':
670  
                ch = '\f';
671  
                break;
672  
            case 'n':
673  
                ch = '\n';
674  
                break;
675  
            case 'r':
676  
                ch = '\r';
677  
                break;
678  
            case 't':
679  
                ch = '\t';
680  
                break;
681  
            case '\"':
682  
                ch = '\"';
683  
                break;
684  
            case '\'':
685  
                ch = '\'';
686  
                break;
687  
            // Hex Unicode: u????
688  
            case 'u':
689  
                if (i >= st.length() - 5) {
690  
                    ch = 'u';
691  
                    break;
692  
                }
693  
                int code = Integer.parseInt(
694  
                        "" + st.charAt(i + 2) + st.charAt(i + 3)
695  
                                + st.charAt(i + 4) + st.charAt(i + 5), 16);
696  
                sb.append(Character.toChars(code));
697  
                i += 5;
698  
                continue;
699  
            }
700  
            i++;
701  
        }
702  
        sb.append(ch);
703  
    }
704  
    return sb.toString();
705  
  }
706  
707  
public static String quote(String s) {
708  
    if (s == null) return "null";
709  
    return "\"" + s.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
710  
  }
711  
  
712  
  static String indent(String indent, String s) {
713  
    return indent + s.replace("\n", "\n" + indent);
714  
  }
715  
  
716  
  static Class<?> getClass(String name) {
717  
    try {
718  
      return Class.forName(name);
719  
    } catch (ClassNotFoundException e) {
720  
      return null;
721  
    }
722  
  }
723  
  
724  
  static void debugOn(String name) {
725  
    try {
726  
      Class c = getClass("main$" + name);
727  
      if (c == null) c = getClass(name);
728  
      Field field;
729  
      while (true)
730  
        try {
731  
          field = c.getDeclaredField("debug");
732  
          break;
733  
        } catch  (NoSuchFieldException e) {
734  
          c = c.getSuperclass();
735  
        }
736  
      field.setBoolean(null, true);
737  
    } catch (Exception e) {
738  
      e.printStackTrace();
739  
      System.err.println("Cannot debug class " + name);
740  
    }
741  
  }
742  
  
743  
  // splits the input at some point, takes only one part
744  
  static class LSplitInput extends LearnerImpl {
745  
    int splitIdx = 1; // split after first character
746  
    Learner baseLearner;
747  
    
748  
    LSplitInput(Learner baseLearner) {
749  
      this.baseLearner = baseLearner;
750  
    }
751  
    
752  
    public void processInOut(Object _in, Object _out) {
753  
      String in = (String) _in, out = (String) _out;
754  
      in = in.substring(splitIdx);
755  
      baseLearner.processInOut(in, out);
756  
    }
757  
    
758  
    public Object processIn(Object _in) {
759  
      String in = (String) _in;
760  
      in = in.substring(splitIdx);
761  
      return baseLearner.processIn(in);
762  
    }
763  
    
764  
    public void toJava(Code code) {
765  
      if (splitIdx != 0)
766  
        code.line(code.var + " = ((String) " + code.var + ").substring(" + splitIdx + ");");
767  
      baseLearner.toJava(code);
768  
    }
769  
  }
770  
  
771  
  // removes common suffix from out, delegates to base learner
772  
  static class LOutSuffix extends LearnerImpl {
773  
    String suffixOut = "";
774  
    Learner baseLearner;
775  
    
776  
    LOutSuffix(Learner baseLearner) {
777  
      this.baseLearner = baseLearner;
778  
    }
779  
    
780  
    public void processInOut(Object _in, Object _out) {
781  
      String in = (String) _in, out = (String) _out;
782  
      if (out.endsWith("!"))
783  
        suffixOut = "!";
784  
      if (out.endsWith(suffixOut))
785  
        out = out.substring(0, out.length()-suffixOut.length());
786  
      
787  
      baseLearner.processInOut(in, out);
788  
    }
789  
    
790  
    public Object processIn(Object _in) {
791  
      String in = (String) _in;
792  
      return baseLearner.processIn(in) + suffixOut;
793  
    }
794  
    
795  
    public void toJava(Code code) {
796  
      baseLearner.toJava(code);
797  
      if (suffixOut.length() != 0)
798  
        code.line(code.var + " = " + code.s() + "+" + quote(suffixOut) + ";");
799  
    }
800  
  }
801  
  
802  
  // if input appears in output in fixed pattern
803  
  static class LOutPattern extends LearnerImpl {
804  
    static boolean debug;
805  
    String pattern = "%!%";
806  
807  
    public void processInOut(Object _in, Object _out) {
808  
      String in = (String) _in, out = (String) _out;
809  
      pattern = out.replace(in, "%!%");
810  
      if (debug)
811  
        System.out.println("LOutPattern: in=" + quote(in) + ", out=" + quote(out) + ", pattern=" + quote(pattern));
812  
    }
813  
    
814  
    public String processIn(Object _in) {
815  
      String in = (String) _in;
816  
      return pattern.replace("%!%", in);
817  
    }
818  
    
819  
    public void toJava(Code code) {
820  
      code.line(code.var + " = " + quote(pattern) + ".replace(" + quote("%!%") + ", (String) " + code.var + ");");
821  
    }
822  
  }
823  
  
824  
  // simplets learner - only knows the "id" function
825  
  static class LId extends LearnerImpl {
826  
    public void processInOut(Object in, Object out) {
827  
    }
828  
    
829  
    public Object processIn(Object in) {
830  
      return in;
831  
    }
832  
    
833  
    public void toJava(Code code) {
834  
    }
835  
  }
836  
  
837  
  // learns to exchange common prefixes and suffixes
838  
  static class LPrefixSuffix extends LearnerImpl {
839  
    static boolean debug;
840  
    String prefixIn, suffixIn, prefixOut, suffixOut;
841  
    
842  
    public void processInOut(Object _in, Object _out) {
843  
      String in = (String) _in, out = (String) _out;
844  
      updateIn(in);
845  
      prefixOut = prefixOut == null ? out : commonPrefix(prefixOut, out);
846  
      suffixOut = suffixOut == null ? out : commonSuffix(suffixOut, out);
847  
      if (debug)
848  
        printState("processInOut(" + quote(in) + ", " + quote(out) + ")");
849  
    }
850  
    
851  
    void updateIn(String in) {
852  
      prefixIn = prefixIn == null ? in : commonPrefix(prefixIn, in);
853  
      suffixIn = suffixIn == null ? in : commonSuffix(suffixIn, in);
854  
      if (debug)
855  
        printState("updateIn(" + quote(in) + ")");
856  
    }
857  
858  
    public String processIn(Object _in) {
859  
      String in = (String) _in;
860  
      //System.out.println("[before last info] " + quote(prefixIn) + " " + quote(suffixIn) + " " + quote(prefixOut) + " " + quote(suffixOut));
861  
      //System.out.println("[last info] " + quote(in));
862  
      
863  
      // use latest information
864  
      String p = prefixIn, s = suffixIn;
865  
      updateIn(in);
866  
      prefixOut = prefixOut.substring(0, prefixOut.length()-(p.length()-prefixIn.length()));
867  
      suffixOut = suffixOut.substring(s.length()-suffixIn.length());
868  
      
869  
      //System.out.println("[after last info] " + quote(prefixIn) + " " + quote(suffixIn) + " " + quote(prefixOut) + " " + quote(suffixOut));
870  
      String core = in.substring(prefixIn.length(), in.length()-suffixIn.length());
871  
      return prefixOut + core + suffixOut;
872  
    }
873  
    
874  
    public void toJava(Code code) {
875  
      if (prefixIn.length() != 0 || suffixIn.length() != 0)
876  
        code.line(code.var + " = ((String) " + code.var + ").substring(" + prefixIn.length() + ", " + code.s() + ".length()-" + suffixIn.length() + ");");
877  
      if (prefixOut.length() != 0 || suffixOut.length() != 0)
878  
        code.line(code.var + " = " + quote(prefixOut) + " + " + code.var + " + " + quote(suffixOut) + ";");
879  
    }
880  
    
881  
    void printState(String text) {
882  
      System.out.println(text);
883  
      printVars();
884  
    }
885  
  }
886  
  
887  
  // for "find" tasks (e.g. "abcde" to "[[abc]]de")
888  
  static class LInputPattern extends LearnerImpl {
889  
    String regexp = "";
890  
    
891  
    public void processInOut(Object _in, Object _out) {
892  
      String in = (String) _in, out = (String) _out;
893  
      int i = out.indexOf("[["), j = out.indexOf("]]", i+1);
894  
      if (j < 0) return;
895  
      String s = out.substring(i+2, j);
896  
      regexp = s.replaceAll("\\d+", Matcher.quoteReplacement("\\d+"));
897  
      System.out.println("regexp: " + regexp);
898  
    }
899  
    
900  
    public String processIn(Object _in) {
901  
      String in = (String) _in;
902  
      if (regexp.length() == 0)
903  
        return in;
904  
      else
905  
        return in.replaceAll("(" + regexp + ")", "[[$1]]");
906  
    }
907  
    
908  
    public void toJava(Code code) {
909  
      code.line(code.var + " = ((String) " + code.var + ").replaceAll(" + quote("(" + regexp + ")") + ", \"[[$1]]\");");
910  
    }
911  
  }
912  
  
913  
  static class LFixed extends LearnerImpl {
914  
    static boolean debug;
915  
    Object value;
916  
    
917  
    public void processInOut(Object in, Object out) {
918  
      value = out;
919  
      if (debug)
920  
        printVars();
921  
    }
922  
    
923  
    public Object processIn(Object in) {
924  
      return value;
925  
    }
926  
    
927  
    public void toJava(Code code) {
928  
      code.line(code.var + " = " + quote((String) value) + ";");
929  
    }
930  
  }
931  
  
932  
  static void fail(String msg) {
933  
    throw new RuntimeException(msg);
934  
  }
935  
  
936  
  static void assertSameSize(List a, List b) {
937  
    if (a.size() != b.size())
938  
      fail("wrong list sizes");
939  
  }
940  
941  
  // process lists in parallel
942  
  // (in and out must be a list of same length)
943  
  static class LEach extends LearnerImpl {
944  
    static boolean debug;
945  
    Learner base;
946  
    
947  
    LEach(Learner base) {
948  
      this.base = base;
949  
    }
950  
    
951  
    public void processInOut(Object _in, Object _out) {
952  
      List in = (List) _in, out = (List) _out;
953  
      assertSameSize(in, out);
954  
      for (int i = 0; i < in.size(); i++)
955  
        base.processInOut(in.get(i), out.get(i));
956  
      if (debug)
957  
        printVars();
958  
    }
959  
    
960  
    public Object processIn(Object _in) {
961  
      List in = (List) _in;
962  
      List out = new ArrayList();
963  
      for (Object x : in)
964  
        out.add(base.processIn(x));
965  
      return out;
966  
    }
967  
    
968  
    public void toJava(Code code) {
969  
      code.line("List out = new ArrayList();");
970  
      code.line("for (Object x : (List) in) {");
971  
      code.indent();
972  
      code.line("in = x;");
973  
      base.toJava(code);
974  
      code.line("out.add(in);");
975  
      code.unindent();
976  
      code.line("}");
977  
      code.line("in = out;");
978  
    }
979  
  }
980  
  
981  
  static class LChange extends LearnerImpl {
982  
    Function f;
983  
    Learner base;
984  
    
985  
    LChange(Function f, Learner base) {
986  
      this.f = f;
987  
      this.base = base;
988  
    }
989  
    
990  
    public void processInOut(Object in, Object out) {
991  
      in = f.process(in);
992  
      base.processInOut(in, out);
993  
    }
994  
    
995  
    public Object processIn(Object in) {
996  
      in = f.process(in);
997  
      return base.processIn(in);
998  
    }
999  
    
1000  
    public void toJava(Code code) {
1001  
      f.toJava_process(code);
1002  
      base.toJava(code);
1003  
    }
1004  
  }
1005  
  
1006  
  static class LBoth extends LearnerImpl {
1007  
    ReversibleFunction f;
1008  
    Learner base;
1009  
    
1010  
    LBoth(ReversibleFunction f, Learner base) {
1011  
      this.f = f;
1012  
      this.base = base;
1013  
    }
1014  
    
1015  
    public void processInOut(Object in, Object out) {
1016  
      in = f.process(in);
1017  
      out = f.process(out);
1018  
      base.processInOut(in, out);
1019  
    }
1020  
    
1021  
    public Object processIn(Object in) {
1022  
      in = f.process(in);
1023  
      in = base.processIn(in);
1024  
      in = f.unprocess(in);
1025  
      return in;
1026  
    }
1027  
    
1028  
    public void toJava(Code code) {
1029  
      f.toJava_process(code);
1030  
      base.toJava(code);
1031  
      f.toJava_unprocess(code);
1032  
    }
1033  
  }
1034  
  
1035  
  static class RFJavaTok implements ReversibleFunction {
1036  
    public Object process(Object in) {
1037  
      return JavaTok.split((String) in);
1038  
    }
1039  
    
1040  
    public Object unprocess(Object in) {
1041  
      return JavaTok.join((List) in);
1042  
    }
1043  
    
1044  
    public void toJava_process(Code code) {
1045  
      code.translators("!636", "!class JavaTok");
1046  
      code.line(code.var + " = JavaTok.split((String) " + code.var + ");");
1047  
    }
1048  
    
1049  
    public void toJava_unprocess(Code code) {
1050  
      code.translators("!636", "!class JavaTok");
1051  
      code.line(code.var + " = JavaTok.join((List) " + code.var + ");");
1052  
    }
1053  
  }
1054  
  
1055  
  // works on a token list - makes a list of only the string constants (unquoted)
1056  
  static class FStringsOnly implements Function {
1057  
    static boolean debug;
1058  
    
1059  
    public Object process(Object _in) {
1060  
      new List<String> tok;
1061  
      for (String s : (List<String>) _in) {
1062  
        boolean isString = s.startsWith("\"") || s.startsWith("[[");
1063  
        if (isString)
1064  
          tok.add(unquote(s));
1065  
        if (debug)
1066  
          System.out.println("FStringsOnly - isString: " + isString + " - " + s);
1067  
      }
1068  
      return tok;
1069  
    }
1070  
    
1071  
    public void toJava_process(Code code) {
1072  
      code.translators("!standard functions");
1073  
      code.line("List<String> tok = new ArrayList<String>();");
1074  
      code.line("for (String s : (List<String>) " + code.var + ")");
1075  
      code.line("  if (s.startsWith(\"\\\"\") || s.startsWith(\"[[\")) tok.add(unquote(s));");
1076  
      code.assign("tok");
1077  
    }
1078  
  }
1079  
  
1080  
  // works on a token list - makes a list of only the number constants
1081  
  static class FNumbersOnly implements Function {
1082  
    static boolean debug;
1083  
    
1084  
    public Object process(Object _in) {
1085  
      new List<String> tok;
1086  
      for (String s : (List<String>) _in) {
1087  
        boolean isNumber = s.length() != 0 && (Character.isDigit(s.charAt(0)) || (s.charAt(0) == '-' && s.length() > 1));
1088  
        if (isNumber)
1089  
          tok.add(s);
1090  
        if (debug)
1091  
          System.out.println("FNumbersOnly - isNumber: " + isNumber + " - " + s);
1092  
      }
1093  
      return tok;
1094  
    }
1095  
    
1096  
    public void toJava_process(Code code) {
1097  
      code.line("List<String> tok = new ArrayList<String>();");
1098  
      code.line("for (String s : (List<String>) " + code.var + ")");
1099  
      code.line("  if (s.length() != 0 && (Character.isDigit(s.charAt(0)) || (s.charAt(0) == '-' && s.length() > 1))) tok.add(s);");
1100  
      code.assign("tok");
1101  
    }
1102  
  }
1103  
  
1104  
  static class LFixedFunction extends LearnerImpl {
1105  
    Function f;
1106  
    
1107  
    LFixedFunction(Function f) {
1108  
      this.f = f;
1109  
    }
1110  
    
1111  
    public void processInOut(Object in, Object out) {
1112  
    }
1113  
    
1114  
    public Object processIn(Object in) {
1115  
      return f.process(in);
1116  
    }
1117  
    
1118  
    public void toJava(Code code) {
1119  
      f.toJava_process(code);
1120  
    }
1121  
  }
1122  
  
1123  
  // trivial stuff like taking the one element out of a 1-element list
1124  
  static class LTrivial extends LearnerImpl {
1125  
    public void processInOut(Object in, Object out) {
1126  
    }
1127  
    
1128  
    public Object processIn(Object in) {
1129  
      return ((List) in).get(0);
1130  
    }
1131  
    
1132  
    public void toJava(Code code) {
1133  
      code.assign(code.list() + ".get(0)");
1134  
    }
1135  
  }
1136  
  
1137  
  // get element of a list at fixed index
1138  
  static class LGetListElement extends LearnerImpl {
1139  
    static boolean debug;
1140  
    int i;
1141  
    
1142  
    public void processInOut(Object _in, Object out) {
1143  
      List in = (List) _in;
1144  
      i = in.indexOf(out);
1145  
      if (debug)
1146  
        System.out.println("LGetListElement: " + i + " " + out);
1147  
    }
1148  
    
1149  
    public Object processIn(Object in) {
1150  
      return ((List) in).get(i);
1151  
    }
1152  
    
1153  
    public void toJava(Code code) {
1154  
      code.assign(code.list() + ".get(" + i + ")");
1155  
    }
1156  
  }
1157  
  
1158  
  // math operations
1159  
  static class LMath extends LearnerImpl {
1160  
    static boolean debug;
1161  
    String allOperations = "+ - * /";
1162  
    new (Tree)Set<String> possibleOperations;
1163  
    
1164  
    LMath() {
1165  
      possibleOperations.addAll(Arrays.asList(allOperations.split(" +")));
1166  
    }
1167  
    
1168  
    public void processInOut(Object _in, Object _out) {
1169  
      List in = (List) _in;
1170  
      String out = (String) _out;
1171  
      BigInteger[] inNumbers = getNumbers(in);
1172  
      BigInteger[] outNumbers = new BigInteger[] {getNumber(out)};
1173  
      findOperation(inNumbers, outNumbers);
1174  
      if (debug)
1175  
        System.out.println("Operations: " + possibleOperations);
1176  
    }
1177  
    
1178  
    public void findOperation(BigInteger[] in, BigInteger[] out) {
1179  
      filterOperations(in, out);
1180  
      if (possibleOperations.isEmpty())
1181  
        fail("tilt");
1182  
    }
1183  
      
1184  
    public void filterOperations(BigInteger[] in, BigInteger[] out) {
1185  
      for (Iterator<String> i = possibleOperations.iterator(); i.hasNext(); ) {
1186  
        String op = i.next();
1187  
        BigInteger[] out2 = doOperation(op, in);
1188  
        if (out2 == null || !arraysEqual(out, out2))
1189  
          i.remove(); // keep only matching operations
1190  
      }
1191  
    }
1192  
    
1193  
    public BigInteger[] doOperation(String op, BigInteger[] in) {
1194  
      op = op.intern();
1195  
      try {
1196  
        if (in.length == 2) {
1197  
          BigInteger a = in[0], b = in[1], x = null;
1198  
          if (op == "+")
1199  
            x = a.add(b);
1200  
          else if (op == "-")
1201  
            x = a.subtract(b);
1202  
          else if (op == "*")
1203  
            x = a.multiply(b);
1204  
          else if (op == "/")
1205  
            x = a.divide(b);
1206  
          return x != null ? new BigInteger[] {x} : null;
1207  
        }
1208  
        return null;
1209  
      } catch (Throwable e) {
1210  
        return null;
1211  
      }
1212  
    }
1213  
    
1214  
    public String processIn(Object _in) {
1215  
      List<String> in = (List<String>) _in;
1216  
      String op = possibleOperations.iterator().next();
1217  
      if (debug)
1218  
        System.out.println("op: " + op);
1219  
      BigInteger[] inNumbers = getNumbers(in);
1220  
      BigInteger[] outNumbers = doOperation(op, inNumbers);
1221  
      return outNumbers[0].toString();
1222  
    }
1223  
    
1224  
    String BI = BigInteger.class.getName();
1225  
    
1226  
    public void toJava(Code code) {
1227  
      String op = possibleOperations.iterator().next();
1228  
      String a = "new " + BI + "((String) " + code.list() + ".get(0))";
1229  
      String b = "new " + BI + "((String) " + code.list() + ".get(1))";
1230  
      if (op.equals("+"))
1231  
        code.assign(a + ".add(" + b + ").toString()");
1232  
      else
1233  
        todo();
1234  
    }
1235  
    
1236  
    static BigInteger[] getNumbers(List<String> in) {
1237  
      BigInteger[] big = new BigInteger[in.size()];
1238  
      for (int i = 0; i < in.size(); i++)
1239  
        big[i] = new BigInteger(in.get(i));
1240  
      return big;
1241  
    }
1242  
    
1243  
    static BigInteger getNumber(String s) {
1244  
      return new BigInteger(s);
1245  
    }
1246  
    
1247  
    static boolean arraysEqual(BigInteger[] a, BigInteger[] b) {
1248  
      if (a.length != b.length) return false;
1249  
      for (int i = 0; i < a.length; i++)
1250  
        if (!a[i].equals(b[i])) return false;
1251  
      return true;
1252  
    }
1253  
  }
1254  
  
1255  
  static class EscapeCase implements Function {
1256  
    static boolean debug;
1257  
    
1258  
    public Object process(Object _in) {
1259  
      if (debug)
1260  
        System.out.println("EscapeCase: " + _in);
1261  
      String in = (String) _in;
1262  
      return in.equals("case") ? "_case" : in;
1263  
    }
1264  
    
1265  
    public void toJava_process(Code code) {
1266  
      code.line("if (\"case\".equals(" + code.var + ")) " + code.var + " = " + quote("_case") + ";");
1267  
    }
1268  
  }
1269  
  
1270  
  static class LCharShift extends LearnerImpl {
1271  
    int shift;
1272  
    
1273  
    public void processInOut(Object _in, Object _out) {
1274  
      String in = (String) _in, out = (String) _out;
1275  
      shift = (int) out.charAt(0) - (int) in.charAt(0);
1276  
    }
1277  
    
1278  
    public Object processIn(Object _in) {
1279  
      String in = (String) _in;
1280  
      char[] c = new char[in.length()];
1281  
      for (int i = 0; i < c.length; i++)
1282  
        c[i] = (char) ((int) in.charAt(i) + shift);
1283  
      return new String(c);
1284  
    }
1285  
    
1286  
    public void toJava(Code code) {
1287  
      code.line("char[] c = new char[((String) " + code.var + ").length()];");
1288  
      code.line("for (int i = 0; i < c.length; i++)");
1289  
      code.line("  c[i] = (char) ((int) ((String) " + code.var + ").charAt(i)" + (shift < 0 ? "" + shift : "+" + shift) + ");");
1290  
      code.line(code.var + " = new String(c);");
1291  
    }
1292  
  }
1293  
  
1294  
  // applies base learner to first char of string
1295  
  // (or first element of list, TODO)
1296  
  static class LFirst extends LearnerImpl {
1297  
    Learner baseLearner;
1298  
    
1299  
    *(Learner baseLearner) {
1300  
      this.baseLearner = baseLearner;
1301  
    }
1302  
    
1303  
    public void processInOut(Object _in, Object _out) {
1304  
      String in = (String) _in, out = (String) _out;
1305  
      if (in.length() == 0)
1306  
        return;
1307  
      String firstIn = in.substring(0, 1), firstOut = out.substring(0, 1);
1308  
      baseLearner.processInOut(firstIn, firstOut);
1309  
    }
1310  
    
1311  
    public Object processIn(Object _in) {
1312  
      String in = (String) _in;
1313  
      if (in.length() == 0)
1314  
        return in;
1315  
      String firstIn = in.substring(0, 1);
1316  
      return baseLearner.processIn(firstIn) + in.substring(1);
1317  
    }
1318  
    
1319  
    public void toJava(Code code) {
1320  
      code.line("if (" + code.s() + ".length() != 0) {");
1321  
      code.indent();
1322  
      code.line("String rest = " + code.s() + ".substring(1);");
1323  
      code.line(code.var + " = " + code.s() + ".substring(0, 1);");
1324  
      baseLearner.toJava(code);
1325  
      code.line(code.var + " = " + code.s() + "+rest;");
1326  
      code.unindent();
1327  
      code.line("}");
1328  
    }
1329  
  }
1330  
  
1331  
  static Method findMainMethod(Class<?> theClass) {
1332  
    for (Method method : theClass.getMethods())
1333  
      if (method.getName().equals("main") && method.getParameterTypes().length == 1)
1334  
        return method;
1335  
    throw new RuntimeException("Method 'main' with 1 parameter not found in " + theClass.getName());
1336  
  }
1337  
  
1338  
  // compile JavaX source and load main class
1339  
  static Class<?> compileAndLoadMainClass(String src) tex {
1340  
    File srcDir = _x16.TempDirMaker_make();
1341  
    File classesDir = _x16.TempDirMaker_make();
1342  
    _x16.saveTextFile(new File(srcDir, "main.java").getPath(), src);
1343  
    new List<File> libraries;
1344  
    File transpiledDir = _x16.topLevelTranslate(srcDir, libraries);
1345  
    String javacOutput = _x16.compileJava(transpiledDir, libraries, classesDir);
1346  
    System.out.println(javacOutput);
1347  
    URL[] urls = {classesDir.toURI().toURL()};
1348  
    
1349  
    // make class loader
1350  
    URLClassLoader classLoader = new URLClassLoader(urls);
1351  
1352  
    // load main class
1353  
    Class<?> mainClass = classLoader.loadClass("main");
1354  
    return mainClass;
1355  
  }
1356  
      
1357  
  static Method compileJavaInToOut(Code code) {
1358  
    try {
1359  
      String java = code.buf.toString();
1360  
      String prelude = /*"import java.util.*;\n\n" +*/
1361  
        "public class main { public static Object main(Object in) throws Exception {\n";
1362  
      String postlude = "\nreturn in;\n}}";
1363  
      String src = code.getTranslators() + "\n" + prelude + java + postlude;
1364  
      Class<?> mainClass = compileAndLoadMainClass(src);
1365  
      return findMainMethod(mainClass);
1366  
    } catch (Exception e) {
1367  
      throw new RuntimeException(e);
1368  
    }
1369  
  }
1370  
  
1371  
  static Method findCalcMethod(Class<?> theClass) {
1372  
    for (Method method : theClass.getMethods())
1373  
      if (method.getName().equals("calc"))
1374  
        return method;
1375  
    throw new RuntimeException("Method 'calc' not found in " + theClass.getName());
1376  
  }
1377  
  
1378  
  // for simplejava stuff (execute tasks)
1379  
  static String execute(String src) {
1380  
    try {
1381  
      Class<?> mainClass = compileAndLoadMainClass(src);
1382  
      Method m = findCalcMethod(mainClass);
1383  
      return String.valueOf(m.invoke(null));
1384  
    } catch (Exception e) {
1385  
      throw new RuntimeException(e);
1386  
    }
1387  
  }
1388  
  
1389  
  static void testJava(Case case, Code code) {
1390  
    try {
1391  
      Method m = compileJavaInToOut(code);
1392  
      
1393  
      for (String[] e : case.fullExamples) {
1394  
        String out = (String) m.invoke(null, e[0]);
1395  
        
1396  
        if (!e[1].equals(out)) {
1397  
          throw new RuntimeException("[fail] Java code on " + quote(e[0]) + " - got: " + quote(out) + " rather than: " + quote(e[1]));
1398  
        }
1399  
      }
1400  
      
1401  
      System.out.println("\nGOOD JAVA.");
1402  
      case.goodJava = true;
1403  
    } catch (Throwable e) {
1404  
      if (showFails)
1405  
        e.printStackTrace();
1406  
      System.out.println("\nBAD JAVA.");
1407  
    }
1408  
  }
1409  
  
1410  
  static void todo() {
1411  
    fail("todo");
1412  
  }
1413  
  
1414  
  static class LSwitch extends LearnerImpl {
1415  
    Case case;
1416  
    Learner switcher;
1417  
    
1418  
    *(Case case, Learner switcher) {
1419  
      this.case = case;
1420  
      this.switcher = switcher;
1421  
    }
1422  
    
1423  
    public void processInOut(Object in, Object out) {
1424  
    }
1425  
   
1426  
    public Object processIn(Object in) {
1427  
      int i = Integer.parseInt((String) switcher.processIn(in));
1428  
      return case.combined.get(i-1).winner.processIn(in);
1429  
    }
1430  
   
1431  
    public void toJava(Code code) {
1432  
      todo();
1433  
    }
1434  
  }
1435  
 
1436  
  static class LTryPrevious extends LearnerImpl {
1437  
    new List<Case> candidates;
1438  
    
1439  
    *() {
1440  
      for (int i = caseIdx-1; i >= 0; i--)
1441  
        candidates.add(cases.get(i));
1442  
    }
1443  
1444  
    public void processInOut(Object _in, Object _out) {
1445  
      String in = (String) _in, out = (String) _out;
1446  
      for (ListIterator<Case> i = candidates.listIterator(); i.hasNext(); ) {
1447  
        Case case = i.next();
1448  
        if (case.winner == null || !validate(new String[] {in, out}, case.winner))
1449  
          i.remove();
1450  
      }
1451  
      if (candidates.isEmpty())
1452  
        fail("no previous solution found");
1453  
    }
1454  
  
1455  
    public Object processIn(Object in) {
1456  
      return candidates.get(0).winner.processIn(in);
1457  
    }
1458  
  
1459  
    public void toJava(Code code) {
1460  
      candidates.get(0).winner.toJava(code);
1461  
    }
1462  
  }
1463  
  
1464  
  static class LMulti extends LearnerImpl {
1465  
    static boolean debug;
1466  
    new List<Learner> candidates;
1467  
    
1468  
    *(Learner... learners) {
1469  
      for (Learner l : learners)
1470  
        candidates.add(l);
1471  
    }
1472  
    
1473  
    *(L<Learner> learners) {
1474  
      for (Learner l : learners)
1475  
        candidates.add(l);
1476  
    }
1477  
    
1478  
    public void processInOut(Object in, Object out) {
1479  
      if (debug)
1480  
        System.err.println("LMulti candidates: " + candidates.size());
1481  
      for (ListIterator<Learner> i = candidates.listIterator(); i.hasNext(); ) {
1482  
        Learner l = i.next();
1483  
        try {
1484  
          l.processInOut(in, out);
1485  
        } catch (Throwable e) {
1486  
          if (debug) {
1487  
            e.printStackTrace();
1488  
            System.err.println("Removing candidate: " + structure(l));
1489  
          }
1490  
          silentException(e);
1491  
          i.remove();
1492  
        }
1493  
      }
1494  
      if (debug)
1495  
        System.err.println("LMulti candidates now: " + candidates.size());
1496  
      if (candidates.isEmpty())
1497  
        fail("no candidates left");
1498  
    }
1499  
    
1500  
    public Object processIn(Object in) {
1501  
      while (true) { // fails or returns eventually
1502  
        Learner l = candidates.get(0);
1503  
        if (debug)
1504  
          System.err.println("Using candidate: " + structure(l) + ", " + candidates.size() + " left");
1505  
        try {
1506  
          return l.processIn(in);
1507  
        } catch (Throwable e) {
1508  
          if (debug) {
1509  
            e.printStackTrace();
1510  
            System.err.println("Removing candidate: " + structure(l));
1511  
          }
1512  
          silentException(e);
1513  
          candidates.remove(0);
1514  
        }
1515  
      }
1516  
    }
1517  
    
1518  
    public void tryAgain() {
1519  
      candidates.remove(0);
1520  
    }
1521  
    
1522  
    public void toJava(Code code) {
1523  
      candidates.get(0).toJava(code);
1524  
    }
1525  
  }
1526  
  
1527  
  static String structure(Object o) {
1528  
    String name = o.getClass().getName();
1529  
    
1530  
    new StringBuilder buf;
1531  
    
1532  
    if (o instanceof Collection) {
1533  
      for (Object x : (Collection) o) {
1534  
        if (!buf.isEmpty()) buf.append(", ");
1535  
        buf.append(structure(x));
1536  
      }
1537  
      return "{" + buf + "}";
1538  
    }
1539  
    
1540  
    // Need more cases? This should cover all library classes...
1541  
    if (name.startsWith("java.") || name.startsWith("javax."))
1542  
      return String.valueOf(o);
1543  
      
1544  
    String shortName = o.getClass().getName().replaceAll("^main\\$", "");
1545  
1546  
    // TODO: go to superclasses too
1547  
    Field[] fields = o.getClass().getDeclaredFields();
1548  
    for (Field field : fields) {
1549  
      if ((field.getModifiers() & Modifier.STATIC) != 0)
1550  
        continue;
1551  
      Object value;
1552  
      try {
1553  
        value = field.get(o);
1554  
      } catch (Exception e) {
1555  
        value = "?";
1556  
      }
1557  
      
1558  
      String fieldName = field.getName();
1559  
      
1560  
      // special case for LMulti - show only first (current) candidate
1561  
      if (shortName.equals("LMulti") && field.getName().equals("candidates")) {
1562  
        fieldName = "candidate";
1563  
        value = ((List) value).isEmpty() ? value : ((List) value).get(0);
1564  
      }
1565  
        
1566  
      if (!buf.isEmpty()) buf.append(", ");
1567  
      buf.append(fieldName + "=" + structure(value));
1568  
    }
1569  
    String s = shortName;
1570  
    if (!buf.isEmpty())
1571  
      s += "(" + buf + ")";
1572  
    return s;
1573  
  }
1574  
  
1575  
  static class FIsString implements Function {
1576  
    static boolean debug;
1577  
    
1578  
    public Object process(Object _in) {
1579  
      String in = (String) _in;
1580  
      return in.startsWith("\"") || in.startsWith("[[") ? "1" : "0";
1581  
    }
1582  
    
1583  
    public void toJava_process(Code code) {
1584  
      code.assign(code.s() + ".startsWith(\"\\\"\") || " + code.s() + ".startsWith(\"[[\") ? \"1\" : \"0\"");
1585  
    }
1586  
  }
1587  
  
1588  
  static class FCommonPrefix implements Function {
1589  
    static boolean debug;
1590  
1591  
    public Object process(Object _in) {
1592  
      String in = (String) _in, prefix = null;
1593  
      for (String line : toLines(in))
1594  
        if (line.length() != 0) {
1595  
          prefix = prefix == null ? line : commonPrefix(prefix, line);
1596  
          if (debug)
1597  
            System.out.println("FCommonPrefix: line=" + quote(line) + ", prefix=" + quote(prefix));
1598  
        }
1599  
      return prefix;
1600  
    }
1601  
    
1602  
    public void toJava_process(Code code) {
1603  
      todo();
1604  
    }
1605  
  }
1606  
  
1607  
  static class FCommonSuffix implements Function {
1608  
    static boolean debug;
1609  
1610  
    public Object process(Object _in) {
1611  
      String in = (String) _in, suffix = null;
1612  
      for (String line : toLines(in))
1613  
        if (line.length() != 0) {
1614  
          suffix = suffix == null ? line : commonSuffix(suffix, line);
1615  
          if (debug)
1616  
            System.out.println("FCommonSuffix: line=" + quote(line) + ", suffix=" + quote(suffix));
1617  
        }
1618  
      return suffix;
1619  
    }
1620  
    
1621  
    public void toJava_process(Code code) {
1622  
      todo();
1623  
    }
1624  
  }
1625  
  
1626  
  /*static class Pair {
1627  
    Object a, b;
1628  
    
1629  
    public boolean equals(Object o) {
1630  
      return o instanceof Pair && a.equals(((Pair) o).a) && b.equals((Pair) o).b);
1631  
    }
1632  
    
1633  
    public int hashCode() {
1634  
      return a.hashCode()+b.hashCode()*2;
1635  
    }
1636  
  }*/
1637  
  
1638  
  static class Matrix {
1639  
    new HashMap<Object, Map> dataByCol;
1640  
    
1641  
    void put(Object col, Object row, Object value) {
1642  
      //data.put(new Pair(col, row), value);
1643  
      getCol(col).put(row, value);
1644  
    }
1645  
    
1646  
    Map getCol(Object col) {
1647  
      Map map = dataByCol.get(col);
1648  
      if (map == null)
1649  
        dataByCol.put(col, map = new HashMap());
1650  
      return map;
1651  
    }
1652  
    
1653  
    Object get(Object col, Object row) {
1654  
      //return data.get(new Pair(col, row));
1655  
      return getCol(col).get(row);
1656  
    }
1657  
    
1658  
    Set cols() {
1659  
      return dataByCol.keySet();
1660  
    }
1661  
    
1662  
    Set rowsFor(Object col) {
1663  
      return getCol(col).keySet();
1664  
    }
1665  
  }
1666  
  
1667  
  static class LDistinguishList extends LearnerImpl {
1668  
    static boolean debug;
1669  
    Function helper;
1670  
    int idx;
1671  
    new Matrix matrix;
1672  
1673  
    *(Function helper) {
1674  
      this.helper = helper;
1675  
    }
1676  
    
1677  
    public void processInOut(Object _in, Object out) {
1678  
      List in = (List) _in;
1679  
      for (int i = 0; i < in.size(); i++) {
1680  
        Object y = helper.process(in.get(i));
1681  
        matrix.put(i, y, out);
1682  
      }
1683  
    }
1684  
    
1685  
    public Object processIn(Object _in) {
1686  
      // find idx
1687  
      
1688  
      for (Object i : matrix.cols()) {
1689  
        Collection ys = matrix.rowsFor(i);
1690  
        if (ys.size() > 1) {
1691  
          idx = (Integer) i;
1692  
          break;
1693  
        }
1694  
      }
1695  
      
1696  
      List in = (List) _in;
1697  
      Object y = helper.process(in.get(idx));
1698  
      return matrix.get(idx, y);
1699  
    }
1700  
    
1701  
    public void toJava(Code code) {
1702  
      List ys = new ArrayList(matrix.rowsFor(idx));
1703  
      //String v = code.var;
1704  
      //code.newVar();
1705  
      //String vy = code.var;
1706  
      //code.oldVar();
1707  
      code.assign(code.list() + ".get(" + idx + ")");
1708  
      helper.toJava_process(code);
1709  
      
1710  
      for (int i = 0; i < ys.size(); i++) {
1711  
        Object y = ys.get(i);
1712  
        if (i < ys.size())
1713  
          code.line((i == 0 ? "" : "else ") + "if (" + quote((String) y) + ".equals(" + code.var + "))");
1714  
        else
1715  
          code.line("else");
1716  
        code.line("  " + code.var + " = " + quote((String) matrix.get(idx, y)) + ";");
1717  
      }
1718  
    }
1719  
  }
1720  
  
1721  
  static class RunnersUp {
1722  
    String expected;
1723  
    int bestScore = -1;
1724  
    String bestResult;
1725  
    Learner winner;
1726  
    
1727  
    void add(String expected, String result, int score, Learner learner) {
1728  
      if (!expected.equals(this.expected) || bestScore == -1 || score < bestScore) {
1729  
        bestScore = score;
1730  
        bestResult = result;
1731  
        winner = learner;
1732  
      }
1733  
      this.expected = expected;
1734  
    }
1735  
  }
1736  
  
1737  
  !include #1000388 // leven (Levenshtein distance function)
1738  
  
1739  
  !include #1000382 // Box learners
1740  
  !include #1000387 // Empty box learner
1741  
  
1742  
}

Author comment

Began life as a copy of #694

download  show line numbers  debug dex  old transpilations   

Travelled to 16 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, jtubtzbbkimh, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, teubizvjbppd, tslmcundralx, tvejysmllsmz, vouqrxazstgt

Comments [hide]

ID Author/Program Comment Date
608 #1000610 (pitcher) 2015-08-18 00:07:07
607 #1000604 (pitcher) 2015-08-18 00:07:22

add comment

Snippet ID: #695
Snippet name: IOIOI Processor (v10)
Eternal ID of this version: #695/1
Text MD5: 21798cf9218936f9aacb6cca1ccdfaa2
Transpilation MD5: 37f3f9aa6e6b6bd9440e5521eb67ec5d
Author: stefan
Category:
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2015-08-03 01:30:33
Source code size: 53248 bytes / 1742 lines
Pitched / IR pitched: No / Yes
Views / Downloads: 1478 / 1541
Referenced in: [show references]