什么是水仙花数
一个 n 位数,各数位的 n 次幂之和等于自身,就叫水仙花数。
比方 153 这个 3 位数:
思路
找所有 n 位水仙花数
假设 n = 3
-
查找范围在 100~1000,即
Math.pow(10, 2)~Math.pow(10, 3)Math.pow(10, n-1)~Math.pow(10, n) -
对范围内各数
num,判断自身是否等于求出的和
求和
num分割得到Array<number>,即各数位上的数- 求出各数位 3 次幂
- 求和
下面一步一步实现
分割数字
-
方案1:数字转字符串再分割
const splitNum = R.compose( R.map(Number), R.split(''), R.toString ); -
方案2:持续对 10 取余
/** * n = 153 * 153 % 10 -> 3 * 15 % 10 -> 5 * 1 % 10 -> 1 */ function splitNum(num) { function go(acc, x) { return 0 === x ? acc : go( [x % 10].concat(acc), Math.trunc(x / 10) ); } return go([], num); }
3 次幂之和
const pow = R.curry( (y, x) => Math.pow(x, y) );
R.compose( R.sum, R.map(pow(3)), splitNum )(153);
// 153
成品
function NarcissisticNums(n) {
const pow = R.curry( (y, x) => Math.pow(x, y) );
function splitNum(num) {
function go(acc, x) {
return 0 === x
? acc
: go( [x % 10].concat(acc), Math.trunc(x / 10) );
}
return go([], num);
}
const sumDigitsPowN = R.compose( R.sum, R.map(pow(n)), splitNum );
const isNarcissisticNum = R.converge( R.equals, [R.identity, sumDigitsPowN] );
return R.filter(isNarcissisticNum, R.range( pow(n-1, 10), pow(n, 10) ));
}
NarcissisticNums(3);
// [153, 370, 371, 407]
NarcissisticNums(4);
// [1634, 8208, 9474]