/*
http://p...content-available-to-author-only...h.net/test/read.cgi/tech/1402622093/81
[ プログラム ] プログラミングのお題スレ Part4

81 名前：デフォルトの名無しさん [sage]： 2014/06/20(金) 00:35:34.20 ID:eyF0lSTD
お題：0から9のうち8種類の数字を使って4桁の10進数を2個つくり、その積をとると
4桁の2個の数に使用した8種類の数字はひとつも現れなかった。
この4桁の2個の10進数を求める。
*/
#include<stdio.h>
#include<stdlib.h>

//左辺と右辺で同じ数字があるか探す
//  -1:同じ数字あり
//   0:なし
//  -2:左の項が右より大きくなったので、重複回避のため計算しない
int keisan(int *res, int *a)
{
    int r, x, i, aa, bb;

    aa = a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3];
    bb = a[4] * 1000 + a[5] * 100 + a[6] * 10 + a[7];
    if (aa > bb)
        return -2;
    r = *res = aa * bb;
    while (r) {
        x = r % 10;
        for (i = 0; i < 8; i++)
            if (a[i] == x)
                return -1;
        r /= 10;
    }

    return 0;
}

//左辺に同じ数字があるか探す
//  -1: 同じ数字あり
//   0: ok
int check(int *a, int n)
{
    int i;

    for (i = 0; i < n; i++)
        if (a[i] == a[n])
            return -1;

    return 0;
}

//
int main()
{
    int a[8], r;

    for (a[0] = 1; a[0] < 10; a[0]++) {
    for (a[1] = 0; a[1] < 10; a[1]++) { if (check(a, 1)) continue;
    for (a[2] = 0; a[2] < 10; a[2]++) { if (check(a, 2)) continue;
    for (a[3] = 0; a[3] < 10; a[3]++) { if (check(a, 3)) continue;
    for (a[4] = 1; a[4] < 10; a[4]++) { if (check(a, 4)) continue;
    for (a[5] = 0; a[5] < 10; a[5]++) { if (check(a, 5)) continue;
    for (a[6] = 0; a[6] < 10; a[6]++) { if (check(a, 6)) continue;
    for (a[7] = 0; a[7] < 10; a[7]++) { if (check(a, 7)) continue;
        switch (keisan(&r, a)) {
            case -1:
            case -2:
                break;
            case 0:
                printf("%d%d%d%d x %d%d%d%d = %d\n", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], r);
                break;
            default:
                fprintf(stderr, "err\n");
                exit(1);
        }
    } } } } } } } }

    return 0;
}
