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

1521
LINES

< > BotCompany Repo | #694 // IOIOI Processor (v9)

JavaX source code - run with: x30.jar

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

Author comment

Began life as a copy of #693

download  show line numbers  debug dex  old transpilations   

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

Comments [hide]

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

add comment

Snippet ID: #694
Snippet name: IOIOI Processor (v9)
Eternal ID of this version: #694/1
Text MD5: 7b5a02bb408e2d88dec73d98b4e077ce
Author: stefan
Category:
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2015-07-31 15:03:14
Source code size: 45894 bytes / 1521 lines
Pitched / IR pitched: No / Yes
Views / Downloads: 1479 / 1140
Referenced in: [show references]