// math operations. // input: L (list of numbers) // output: S (number) static class LMath extends LearnerImpl { static boolean debug; String allOperations = "+ - * /"; new (Tree)Set possibleOperations; LMath() { possibleOperations.addAll(Arrays.asList(allOperations.split(" +"))); } public void processInOut(Object _in, Object _out) { List in = (List) _in; String out = (String) _out; BigInteger[] inNumbers = makeBigIntArray(in); BigInteger[] outNumbers = new BigInteger[] {bigint(out)}; findOperation(inNumbers, outNumbers); if (debug) System.out.println("Operations: " + possibleOperations); } public void findOperation(BigInteger[] in, BigInteger[] out) { filterOperations(in, out); if (possibleOperations.isEmpty()) fail("tilt"); } 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; } } public String processIn(Object _in) { L in = cast _in; String op = possibleOperations.iterator().next(); if (debug) System.out.println("op: " + op); BigInteger[] inNumbers = makeBigIntArray(in); BigInteger[] outNumbers = doOperation(op, inNumbers); return outNumbers[0].toString(); } String BI = BigInteger.class.getName(); public void toJava(Code code) { String op = possibleOperations.iterator().next(); String a = "new " + BI + "((String) " + code.list() + ".get(0))"; String b = "new " + BI + "((String) " + code.list() + ".get(1))"; if (op.equals("+")) code.assign(a + ".add(" + b + ").toString()"); else todo(); } }