ภาพรวม
จำนวนอาร์มสตรอง (Armstrong Number) หรือ Narcissistic Number คือตัวเลขที่ผลรวมของแต่ละหลักยกกำลังจำนวนหลักเท่ากับตัวเลขนั้นเอง
ตัวอย่าง
153 เป็นจำนวนอาร์มสตรอง เพราะ: 1³ + 5³ + 3³ = 1 + 125 + 27 = 153
การนำไปใช้
const isArmstrong = (number) => {
let num = number;
const len = String(num).length;
let res = 0;
while (num) {
const last = num % 10;
res += Math.pow(last, len);
num = Math.floor(num / 10);
}
return res === number;
};
const armstrongBetween = (lower, upper) => {
const res = [];
for (let i = lower; i <= upper; i++) {
if (isArmstrong(i)) {
res.push(i);
}
}
return res;
};
console.log(armstrongBetween(1, 400));
ผลลัพธ์
[1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371]
จำนวนอาร์มสตรองที่รู้จัก (ฐาน 10)
- 1 หลัก: 1-9 (ทั้งหมด)
- 3 หลัก: 153, 370, 371, 407
- 4 หลัก: 1634, 8208, 9474
- 5 หลัก: 54748, 92727, 93084
- 6 หลัก: 548834
- 7 หลัก: 1741725, 4210818, 9800817, 9926315
- 8 หลัก: 24678050, 24678051, 88593477
- รวมทั้งหมดมีเพียง 88 ตัวในฐาน 10
การปรับปรุงประสิทธิภาพ
// Pre-calculate powers เพื่อลดการคำนวณซ้ำ
const armstrongOptimized = (lower, upper) => {
// สร้างตารางกำลัง: powers[digit][length]
const powers = Array.from({ length: 10 }, (_, d) =>
Array.from({ length: 20 }, (_, l) => Math.pow(d, l))
);
const isArmstrongFast = (num) => {
const digits = String(num).split('').map(Number);
const len = digits.length;
const sum = digits.reduce((s, d) => s + powers[d][len], 0);
return sum === num;
};
const res = [];
for (let i = lower; i <= upper; i++) {
if (isArmstrongFast(i)) res.push(i);
}
return res;
};
ข้อสังเกต
จำนวนอาร์มสตรองมีน้อยมาก และเพิ่มขึ้นช้ามากเมื่อจำนวนหลักเพิ่มขึ้น สำหรับการใช้งานจริง มักจะ Pre-compute ไว้แล้วนำมาใช้ได้เลย