A vampire number is a natural decimal number with an even number of digits,   that can be factored into two integers.

These two factors are called the   fangs,   and must have the following properties:

   they each contain half the number of the decimal digits of the original number
   together they consist of exactly the same decimal digits as the original number
   at most one of them has a trailing zero


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



Task

 Print the first   25   vampire numbers and their fangs. 
 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 one pair of fangs.



See also

 numberphile.com.
 vampire search algorithm
 vampire numbers on OEIS


// version 1.1
 
data class Fangs(val fang1: Long = 0L, val fang2: Long = 0L)
 
fun pow10(n: Int): Long = when {
    n < 0 -> throw IllegalArgumentException("Can't be negative")
    else -> {
        var pow = 1L
        for (i in 1..n) pow *= 10L
        pow
    }
}
 
fun countDigits(n: Long): Int = when {
    n < 0L -> throw IllegalArgumentException("Can't be negative")
    n == 0L -> 1
    else -> {
        var count = 0
        var nn = n
        while (nn > 0L) {
            count++
            nn /= 10L
        }
        count
    }
}
 
fun hasTrailingZero(n: Long): Boolean = when {
    n < 0L -> throw IllegalArgumentException("Can't be negative")
    else -> n % 10L == 0L
}
 
fun sortedString(s: String): String {
    val ca = s.toCharArray()
    ca.sort()
    return String(ca)
}
 
fun isVampiric(n: Long, fl: MutableList<Fangs>): Boolean {
    if (n < 0L) return false
    val len = countDigits(n)
    if (len % 2L == 1L) return false
    val hlen = len / 2
    val first = pow10(hlen - 1)
    val last = 10L * first
    var j: Long
    var cd: Int
    val ss = sortedString(n.toString())
    for (i in first until last) {
        if (n % i != 0L) continue
        j = n / i
        if (j < i) return fl.size > 0
        cd = countDigits(j)
        if (cd > hlen) continue
        if (cd < hlen) return fl.size > 0
        if (ss != sortedString(i.toString() + j.toString())) continue
        if (!(hasTrailingZero(i) && hasTrailingZero(j))) {
            fl.add(Fangs(i, j))
        }
    }
    return fl.size > 0
}
 
fun showFangs(fangsList: MutableList<Fangs>): String {
    var s = ""
    for ((fang1, fang2) in fangsList) {
        s += " = $fang1 x $fang2"
    }
    return s
}
 
fun main(args: Array<String>) {
    println("The first 25 vampire numbers and their fangs are:")
    var count = 0
    var n: Long = 0
    val fl = mutableListOf<Fangs>()
    while (true) {
        if (isVampiric(n, fl)) {
            count++
            println("${"%2d".format(count)} : $n\t${showFangs(fl)}")
            fl.clear()
            if (count == 25) break
        }
        n++
    }
    println()
    val va = longArrayOf(16758243290880L, 24959017348650L, 14593825548650L)
    for (v in va) {
        if (isVampiric(v, fl)) {
            println("$v\t${showFangs(fl)}")
            fl.clear()
        } else {
            println("$v\t = not vampiric")
        }
    }
}