【算法】Vampire Numbers

Vampire Numbers

recursion permutation brute force

A Vampire Number is a positive integer greater than 99, that rearranged in all of its possible digits permutations, with every permutation being split into two parts, is equal to the product of at least one of its permutations.

  • If the number has an even quantity of digits, left and right parts will have the same length in every permutation;
  • If the number has an odd quantity of digits and at least three digits, the left and right parts will present different lengths for every possible permutation, alternating between them in the range +1 and -1.

Given a positive integer n, implement a function that returns the type of n as a string:

  • 'Normal Number' if n is lower than 100 or if no permutations return a product of their parts equal to n.
  • 'Pseudovampire' if n it is a Vampire with an odd quantity of digits.
  • 'True Vampire' if n it is a Vampire with an even quantity of digits.
Examples
javascript 复制代码
isVampire(1260) // "True Vampire"
// Has an even number of digits and is greater than 99)
// Permutations:
// 12 * 60 = 720
// 16 * 20 = 320
// 10 * 26 = 260
// 21 * 60 = 1260

isVampire(126) // "Pseudovampire"
// Has an odd number of digits and is greater than 99
// Permutations:
// 12 * 6 = 72
// 1 * 26 = 26
// 21 * 6 = 126

isVampire(67) // "Normal Number"
// Is lower than 100
// Permutations:
// 6 * 7 = 7 * 6 = 42
Notes
  • Trivially, a number from 1 to 99 is a Normal Number by the definitions: a single-digit number can't be split into two parts, and the product of the permutated two digits of a number will always be lower than the number itself.
Solutions
javascript 复制代码
// solution1: recursion + permutation
const isVampire = (n) => {
    if(n < 100){
        return 'Normal Number'
    }
    let t = n,d=[];
    while(t){
        d.unshift(t%10)
        t = Math.floor(t/10)
    }
    let o = d.length&0b1;
    let res = compute(d,0,n,o,d.length)
    return res?(!o?'True Vampire':'Pseudovampire'):'Normal Number';
}
const compute = (d,k,n,o,l)=>{
    if(k==l){
        k = l>>>1
        let pair = toIntPair(d,k);
        let res = pair[0]*pair[1] === n;
        if(o && !res){
            pair = toIntPair(d,k+1);
            res = pair[0]*pair[1] === n;
        }
        return res;
    }
    for(let i=k;i<l;i++){
        [d[i],d[k]] = [d[k],d[i]]
        let res = compute(d,k+1,n,o,l)
        if(res){
            return true;
        }
        [d[k],d[i]] = [d[i],d[k]]
    }
    return false;
};
const toIntPair=(d,k)=>{
    let res = [0,0];
    for(let i=0;i<k;i++){
        res[0] = res[0]*10 + d[i]
    }
    for(let i=k;i<d.length;i++){
        res[1] = res[1]*10 + d[i]
    }
    return res
}
javascript 复制代码
// solution2: brute force
const isVampire = (n) => {
    if(n < 100){
        return 'Normal Number'
    }
    let t = n,c=0;
    while(t){
        c++;
        t = Math.floor(t/10);
    }
    let o = c&0b1;
    c >>>= 1
    let max = 1 ;
    while(c-->0){
        max *= 10
    }
    let d=Array(10).fill(0);
    for(let i = Math.floor(max/10); i < max;i++){
            let j = Math.floor(n/i);
            let m = i*j;
            let [ii,jj,mm] = [i,j,m];
            while(mm){
                d[mm%10]++;
                mm = Math.floor(mm/10);
            }
            while(ii){
                d[ii%10]--;
                ii = Math.floor(ii/10);
            }
            while(jj){
                d[jj%10]--;
                jj = Math.floor(jj/10);
            }
            let is = true;
            for(let i=0;i<10;i++){
                if(d[i]){
                    is = false;
                    d[i] = 0;
                }
            }
            if(is && m === n){
                return !o?'True Vampire':'Pseudovampire';
            }
    }
    return 'Normal Number';
}
TestCases
javascript 复制代码
let Test = (function(){
    return {
        assertEquals:function(actual,expected){
            if(actual !== expected){
                let errorMsg = `actual is ${actual},${expected} is expected`;
                throw new Error(errorMsg);
            }
        }
    }
})();

Test.assertEquals(isVampire(1260), "True Vampire", "Example #1")
Test.assertEquals(isVampire(126), "Pseudovampire", "Example #2")
Test.assertEquals(isVampire(67), "Normal Number", "Example #3")
Test.assertEquals(isVampire(1), "Normal Number")
Test.assertEquals(isVampire(645), "Normal Number")
Test.assertEquals(isVampire(688), "Pseudovampire")
Test.assertEquals(isVampire(1345), "Normal Number")
Test.assertEquals(isVampire(1395), "True Vampire")
Test.assertEquals(isVampire(12964), "Pseudovampire")
Test.assertEquals(isVampire(98765), "Normal Number")
Test.assertEquals(isVampire(124421), "Normal Number")
Test.assertEquals(isVampire(125460), "True Vampire")
相关推荐
mit6.8245 小时前
bfs|栈
算法
CoderYanger6 小时前
优选算法-栈:67.基本计算器Ⅱ
java·开发语言·算法·leetcode·职场和发展·1024程序员节
jllllyuz6 小时前
Matlab实现基于Matrix Pencil算法实现声源信号角度和时间估计
开发语言·算法·matlab
稚辉君.MCA_P8_Java6 小时前
DeepSeek 插入排序
linux·后端·算法·架构·排序算法
多多*6 小时前
Java复习 操作系统原理 计算机网络相关 2025年11月23日
java·开发语言·网络·算法·spring·microsoft·maven
.YM.Z7 小时前
【数据结构】:排序(一)
数据结构·算法·排序算法
Chat_zhanggong3457 小时前
K4A8G165WC-BITD产品推荐
人工智能·嵌入式硬件·算法
百***48078 小时前
【Golang】slice切片
开发语言·算法·golang
墨染点香8 小时前
LeetCode 刷题【172. 阶乘后的零】
算法·leetcode·职场和发展
做怪小疯子8 小时前
LeetCode 热题 100——链表——反转链表
算法·leetcode·链表