// 覆面算: SEND+MORE=MONEY となる S,E,N,D,M,O,R,Y を見つける // プログラム中では文字S〜Yを整数の配列の0〜7番目の要素に対応させる class Alphametics { // 組み合わせnが上の式を満たしているかを調べ、満たしていれば表示 static void checkExpression(int[] n) { int S=n[0], E=n[1], N=n[2], D=n[3], M=n[4], O=n[5], R=n[6], Y=n[7]; int SEND = S*1000+E*100+N*10+D, MORE = M*1000+O*100+R*10+E, MONEY = M*10000+O*1000+N*100+E*10+Y; if (S!=0 && M!=0 // 各最上位桁は非零 && SEND+MORE == MONEY) // 式のチェック System.out.println(SEND+ "+" + MORE + "=" + MONEY); } // 組み合わせnumbersの0〜index-1要素にxが含まれているかを調べる static boolean used(int[] numbers, int index, int x) { // 0からindex-1桁目までの要素について調べる for (int i = 0; i < index; i=i+1) if (numbers[i] == x) // xはnumbersに含まれているのでtrueを返す return true; // 繰り返しが終了した場合、xはnumbersに含まれていなかったのでfalse return false; } // numbers[0]..numbers[index-1] に1桁の数の重複のない組み合わせが // があるとき、index桁目以降の数を決める static void combination(int[] numbers, int index) { if (index == numbers.length) // 全ての桁が決った場合 checkExpression(numbers); // その数が条件を満たしているかを調べる else { // 次の1桁(nextNumber)として 0 から 9 を全て試す for (int nextNumber = 0; nextNumber < 10; nextNumber=nextNumber+1) { // numbers[0]..numbers[index-1]にnextNumberが含まれているかを調べ if (!used(numbers,index,nextNumber)) { // 含まれていなければ numbers[index] = nextNumber; // index桁目にセットして combination(numbers, index+1); // index+1桁目以降を決める } } } } public static void main(String[] args) { int[] numbers = new int[8]; // 8桁の数を覚える配列を作る combination(numbers,0); // 最初の桁から決めてゆく } }
Hidehiko Masuhara, November 2000