!7 !include once #1003474 // class E abstract sclass Learner { abstract void processInOut(S in, S out); abstract S processIn(S in); } static LMath learner; p { testPoem("#1003072"); // Addition Poem testPoem("#1003073"); // Division Poem print("OK!"); } static void testPoem(S snippetID) { learner = new LMath; L texts = loadPoems(snippetID); L test1 = parsePoem(texts.get(0).lines); L test2 = parsePoem(texts.get(1).lines); learner.processInOut(test1.get(0).q, test1.get(1).a); print("Test: " + assertTrue(runPoemTest1(test2))); } static void untest(L test) { for (E e : test) e.test = false; } // used by runPoemTest1 static L predict(L input) { if (l(input) != 1) ret null; new E e; S q = input.get(0).q; e.a = learner.processIn(q); print(q + " >> " + e.a + " " + structure(learner.possibleOperations)); ret litlist(e); } sclass LMath extends Learner { String allOperations = "+ - * /"; Set possibleOperations = new TreeSet(); String outPattern = ""; LMath() { restart(); } void restart() { possibleOperations.addAll(Arrays.asList(allOperations.split(" +"))); } void processInOut(String in, String out) { outPattern = out.replaceAll("-?\\d+", "*"); BigInteger[] inNumbers = extractIntsFromString(in); BigInteger[] outNumbers = extractIntsFromString(out); try { findOperation(inNumbers, outNumbers); } catch (Throwable e) { e.printStackTrace(); } } public void findOperation(BigInteger[] in, BigInteger[] out) { filterOperations(in, out); if (possibleOperations.isEmpty()) { System.out.println("TILT"); restart(); filterOperations(in, out); } } public void filterOperations(BigInteger[] in, BigInteger[] out) { for (Iterator i = possibleOperations.iterator(); i.hasNext(); ) { String op = i.next(); BigInteger[] out2 = doOperation(op, in); if (out2 == null || !arraysEqual(out, out2)) i.remove(); // keep only matching operations } } public BigInteger[] doOperation(String op, BigInteger[] in) { op = op.intern(); try { if (in.length == 2) { BigInteger a = in[0], b = in[1], x = null; if (op == "+") x = a.add(b); else if (op == "-") x = a.subtract(b); else if (op == "*") x = a.multiply(b); else if (op == "/") x = a.divide(b); return x != null ? new BigInteger[] {x} : null; } return null; } catch (Throwable e) { return null; } } String processIn(String in) { if (possibleOperations.isEmpty()) return ""; String op = possibleOperations.iterator().next(); BigInteger[] inNumbers = extractIntsFromString(in); BigInteger[] outNumbers = doOperation(op, inNumbers); String s = outPattern; if (outNumbers != null) for (BigInteger num : outNumbers) s = outPattern.replaceFirst("\\*", num.toString()); return s; } }