Task: Vampire number


C++: #include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <cmath>
 
bool isVampireNumber( long number, std::vector<std::pair<long, long> > & solution ) {
   std::ostringstream numberstream ;
   numberstream << number ;
   std::string numberstring( numberstream.str( ) ) ;
   std::sort ( numberstring.begin( ) , numberstring.end( ) ) ;
   int fanglength = numberstring.length( ) / 2 ;
   long start = static_cast<long>( std::pow( 10 , fanglength - 1 ) ) ;
   long end = sqrt(number) ;
   for ( long i = start ; i <= end ; i++ ) { 
      if ( number % i == 0 ) {
	 long quotient = number / i ;
	 if ( ( i % 10 == 0 ) && ( quotient % 10 == 0 ) ) 
	    continue ;
	 numberstream.str( "" ) ; 
	 numberstream << i << quotient ;
	 std::string divisorstring ( numberstream.str( ) ) ;
         std::sort ( divisorstring.begin( ) , divisorstring.end( ) ) ;
	 if ( divisorstring == numberstring ) {
	    std::pair<long , long> divisors = std::make_pair( i, quotient ) ;
	    solution.push_back( divisors ) ;
	 }
      }
   }
   return !solution.empty( ) ;
}
 
void printOut( const std::pair<long, long> & solution ) {
   std::cout << "[ " << solution.first << " , " << solution.second << " ]" ;
}
 
int main( ) {
   int vampireNumbersFound = 0 ;
   std::vector<std::pair<long , long> > solutions ;
   double i = 1.0 ;
   while ( vampireNumbersFound < 25 ) {
      long start = static_cast<long>( std::pow( 10 , i ) ) ;
      long end = start * 10 ;
      for ( long num = start ; num < end ; num++ ) {
	 if ( isVampireNumber( num , solutions ) ) {
            vampireNumbersFound++ ;
	    std::cout << vampireNumbersFound << " :" << num << " is a vampire number! These are the fangs:\n" ;
	    std::for_each( solutions.begin( ) , solutions.end( ) , printOut ) ;
	    std::cout << "\n_______________" << std::endl ;
	    solutions.clear( ) ;	    
	    if ( vampireNumbersFound == 25 ) 
	       break ;
	 }
      }
      i += 2.0 ;
   }
   std::vector<long> testnumbers ;
   testnumbers.push_back( 16758243290880 ) ;
   testnumbers.push_back( 24959017348650 ) ;
   testnumbers.push_back( 14593825548650 ) ;
   for ( std::vector<long>::const_iterator svl = testnumbers.begin( ) ; 
	 svl != testnumbers.end( ) ; svl++ ) {
      if ( isVampireNumber( *svl , solutions ) ) {
	 std::cout << *svl << " is a vampire number! The fangs:\n" ;
	 std::for_each( solutions.begin( ) , solutions.end( ) , printOut ) ;
	 std::cout << std::endl ;
	 solutions.clear( ) ;
      } else {
	 std::cout << *svl << " is not a vampire number!" << std::endl ;
      }
   }
   return 0 ;
}






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))