!636 !quickmain !auto-import import java.math.*; // BigInteger interface Learner { void processInOut(String in, String out); String processIn(String in); } main { psvm { print "\nHello. Teach me math." LMath learner = new LMath(); while (true) { String in = readLine("\nQ: "); in = in.trim(); if (in.equals("restart")) { System.out.println("[restart]"); learner.restart(); continue; } if (in.length() == 0) break; String guess = learner.processIn(in); if (guess != null && guess.length() != 0) { System.out.println(in + " => " + guess); String ok = readLine("\nOK (y/n)? "); ok = ok.toLowerCase().trim(); boolean yes = ok.startsWith("y") || ok.startsWith("j"); if (yes) { print ":)" // OPTIONAL - indicate that guess was OK: learner.processInOut(in, guess); continue; } else { print "Oops." // query correcting answer from user } } else { print "I don't know." } String out = readLine(in + " => "); out = out.trim(); learner.processInOut(in, out); System.out.println("OK. " + in + " => " + out); } } static Scanner system_in = new Scanner(System.in); static String readLine(String prompt) { System.out.print(prompt); return system_in.nextLine(); } static BigInteger[] getNumbers(String s) { Pattern p = Pattern.compile("-?\\d+"); Matcher m = p.matcher(s); List list = new ArrayList(); while (m.find()) list.add(new BigInteger(m.group())); return list.toArray(new BigInteger[list.size()]); } static boolean arraysEqual(BigInteger[] a, BigInteger[] b) { if (a.length != b.length) return false; for (int i = 0; i < a.length; i++) if (!a[i].equals(b[i])) return false; return true; } static class LMath implements Learner { String allOperations = "+ - * /"; Set possibleOperations = new TreeSet(); String outPattern = ""; LMath() { restart(); } void restart() { possibleOperations.addAll(Arrays.asList(allOperations.split(" +"))); } public void processInOut(String in, String out) { outPattern = out.replaceAll("-?\\d+", "*"); BigInteger[] inNumbers = getNumbers(in); BigInteger[] outNumbers = getNumbers(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; } } public String processIn(String in) { if (possibleOperations.isEmpty()) return ""; String op = possibleOperations.iterator().next(); BigInteger[] inNumbers = getNumbers(in); BigInteger[] outNumbers = doOperation(op, inNumbers); String s = outPattern; if (outNumbers != null) for (BigInteger num : outNumbers) s = outPattern.replaceFirst("\\*", num.toString()); return s; } } }