92 lines
2.1 KiB
D
92 lines
2.1 KiB
D
import std.stdio, std.math, std.algorithm, std.array, std.traits;
|
|
|
|
T[N] pows(T, size_t N)() pure nothrow @safe @nogc {
|
|
typeof(return) result;
|
|
result[0] = 1;
|
|
foreach (immutable i, ref r; result[1 .. $])
|
|
r = result[i] * 10;
|
|
return result;
|
|
}
|
|
|
|
__gshared immutable tenPowsU = pows!(uint, 10);
|
|
__gshared immutable tenPowsUL = pows!(ulong, 20);
|
|
|
|
size_t nDigits(T)(in T x) pure nothrow @safe @nogc {
|
|
Unqual!T y = x;
|
|
size_t n = 0;
|
|
while (y) {
|
|
n++;
|
|
y /= 10;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
T dTally(T)(in T x) pure nothrow @safe @nogc {
|
|
Unqual!T y = x;
|
|
T t = 0;
|
|
while (y) {
|
|
t += 1 << ((y % 10) * 6);
|
|
y /= 10;
|
|
}
|
|
return t;
|
|
}
|
|
|
|
T[] fangs(T)(in T x, T[] f)
|
|
pure nothrow @safe @nogc if (is(T == uint) || is(T == ulong)) {
|
|
alias tenPows = Select!(is(T == ulong), tenPowsUL, tenPowsU);
|
|
|
|
immutable nd0 = nDigits(x);
|
|
if (nd0 & 1)
|
|
return null;
|
|
immutable nd = nd0 / 2;
|
|
|
|
immutable lo = max(tenPows[nd - 1],
|
|
(x + tenPows[nd] - 2) / (tenPows[nd] - 1));
|
|
immutable hi = min(x / lo, cast(T)sqrt(real(x)));
|
|
immutable t = x.dTally;
|
|
|
|
size_t n = 0;
|
|
foreach (immutable a; lo .. hi + 1) {
|
|
immutable b = x / a;
|
|
if (a * b == x
|
|
&& (a % 10 || b % 10)
|
|
&& t == (a.dTally + b.dTally)) {
|
|
f[n] = a;
|
|
n++;
|
|
}
|
|
}
|
|
|
|
return f[0 .. n];
|
|
}
|
|
|
|
void showFangs(T)(in T x, in T[] fs) {
|
|
x.write;
|
|
foreach (immutable fi; fs)
|
|
writef(" = %d x %d", fi, x / fi);
|
|
writeln;
|
|
}
|
|
|
|
void main() {
|
|
uint[16] fu;
|
|
for (uint x = 1, n = 0; n < 25; x++) {
|
|
const fs = fangs(x, fu);
|
|
if (fs.empty)
|
|
continue;
|
|
n++;
|
|
writef("%2d: ", n);
|
|
showFangs(x, fs);
|
|
}
|
|
writeln;
|
|
|
|
static immutable ulong[3] bigs = [16_758_243_290_880UL,
|
|
24_959_017_348_650UL,
|
|
14_593_825_548_650UL];
|
|
ulong[fu.length] ful;
|
|
foreach (immutable bi; bigs) {
|
|
const fs = fangs(bi, ful);
|
|
if (fs.empty)
|
|
writeln(bi, " is not vampiric");
|
|
else
|
|
showFangs(bi, fs);
|
|
}
|
|
}
|