代码大战挑战

时间:2017-03-02 11:02:08

标签: javascript algorithm math numbers

我一直在努力应对这一挑战,似乎无法找到我失败的地方:

有些数字有趣。例如:

89 --> 8¹ + 9² = 89 * 1

695 --> 6² + 9³ + 5⁴= 1390 = 695 * 2

46288 --> 4³ + 6⁴+ 2⁵ + 8⁶ + 8⁷ = 2360688 = 46288 * 51

给定正整数n写为abcd ...(a,b,c,d ...为数字)和正整数p我们想要找到正整数k,如果它存在,例如总和取为p的连续幂的n的数字等于k * n。换句话说:

是否存在整数k,例如:(a ^ p + b ^(p + 1)+ c ^(p + 2)+ d ^(p + 3)+ ...)= n * k 如果是这种情况,我们将返回k,如果不返回-1。

注意:n,p将始终以严格正整数给出。

digPow(89, 1) should return 1 since 8¹ + 9² = 89 = 89 * 1
digPow(92, 1) should return -1 since there is no k such as 9¹ + 2² equals 92 * k
digPow(695, 2) should return 2 since 6² + 9³ + 5⁴= 1390 = 695 * 2
digPow(46288, 3) should return 51 since 4³ + 6⁴+ 2⁵ + 8⁶ + 8⁷ = 2360688 = 46288 * 51

我是javascript的新手,所以我的代码可能会有些内容,但我无法找到它。我的目的是正确学习javascript,但现在我想找出我做错了什么。我试图将给定的整数转换为数字,方法是将其模数设为10,然后将其除以10使用trunc来摆脱小数部分。我试图用这些数字填充数组各自的权限。但测试结果只是说我只返回0.我的代码中唯一返回0的是第一部分,但是当我尝试将其评论出来时,我仍然返回0。

function digPow(n, p){
// ...
var i;
var sum;
var myArray= new Array();
if(n<0)
  {
    return 0;
  }
var holder;
holder=n;
for(i=n.length-1;i>=0;i--)
 {
   if(holder<10)
    {
     myArray[i]=holder;
     break;
    }
  myArray[i]=holder%10;
  holder=math.trunc(holder/10);
  myArray[i]=math.pow(myArray[i],p+i);
  sum=myArray[i]+sum;

}
 if(sum%n==0)
  {
  return sum/n;
  }  
else
{
  return -1;
}}

5 个答案:

答案 0 :(得分:2)

这是另一个简单的解决方案

  function digPow(n, p){
    // convert the number into string
    let str = String(n);
    let add = 0;
    // convert string into array using split()
    str.split('').forEach(num=>{
      add += Math.pow(Number(num) , p);
      p++;
    });

    return (add % n) ? -1 : add/n;
  }
  let result = digPow(46288, 3);
  console.log(result);

答案 1 :(得分:1)

您有多个问题:

  1. 如果n是数字,则不会有长度属性。所以i将是undefined并且您的循环永远不会运行,因为undefined不大于或等于零

    for(i=n.length-1;i>=0;i--) //could be
    for(i=(""+n).length;i>=0;i--) //""+n quick way of converting to string
    
  2. 您永远不会将sum初始化为0,因此它是undefined,当您将功效计算的结果添加到总和时,您将不断得到NaN

    var sum; //should be
    var sum=0;
    
  3. 你有if(holder<10)...break你不需要这个,因为循环将在持有者小于10的迭代之后结束。你也永远不会为它执行权力或将其添加到{{1 }}。如果一起完全删除它。

  4. 您的结束代码如下所示:

    sum

    请注意,你可以将它缩小到像

    这样的东西
    function digPow(n, p) {
      var i;
      var sum=0;
      var myArray = new Array();
      if (n < 0) {
        return 0;
      }
      var holder;
      holder = n;
      for (i = (""+n).length - 1; i >= 0; i--) {
        myArray[i] = holder % 10;
        holder = Math.trunc(holder / 10);
        myArray[i] = Math.pow(myArray[i], p + i);
        sum = myArray[i] + sum;
      }
      if (sum % n == 0) {
        return sum / n;
      } else {
        return -1;
      }
    }
    
    • function digPow(n,p){ if( isNaN(n) || (+n)<0 || n%1!=0) return -1; var sum = (""+n).split("").reduce( (s,num,index)=>Math.pow(num,p+index)+s,0); return sum%n ? -1 : sum/n; } 只需转换为字符串
    • 即可
    • (""+n)将字符串拆分为一个数组(无需使用%10数学来获取每个数字
    • .split("")调用数组的reduce函数,该函数为数组中的每个项调用一个函数。该函数每次都返回一个值,第二个参数是起始值
    • .reduce( function,0) Fat Arrow函数,只需使用正确的参数调用Math.pow,然后将其添加到总和(s,num,index)=>Math.pow(num,p+index+1)+s并返回

答案 2 :(得分:1)

<强>误

您的代码存在一些问题。这是你犯过的一些错误。

  1. number.length无效。获取JS中数字长度的最简单方法是将其转换为字符串,如下所示:n.toString().length。 检查一下:Length of Number in JavaScript

  2. 数学对象应该被引用为Math,而不是数学。 (注意大写M)所以math.pow和math.trunc应该是Math.powMath.trunc

  3. sum中第一次迭代for循环时,
  4. sum=myArray[i]+sum;未定义。使用var sum = 0;代替var sum;

  5. 固定代码

    我修正了这些错误并更新了您的代码。一些部分已被删除 - 例如验证n,(问题表明其严格肯定) - 并且其他部分已被重写。我做了一些风格上的修改,以使代码更具可读性。

    function digPow(n, p){
    var sum = 0;
    var myArray = [];
    var holder = n;
    
    for (var i = n.toString().length-1; i >= 0; i--) {
      myArray[i] = holder % 10;
      
      holder = Math.trunc(holder/10);  
      myArray[i] = Math.pow(myArray[i],p+i);
      sum += myArray[i];  
    }
    
      if(sum % n == 0) {
        return sum/n;
      } else {
        return -1;
      }
    }
    
    console.log(digPow(89, 1));
    console.log(digPow(92, 1));
    console.log(digPow(46288, 3));

    我的代码

    这是我在回答这个问题时所做的。希望这会有所帮助。

    function digPow(n, p){
      var digPowSum = 0;  
      var temp = n;
      
      while (temp > 0) {
        digPowSum += Math.pow(temp % 10, temp.toString().length + p - 1); 
        temp = Math.floor(temp / 10);
      }
      
      return (digPowSum % n === 0) ? digPowSum / n : -1;  
    }
    
    console.log(digPow(89, 1));
    console.log(digPow(92, 1));
    console.log(digPow(46288, 3));

答案 3 :(得分:0)

我创建了一个完全符合您要求的代码。您的代码中的问题已在评论中解释,因此我不会专注于此。

<强> FIDDLE

这是代码。

$sql = "SELECT date::varchar FROM table"

答案 4 :(得分:0)

只是为了各种各样,你可以在不使用任何字符串操作的情况下在功能上执行相同的工作。

&#13;
&#13;
function digPow(n,p){
  var d = ~~Math.log10(n)+1;  // number of digits
      r = Array(d).fill()
                  .map(function(_,i){
                         var t = Math.pow(10,d-i);
                         return Math.pow(~~((n%t)*10/t),p+i);
                       })
                  .reduce((p,c) => p+c);
  return r%n ? -1 : r/n;
}

var res = digPow(46288,3);
console.log(res);
&#13;
&#13;
&#13;