Vampire number

From Rosetta Code
Revision as of 13:11, 22 March 2013 by rosettacode>Fwend (→‎{{header|D}}: added D)
Vampire number is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

A Vampire number is a natural number with an even number of digits, that can be factored into two integers. These 2 factors are called the fangs, and must have the following properties:

  • they each have half the number of the digits of the orginal number
  • together they consist of exactly the same digits as the orginal number
  • at most one of them has a trailing zero

An example of a Vampire number and its fangs: 1260 : (21, 60)

Task description:

  1. Print the first 25 Vampire numbers and their fangs.
  2. Check if the following numbers are vampire numbers and, if so, print them and their fangs: 16758243290880, 24959017348650, 14593825548650

Note that a Vampire number can have more than 1 pair of fangs.

Cf:


D <lang d>import std.stdio, std.algorithm;

void main() {

   for (long n, count; n < 250_000L && count < 25; n++)
       if (auto factors = vampireNumberFactors(n)) {
           writefln("%s : %(%s %)", n, factors);
           count++;
        }
   writeln();
   foreach (n; [16758243290880L, 24959017348650L, 14593825548650L])
       if (auto factors = vampireNumberFactors(n))
           writefln("%s : %(%s %)", n, factors);

}

long[2][] vampireNumberFactors(in long n) {

   long[2][] factorPairs(in long k) pure {
       typeof(return) res;
       foreach (i; 2 .. cast(long) (k ^^ 0.5 + 1)) {
           if (k % i == 0) {
               long q = k / i;
               if (q > i)
                   res ~= [i, q];
           }
       }
       return res;
   }
   long[] getDigits(in long k) pure {
       typeof(return) digits;
       long m = k;
       while (m > 0) {
           digits ~= (m % 10);
           m /= 10;
       }
       return digits.reverse;
   }
   if (n < 2) return null;
   typeof(return) result;
   auto digits = getDigits(n).sort().release();
   if (digits.length & 1)
       return null;
   immutable half = digits.length / 2;
   foreach (pair; factorPairs(n)) {
       auto f1 = getDigits(pair[0]);
       if (f1.length != half)
           continue;
       auto f2 = getDigits(pair[1]);
       if (f2.length != half)
           continue;
       if (f1[$-1] == 0 && f2[$-1] == 0)
           continue;
       if (digits != (f1 ~ f2).sort().release())
           continue;
       result ~= pair;
   }
   return result;

}</lang>

Output:
1260 : [21, 60]
1395 : [15, 93]
1435 : [35, 41]
1530 : [30, 51]
1827 : [21, 87]
2187 : [27, 81]
6880 : [80, 86]
102510 : [201, 510]
104260 : [260, 401]
105210 : [210, 501]
105264 : [204, 516]
105750 : [150, 705]
108135 : [135, 801]
110758 : [158, 701]
115672 : [152, 761]
116725 : [161, 725]
117067 : [167, 701]
118440 : [141, 840]
120600 : [201, 600]
123354 : [231, 534]
124483 : [281, 443]
125248 : [152, 824]
125433 : [231, 543]
125460 : [204, 615] [246, 510]
125500 : [251, 500]

16758243290880 : [1982736, 8452080] [2123856, 7890480] [2751840, 6089832] [2817360, 5948208]
24959017348650 : [2947050, 8469153] [2949705, 8461530] [4125870, 6049395] [4129587, 6043950] [4230765, 5899410]