Given a stock of integers 0-9, what is the last number I can write before I run out of some integer?

浪尽此生 提交于 2019-12-05 10:13:21

Step 1. Write an efficient function to calculate how much stock needs to be used to write all of the numbers up to N. (Hint: calculate everything that was used to write out the numbers in the last digit with a formula, and then use recursion to calculate everything that was used in the other digits.)

Step 2. Do a binary search to find the last number you can write with your amount of stock.

We can calculate the answer directly. A recursive formula can determine how much stock is needed to get from 1 to numbers that are powers of ten minus 1:

f(n, power, target){
  if (power == target)
    return 10 * n + power;
  else
    return f(10 * n + power, power * 10, target);
}

f(0,1,1) = 1 // a stock of 1 is needed for the numbers from 1 to 9
f(0,1,10) = 20 // a stock of 20 is needed for the numbers from 1 to 99
f(0,1,100) = 300 // a stock of 300 is needed for the numbers from 1 to 999
f(0,1,1000) = 4000 // a stock of 4000 is needed for the numbers from 1 to 9999

Where it gets complicated is accounting for the extra 1's needed when our calculation lands after the first multiple of any of the above coefficients; for example, on the second multiple of 10 (11-19) we need an extra 1 for each number.

JavaScript code:

function f(stock){
  var cs = [0];
  var p = 1;
  function makeCoefficients(n,i){
    n  = 10*n + p;
    if (n > stock){
      return;
    } else {
      cs.push(n);
      p *= 10;
      makeCoefficients(n,i*10);
    }
  }

  makeCoefficients(0,1);
  var result = -1;
  var numSndMul = 0;
  var c;

  while (stock > 0){
    if (cs.length == 0){
      return result;
    }
    c = cs.pop();
    var mul = c + p * numSndMul;

    if (stock >= mul){
      stock -= mul;
      result += p;
      numSndMul++;
      if (stock == 0){
        return result;
      }
    }

    var sndMul = c + p * numSndMul;

    if (stock >= sndMul){
      stock -= sndMul;
      result += p;
      numSndMul--;
      if (stock == 0){
        return result;
      }
      var numMul = Math.floor(stock / mul);
      stock -= numMul * mul;
      result += numMul * p;
    }
    p = Math.floor(p/10);
  }
  return result;
}

Output:

console.log(f(600));
1180

console.log(f(17654321));
16031415

console.log(f(2147483647));
1633388154
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!