codewars 6kyu_Sum of Digits

今天发现一个有意思刷 JS 题的网站!codewars
希望能够快速学会 JS 语法。今天做了一道题。6kyu_Sum of Digits / Digital Root
主要意思是给定一个数字 n,需要把 n 的各位数字加起来,如果得到的结果不是一位数,那么需要再把得到的结果的各位数字加起来。
题目简单,主要是为了熟悉 JS 语法。

function digital_root(n) {
    if(n<10){
        return n;
    }
    while(parseInt(n/10)!=0){
      sn = String(n);
      var ans = 0
      for(let i=0;i<sn.length;i++){
        ans += n%10;
        n = parseInt(n/10);
        // console.log(temp,ans);
      }
      n = ans;
    }
    return ans;
  }

做完了之后的测试样例如下:

describe("Basic tests", function () {
  it("Should pass basic tests", function () {
    Test.assertEquals(digital_root(16), 7);
    Test.assertEquals(digital_root(195), 6);
    Test.assertEquals(digital_root(992), 2);
    Test.assertEquals(digital_root(999999999999), 9);
    Test.assertEquals(digital_root(167346), 9);
    Test.assertEquals(digital_root(10), 1);
    Test.assertEquals(digital_root(0), 0);
  });
});

describe("Random tests", function () {
  it("Should pass random tests", function () {
    function digital_root_sol(n) {
      return n > 0 ? 1 + ((parseInt(n) - 1) % 9) : 0;
    }

    for (let i = 0; i < 100; i++) {
      let n = Math.floor(Math.random() * 1000000);
      Test.assertEquals(digital_root(n), digital_root_sol(n));
    }
  });
});

遇到的问题:

  1. JavaScript 可以通过不同的方式来输出数据:

    • 使用 window.alert() 弹出警告框。
    • 使用 document.write() 方法将内容写到 HTML 文档中。
    • 使用 innerHTML 写入到 HTML 元素。
    • 使用 console.log() 写入到浏览器的控制台。
  2. 注释:// 或 /**/

  3. js 严格区分大小写,每一条语句用‘;’结尾。

    通常我们在每条可执行的语句结尾添加分号。

    使用分号的另一用处是在一行中编写多条语句。

  4. 可以一条语句,声明多个变量

// 方法一
var lastname = "Doe",
  age = 30,
  job = "carpenter";
// 方法二:声明可以跨行
var lastname = "Doe",
  age = 30,
  job = "carpenter";
// 错误示范!一条语句中声明的多个变量不可以同时赋同一个值:
var x,
  y,
  z = 1; // x,y为undefined,z为1
  1. 如果重新声明 JavaScript 变量,该变量的值不会丢失:

在以下两条语句执行后,变量 carname 的值依然是 “Volvo”:

var carname = "Volvo";
var carname;
  1. 地板除、天花板除
// 地板除
console.log(parseInt(6 / 4)); // 1
console.log(Math.floor(6 / 4)); //1
// 正常除
console.log(parseIntFloat(6 / 4)); // 1.5
console.log(6 / 4); //1.5
// 天花板除
console.log(Math.ceil(6.4)); //2

最后交完了,看了别人的题解,发现别人用一行就写完了。-_- 真难过。代码如下:

function digital_root(n) {
  return ((n - 1) % 9) + 1;
}

这是什么原理呢?
这个题一般的思路我认为是

while(n/10 != 0):
  ans += n%10;
  n /= 10;
return ans

n%10 和 n%9 又有什么关系呢?有待之后探究!

n % 9 = (n-1+1) % 9 = (n-1) % 9 + 1 % 9 = (n-1)%9 + 1

一般情况
1234 =   1000  + 2* 100   + 3* 10   + 4
     = (999+1) + 2*(99+1) + 3*(9+1) + 4
     = 999 + 2*99 + 3*9 +(1 + 2*1 + 3*1 + 4)
1234 % 9 = (1+2*1+3*1+4) % 9 = 10 % 9 = 9%9 + 1%9 = 1
f(1234) = f(1+2+3+4)
        = f(10) = f(1+0)
        = f(1) = 1

如果结果为9,但是直接n%9的结果会是0
f(167346) = f(1+6+7+3+4+6)
          = f(27) = f(2+7)
          = f(9) = 9
167346 = 100000 + 6*10000 + 7* 1000 + 3*100 + 4*10 + 6
       = (99999+1) + 6*(9999+1)+ 7*(999+1) + 3*(99+1) + 4*(9+1)+6
       =(99999 + 6*9999 + 7*999 + 3*99 + 4*9) + (1 + 6*1 + 7*1 + 3*1 + 4*1 + 6)
167346 % 9 = (1 + 6*1 + 7*1 + 3*1 + 4*1 + 6)%9
           = (27 % 9) = 0  欸,不对了吧,答案应该是9的啊
           = (27-1) % 9 + 1 = 9 所以要先-1模9,再加1

这个解法的思维十分巧妙,果然数学思维在解题中十分重要!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值