Next Bigger Number

const {log} = console;

/*
    n(abcde): 
      ไปฃ่กจไธ‹ไธ€ๅ€‹ๆฏ” abcde ๅคง็š„ๆ•ธๅญ— (ไฝ†้‚„ๆ˜ฏๅช่ƒฝ็”จ abcde ้€™ๅนพๅ€‹ๆ•ธๅญ—)ใ€‚
      
    f(abcde): 
      1. ไปฃ่กจๅœจ bcde ๅ…งๆ‰พๅ‡บใ€Œๆฏ” a ๅคง็š„ๆ•ธๅญ—ๆœ€ๅฐ่€…ใ€๏ผŒ็„ถๅพŒ่ทŸ a ๅฐ่ชฟ๏ผŒ
         ๅฆ‚ๆžœๆ‰พไธๅˆฐ๏ผŒๅฐฑๅ›žๅ‚ณ undefinedใ€‚
      2. ๅฐ่ชฟๅพŒ๏ผŒๅพŒ้ข็š„ๆ•ธๅญ—ใ€ŒๅพžๅฐๆŽ’ๅˆฐๅคงใ€๏ผŒ่ทŸ็ฌฌไธ€ๅ€‹ๆ•ธๅญ—ๆŽฅ่ตทไพ†๏ผŒ็„ถๅพŒๅ›žๅ‚ณใ€‚
      
    n(abcde) = abc+f(de) || ab+f(cde) || a+f(bcde) || f(abcde)
*/

// assume: `k` -> string of digits.
// suppose k = abcd, b = next bigger digit than `a`, then:
// f(abcd) = b + smallest(acd)
function f(k) {
    
    // 1. find next bigger digit than leading digit
    let arr = k.substring(1).split('').sort();  // sort is key
    let i = arr.findIndex(c => +c > +k[0]);
    
    // 2. if not found, return undefined.
    if (i === -1) return undefined;
    
    //    if found, interchange them.
    let b = arr[i]; arr[i] = k[0];
    return b + arr.sort().join('');             // remember to sort again
}

// assume: `k` -> string of digits.
// next bigger number
function n(k) {
    
    let next;
    let left = k.length - 2;
    
    while (!next && left >= 0) {
        let found = f(k.substring(left));
        if (found) next = k.substring(0, left) + found;
        left -= 1;
    }
    
    return next;
}

// -------- log --------

// f(k)
[
    3412,           // 4123
    4312,           // undefined
]
    .map(n => f(String(n)))
    .forEach(x => log(x));

// n(k)
[
    3412,           // 3421
    4312,           // 4321
    59884848459853, // 59884848483559
]
    .map(k => n(String(k)))
    .forEach(x => log(x));

Last updated