luhn算法

在codewars刷js题时,碰到一个luhn算法题,很简单,但如何写的优雅和简洁却很考验功力。先介绍下luhn算法吧:

LUHN算法,主要用来计算信用卡等证件号码的合法性。

1、从卡号最后一位数字开始,偶数位乘以2,如果乘以2的结果是两位数,将两个位上数字相加保存。
2、把所有数字相加,得到总和。
3、如果信用卡号码是合法的,总和可以被10整除。

我的代码如下:

function validate(n){
  var arr = parseToArray(n);
  arr = walkToReplace(arr);
  var sum = sumOfArray(arr);
  return sum%10===0;
}

function parseToArray(n){
  n = '' + n;
  return n.split("").reverse();
}

function walkToReplace(arr){
  for(var i=0,l=arr.length; i<l; i++){
    if((i+1)%2===0){
      arr[i] = 2*arr[i] > 9 ? 2*arr[i]-9 : 2*arr[i];
    }
  }
  return arr;
}

function sumOfArray(arr){
  return eval(arr.join("+"));
}

代码其实也不长,比70%以上的解决方法的代码要短,但感觉有些死板,而且也体现不出技巧性,只能说中规中矩的代码。

最佳解决方案如下:

function validate(n){
  var sum = 0;

  while (n > 0) {
    var a = n % 10;
    n = Math.floor(n / 10);
    
    var b = (n % 10) * 2;
    n = Math.floor(n / 10);
    
    if (b > 9) {
      b -= 9;
    }
    
    sum += a + b;
  }
  
  return sum % 10 == 0;
}

读完后不禁拍案叫绝,其实该方法用到的算法技巧也非常简单,但关键是用的很妙,大部分的解决方案是先替换值,然后再求和,我的解决方案也是如此。然而该方法,将值的替换与求和在一个while循环里就完成了,而且代码简短易读,确实是很很值得称赞。

该方法还为“求一个n位数字的各位数之和”这种问题提供了一种思路,属于reduce的一种。

原文地址:https://www.cnblogs.com/just4play/p/5668754.html