Task: Vampire number

C: #include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>

typedef uint64_t xint;
typedef unsigned long long ull;

xint tens[20];

inline xint max(xint a, xint b) { return a > b ? a : b; }
inline xint min(xint a, xint b) { return a < b ? a : b; }
inline int ndigits(xint x)
{
	int n = 0;
	while (x) n++, x /= 10;
	return n;
}

inline xint dtally(xint x)
{
	xint t = 0;
	while (x) t += 1<<((x%10) * 6), x /= 10;

	return t;
}

int fangs(xint x, xint *f)
{
	int n = 0;
	int nd = ndigits(x);
	if (nd & 1) return 0;
	nd /= 2;

	xint lo, hi;
	lo = max(tens[nd-1], (x + tens[nd] - 2)/ (tens[nd] - 1));
	hi = min(x / lo, sqrt(x));

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

	return n;
}

void show_fangs(xint x, xint *f, xint cnt)
{
	printf("%llu", (ull)x);
	int i;
	for (i = 0; i < cnt; i++)
		printf(" = %llu x %llu", (ull)f[i], (ull)(x / f[i]));
	putchar('\n');
}

int main(void)
{
	int i, j, n;
	xint x, f[16], bigs[] = {16758243290880ULL, 24959017348650ULL, 14593825548650ULL, 0};

	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))) continue;
		printf("%2d: ", ++n);
		show_fangs(x, f, j);
	}

	putchar('\n');
	for (i = 0; bigs[i]; i++) {
		if ((j = fangs(bigs[i], f)))
			show_fangs(bigs[i], f, j);
		else
			printf("%llu is not vampiric\n", (ull)bigs[i]);
	}

	return 0;
}





Java: import java.util.Arrays;
import java.util.HashSet;

public class VampireNumbers{
    private static int numDigits(long num){
        return Long.toString(Math.abs(num)).length();
    }

    private static boolean fangCheck(long orig, long fang1, long fang2){
        if(Long.toString(fang1).endsWith("0") && Long.toString(fang2).endsWith("0")) return false;

        int origLen = numDigits(orig);
        if(numDigits(fang1) != origLen / 2 || numDigits(fang2) != origLen / 2) return false;

        byte[] origBytes = Long.toString(orig).getBytes();
        byte[] fangBytes = (Long.toString(fang1) + Long.toString(fang2)).getBytes();
        Arrays.sort(origBytes);
        Arrays.sort(fangBytes);
        return Arrays.equals(origBytes, fangBytes);
    }

    public static void main(String[] args){
        HashSet<Long> vamps = new HashSet<Long>();
        for(long i = 10; vamps.size() <= 25; i++ ){
            if((numDigits(i) % 2) != 0) {i = i * 10 - 1; continue;}
            for(long fang1 = 2; fang1 <= Math.sqrt(i) + 1; fang1++){
                if(i % fang1 == 0){
                    long fang2 = i / fang1;
                    if(fangCheck(i, fang1, fang2) && fang1 <= fang2){
                        vamps.add(i);
                        System.out.println(i + ": [" + fang1 + ", " + fang2 +"]");
                    }
                }
            }
        }
        Long[] nums = {16758243290880L, 24959017348650L, 14593825548650L};
        for(Long i : nums){
            for(long fang1 = 2; fang1 <= Math.sqrt(i) + 1; fang1++){
                if(i % fang1 == 0){
                    long fang2 = i / fang1;
                    if(fangCheck(i, fang1, fang2) && fang1 <= fang2){
                        System.out.println(i + ": [" + fang1 + ", " + fang2 +"]");
                    }
                }
            }
        }
    }
}