【算法】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")
相关推荐
HjhIron1 天前
面试常客:字符串算法从入门到进阶
算法·面试
吴佳浩1 天前
DeepSeek DSpark:Confidence-Scheduled Speculative Decoding 技术解析
人工智能·算法·deepseek
触底反弹1 天前
🧠 搞懂 Token,才算真正入门大模型——从分词原理到 Embedding 语义实战
javascript·人工智能·算法
vivo互联网技术1 天前
ICLR 2026 | 基于后验采样的图像恢复方法LearnIR:人脸去阴影、去雾
人工智能·算法·aigc
浮生望1 天前
JS字符串与回文算法:从包装类到双指针的面试进阶之路
javascript·算法
黄敬峰1 天前
面试必刷:从JS底层包装类到双指针,彻底搞懂字符串与回文算法
算法
地平线开发者2 天前
J6B vio scenario sample
算法
BothSavage2 天前
Trae远程开发中DeepSeek自定义模型4054错误的排查与修复
算法
小林ixn2 天前
从暴力到KMP:一道题彻底搞懂字符串匹配的前世今生
算法