Task: Vampire number



C#: using System;

namespace RosettaVampireNumber
{
    class Program
    {
        static void Main(string[] args)
        {
            int i, j, n;
            ulong x;
            var f = new ulong[16];
            var bigs = new ulong[] { 16758243290880UL, 24959017348650UL, 14593825548650UL, 0 };
            ulong[] tens = new ulong[20];
            tens[0] = 1;
            for (i = 1; i < 20; i++)
                tens[i] = tens[i - 1] * 10;
            
            for (x = 1, n = 0; n < 25; x++)
            {
                if ((j = fangs(x, f, tens)) == 0) continue;
                Console.Write(++n + ": ");
                show_fangs(x, f, j);
            }

            Console.WriteLine();
            for (i = 0; bigs[i] > 0 ; i++)
            {
                if ((j = fangs(bigs[i], f, tens)) > 0)
                    show_fangs(bigs[i], f, j);
                else
                    Console.WriteLine(bigs[i] + " is not vampiric.");
            }
            Console.ReadLine();
        }

        private static void show_fangs(ulong x, ulong[] f, int cnt)
        {
            Console.Write(x); 
            int i;
            for (i = 0; i < cnt; i++)
                Console.Write(" = " + f[i] + " * " + (x / f[i]));
            Console.WriteLine();
        }

        private static int fangs(ulong x, ulong[] f, ulong[] tens)
        {
            int n = 0;
            int nd = ndigits(x);
            if ((nd & 1) > 0) return 0;
            nd /= 2;

            ulong lo, hi;
            lo = Math.Max(tens[nd - 1], (x + tens[nd] - 2) / (tens[nd] - 1));
            hi = Math.Min(x / lo, (ulong) Math.Sqrt(x));

            ulong a, b, t = dtally(x);
            for (a = lo; a <= hi; a++)
            {
                b = x / a;
                if (a * b == x && ((a % 10) > 0 || (b % 10) > 0) && t == dtally(a) + dtally(b))
                    f[n++] = a;
            }

            return n;
        }

        private static ulong dtally(ulong x)
        {
            ulong t = 0;
            while (x > 0)
            {
                t += 1UL << (int)((x % 10) * 6);
                x /= 10;
            }

            return t;
        }

        private static int ndigits(ulong x)
        {
            int n = 0;
            while (x > 0)
            {
                n++;
                x /= 10;
            }
            return n;
        }
    }
}





Python: from __future__ import division

import math
from operator import mul
from itertools import product
from functools import reduce


def fac(n):
    
    step = lambda x: 1 + x*4 - (x//2)*2
    maxq = int(math.floor(math.sqrt(n)))
    d = 1
    q = n % 2 == 0 and 2 or 3 
    while q <= maxq and n % q != 0:
        q = step(d)
        d += 1
    res = []
    if q <= maxq:
        res.extend(fac(n//q))
        res.extend(fac(q)) 
    else: res=[n]
    return res

def fact(n):
    
    res = fac(n)
    return [(c, res.count(c)) for c in set(res)]

def divisors(n):
    'Returns all the divisors of n'
    factors = fact(n)   
    primes, maxpowers = zip(*factors)
    powerranges = (range(m+1) for m in maxpowers)
    powers = product(*powerranges)
    return (
        reduce(mul,
               (prime**power for prime, power in zip(primes, powergroup)),
               1)
        for powergroup in powers)
    
def vampire(n):
    fangsets = set( frozenset([d, n//d])
                    for d in divisors(n)
                    if (len(str(d)) == len(str(n))/2.
                        and sorted(str(d) + str(n//d)) == sorted(str(n))
                        and (str(d)[-1] == 0) + (str(n//d)[-1] == 0) <=1) )
    return sorted(tuple(sorted(fangs)) for fangs in fangsets)
    

if __name__ == '__main__':
    print('First 25 vampire numbers')
    count = n = 0
    while count <25:
        n += 1
        fangpairs = vampire(n)
        if fangpairs:
            count += 1
            print('%i: %r' % (n, fangpairs))
    print('\nSpecific checks for fangpairs')
    for n in (16758243290880, 24959017348650, 14593825548650):
        fangpairs = vampire(n)
        print('%i: %r' % (n, fangpairs))