特に抽象的な洞察に頼らずに可能な限り少ないテストを実行するには、おそらく牙を繰り返して、明らかに無意味な候補を選別する必要があるようです。
たとえば、x*y == y*x
検索スペースの約半分は、y > x
. 最大の 2 桁の牙が 99 である場合、4 桁の数を作成できる最小の牙は 11 であるため、11 未満で開始しないでください。
編集:
OK、私が考えたすべてをミックスに投入します (主要なソリューションに対してはばかげているように見えますが)。
for (x = 11; x < 100; x++)
{
/* start y either at x, or if x is too small then 1000 / x */
for (y = (x * x < 1000 ? 1000 / x : x); y < 100; y++)
{
int p = x * y;
/* if sum of digits in product is != sum of digits in x+y, then skip */
if ((p - (x + y)) % 9 != 0)
continue;
if (is_vampire(p, x, y))
printf("%d\n", p);
}
}
誰もヒストグラムを使用していないので、テストはまだ:
int is_vampire(int p, int x, int y)
{
int h[10] = { 0 };
int i;
for (i = 0; i < 4; i++)
{
h[p % 10]++;
p /= 10;
}
for (i = 0; i < 2; i++)
{
h[x % 10]--;
h[y % 10]--;
x /= 10;
y /= 10;
}
for (i = 0; i < 10; i++)
if (h[i] != 0)
return 0;
return 1;
}