fork 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. // ここから
  51. used[0] = true;
  52. used[3] = true;
  53. used[4] = true;
  54. // ここまで追加
  55.  
  56. for (int i = 0; i <= 9; i++) map['0' + i] = i;
  57. for (int i = 'A'; i <= 'Z'; i++) map[i] = i;
  58. e = Math.max(Math.max(sa.length(), sb.length()), sc.length()) * 3;
  59. solve(0, new long[3], 1);
  60. }
  61.  
  62. private void solve(int p, long[] ls, long d)
  63. {
  64. if (p == e)
  65. {
  66. if (!operator.test(ls[0], ls[1], ls[2], Long.MAX_VALUE)) return;
  67. for (String s : st) if (map[s.charAt(0)] <= 0) return;
  68. result = Arrays.copyOf(result, result.length + 1);
  69. result[result.length - 1] = String.format("%d%s%d=%d", ls[0], op, ls[1], ls[2]);
  70. return;
  71. }
  72.  
  73. int i = p / 3;
  74. int j = p % 3;
  75. if (p > 0 && j == 0)
  76. {
  77. d *= 10;
  78. if (!operator.test(ls[0], ls[1], ls[2], d)) return;
  79. }
  80.  
  81. int n = ch(st[j], i);
  82. long l = ls[j];
  83.  
  84. if (n >= 'A' && n <= 'Z')
  85. {
  86. for (int k = 0; k < 10; k++)
  87. {
  88. if (used[k]) continue;
  89. used[k] = true;
  90. map[n] = k;
  91. ls[j] = l + k * d;
  92. solve(p + 1, ls, d);
  93. used[k] = false;
  94. }
  95. map[n] = n;
  96. }
  97. else
  98. {
  99. ls[j] += n * d;
  100. solve(p + 1, ls, d);
  101. }
  102. ls[j] = l;
  103. }
  104.  
  105. private int ch(String s, int i)
  106. {
  107. return s.length() <= i ? 0 : map[s.charAt(s.length() - i - 1)];
  108. }
  109.  
  110. void print()
  111. {
  112. System.out.printf("%s%s%s=%s%n", sa, op, sb, sc);
  113. for (String s : result) System.out.println(s);
  114. System.out.println();
  115. }
  116.  
  117. private interface Op
  118. {
  119. long op(long a, long b);
  120.  
  121. default boolean test(long a, long b, long c, long d)
  122. {
  123. return Math.abs(op(a, b) - c) % d == 0;
  124. }
  125. }
  126. }
Success #stdin #stdout 0.15s 4386816KB
stdin
ABC4D-E3FG=77777
stdout
ABC4D-E3FG=77777
87142-9365=77777