fork(5) download
  1. import java.util.Arrays;
  2. import java.util.Scanner;
  3. import java.util.regex.Matcher;
  4. import java.util.regex.Pattern;
  5.  
  6. class Alphametic
  7. {
  8. public static void main(String[] args)
  9. {
  10. try (Scanner in = new Scanner(System.in))
  11. {
  12. while (in.hasNextLine())
  13. {
  14. new Alphametic(in.nextLine()).print();
  15. }
  16. }
  17. }
  18.  
  19. private static Pattern pat = Pattern.compile("([0-9A-Z]+)([+-\\\\*])([0-9A-Z]+)=([0-9A-Z]+)");
  20. private final String sa;
  21. private final String sb;
  22. private final String sc;
  23. private final String op;
  24. private final String[] st;
  25. private final Op operator;
  26. private final int e;
  27.  
  28. private final int[] map = new int[256];
  29. private final boolean[] used = new boolean[10];
  30. private String[] result = new String[0];
  31.  
  32. private Alphametic(String exp)
  33. {
  34. Matcher mat = pat.matcher(exp);
  35. if (!mat.matches()) throw new IllegalArgumentException();
  36.  
  37. this.sa = mat.group(1);
  38. this.op = mat.group(2);
  39. this.sb = mat.group(3);
  40. this.sc = mat.group(4);
  41. this.st = new String[] { sa, sb, sc };
  42. switch(op)
  43. {
  44. case "+": operator = (a, b) -> a + b; break;
  45. case "-": operator = (a, b) -> a - b; break;
  46. case "*": operator = (a, b) -> a * b; break;
  47. default: throw new IllegalArgumentException();
  48. }
  49.  
  50. for (int i = 0; i <= 9; i++) map['0' + i] = i;
  51. for (int i = 'A'; i <= 'Z'; i++) map[i] = i;
  52. e = Math.max(Math.max(sa.length(), sb.length()), sc.length()) * 3;
  53. solve(0, new long[3], 1);
  54. }
  55.  
  56. private void solve(int p, long[] ls, long d)
  57. {
  58. if (p == e)
  59. {
  60. if (!operator.test(ls[0], ls[1], ls[2], Long.MAX_VALUE)) return;
  61. for (String s : st) if (map[s.charAt(0)] <= 0) return;
  62. result = Arrays.copyOf(result, result.length + 1);
  63. result[result.length - 1] = String.format("%d%s%d=%d", ls[0], op, ls[1], ls[2]);
  64. return;
  65. }
  66.  
  67. int i = p / 3;
  68. int j = p % 3;
  69. if (p > 0 && j == 0)
  70. {
  71. d *= 10;
  72. if (!operator.test(ls[0], ls[1], ls[2], d)) return;
  73. }
  74.  
  75. int n = ch(st[j], i);
  76. long l = ls[j];
  77.  
  78. if (n >= 'A' && n <= 'Z')
  79. {
  80. for (int k = 0; k < 10; k++)
  81. {
  82. if (used[k]) continue;
  83. used[k] = true;
  84. map[n] = k;
  85. ls[j] = l + k * d;
  86. solve(p + 1, ls, d);
  87. used[k] = false;
  88. }
  89. map[n] = n;
  90. }
  91. else
  92. {
  93. ls[j] += n * d;
  94. solve(p + 1, ls, d);
  95. }
  96. ls[j] = l;
  97. }
  98.  
  99. private int ch(String s, int i)
  100. {
  101. return s.length() <= i ? 0 : map[s.charAt(s.length() - i - 1)];
  102. }
  103.  
  104. void print()
  105. {
  106. System.out.printf("%s%s%s=%s%n", sa, op, sb, sc);
  107. for (String s : result) System.out.println(s);
  108. System.out.println();
  109. }
  110.  
  111. private interface Op
  112. {
  113. long op(long a, long b);
  114.  
  115. default boolean test(long a, long b, long c, long d)
  116. {
  117. return Math.abs(op(a, b) - c) % d == 0;
  118. }
  119. }
  120. }
  121.  
Success #stdin #stdout 0.24s 321152KB
stdin
SEND+MORE=MONEY
WWWDOT-GOOGLE=DOTCOM
AB2DEF*2=2DEFAB
ABA*ABA=CCDCC
stdout
SEND+MORE=MONEY
9567+1085=10652

WWWDOT-GOOGLE=DOTCOM
777589-188103=589486
777589-188106=589483

AB2DEF*2=2DEFAB
142857*2=285714

ABA*ABA=CCDCC
212*212=44944