覆面算を満たすのは何通り?

awkネタ

覆面算とは、文字列で表された計算式で、同じ文字には同じ数字がはいり、違う文字には違う数字が入ります。
また、最上位の文字には0は入りません。
例えば、
We × love = CodeIQ
という式が与えられた時、以下のように当てはめることができます。
W = 7, e = 4, l = 3, o = 8, v = 0, C = 2, d = 1, I = 9 , Q = 6
この変換により、74 × 3804 = 281496という式が出来ます。
では、以下の式を満たすような数字の当てはめ方は何通りあるか求めてください。
READ + WRITE + TALK = SKILL

力任せに書けば、すんなり解けますね。

#!/usr/bin/awk -f

BEGIN{
    count = 0;
    for(r = 1; r <=9; r++){
        for(e = 0; e <= 9; e++){
            if(r == e){continue;}
            for(a = 0; a <= 9; a++){
                if(a == r ||a == e){continue;}
                for(d = 0; d <= 9; d++){
                    if(d == r || d == e || d == a){continue;}
                    for(w = 1; w <= 9; w++){
                        if(w == r || w == e || w == a || w == d){continue;}
                        for(i = 0; i <= 9; i++){
                            if(i == r || i == e || i == a || i == d || i == w){continue;}
                            for(t = 1; t <= 9; t++){
                                if(t == r || t == e || t == a || t == d || t == w || t == i){continue;}
                                for(l = 0; l <= 9; l++){
                                    if(l == r || l == e || l == a || l == d || l == w || l == i || l == t){continue;}
                                    for(k = 0; k <=9; k++){
                                        if(k == r || k == e || k == a || k == d || k == w || k == i || k == t || k == l){continue;}
                                        for(s = 1; s <= 9; s++){
                                            if(s == r || s == e || s == a || s == d || s == w || s == i || s == t || s == l || s == k){continue;}
                                            read = r * 1000 + e * 100 + a * 10 + d;
                                            write = w * 10000 + r * 1000 + i * 100 + t * 10 + e;
                                            talk = t * 1000 + a * 100 + l * 10 + k;
                                            skill = s * 10000 + k * 1000 + i * 100 + l * 10 + l;
                                            if(read + write + talk == skill){
                                                count++;
                                                print read "+" write "+" talk "=" skill;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    print count;
}

実行してみます。

 awk -f q13.awk
1632+41976+7380=50988
2543+72065+6491=81099
4905+24689+8017=37611
5094+75310+1962=82366
5096+35710+1982=42788
5180+65921+2843=73944
5270+85132+3764=94166
7092+37510+1986=46588
7092+47310+1986=56388
9728+19467+6205=35400
10

10通りもありました。