Yet another brute force (C) version, with a free bubble sort to boot...
#include <stdio.h>
static inline void bubsort(int *p)
{ while (1)
{ int s = 0;
for (int i = 0; i < 3; ++i)
if (p[i] > p[i + 1])
{ s = 1;
int t = p[i]; p[i] = p[i + 1]; p[i + 1] = t;
}
if (!s) break;
}
}
int main()
{ for (int i = 10; i < 100; ++i)
for (int j = i; j < 100; ++j)
{ int p = i * j;
if (p < 1000) continue;
int xd[4];
xd[0] = i % 10;
xd[1] = i / 10;
xd[2] = j % 10;
xd[3] = j / 10;
bubsort(xd);
int x = xd[0] + xd[1] * 10 + xd[2] * 100 + xd[3] * 1000;
int yd[4];
yd[0] = p % 10;
yd[1] = (p / 10) % 10;
yd[2] = (p / 100) % 10;
yd[3] = (p / 1000);
bubsort(yd);
int y = yd[0] + yd[1] * 10 + yd[2] * 100 + yd[3] * 1000;
if (x == y)
printf("%2d * %2d = %4d\n", i, j, p);
}
return 0;
}
Runs pretty much instantaneously. Variable names aren't too descriptive, but should be pretty obvious...
The basic idea is to start with two potential fangs, break them down into digits, and sort the digits for easy comparison. Then we do the same with the product - break it down to digits and sort. Then we re-constitute two integers from the sorted digits, and if they're equal, we have a match.
Possible improvements: 1) start j
at 1000 / i
instead of i
to avoid having to do if (p < 1000) ...
, 2) maybe use insertion sort instead of bubble sort (but who's gonna notice those 2 extra swaps?), 3) use a real swap()
implementation, 4) compare the arrays directly rather than building a synthetic integer out of them. Not sure any of those would make any measurable difference, though, unless you run it on a Commodore 64 or something...
Edit: Just out of curiosity, I took this version and generalized it a bit more to work for the 4, 6 and 8 digit cases - without any major optimization, it can find all the 8-digit vampire numbers in < 10 seconds...
1000
which means10 * 00
, check if the result is a vampire. – Maarten Bodewes