কম্পিউটার টিউটোরিয়াল

JavaScript-এ রিকারসন ব্যবহার করে হ্যাপি নম্বর নির্ধারণ

হ্যাপি নম্বর (Happy Number) কী?

একটি নম্বর যদি তার ডিজিটগুলোর বর্গের যোগফল বের করে, এবং সেই প্রক্রিয়া বারবার दुহরাতে শেষে **১** এ পৌঁছায়, তবে সেটি **হ্যাপি নম্বর**। যদি কোনো নম্বর পুনরাবৃত্তি হয় (সাইকেল বানায়), তবে সেটি **আনহ্যাপি (unhappy) নম্বর**।

উদাহরণ

13 (হ্যাপি):

1² + 3² = 1 + 9 = 10
1² + 0² = 1 + 0 = 1  → হ্যাপি! ✓

36 (আনহ্যাপি):

3² + 6² = 9 + 36 = 45
4² + 5² = 16 + 25 = 41
4² + 1² = 16 + 1 = 17
1² + 7² = 1 + 49 = 50
5² + 0² = 25
2² + 5² = 4 + 25 = 29
2² + 9² = 4 + 81 = 85
8² + 5² = 64 + 25 = 89
8² + 9² = 64 + 81 = 145
1² + 4² + 5² = 1 + 16 + 25 = 42
4² + 2² = 16 + 4 = 20
2² + 0² = 4
4² = 16
1² + 6² = 37
3² + 7² = 9 + 49 = 58
5² + 8² = 25 + 64 = 89  → সাইকেল ডিটেক্টেড! ❌

সম্পূর্ণ কোড (রিকারসিভ)

const squareSumRecursively = (n, res = 0) => {
  if (n) {
    return squareSumRecursively(Math.floor(n / 10), res + Math.pow((n % 10), 2));
  }
  return res;
};

const isHappy = (num, map = {}) => {
  if (num !== 1) {
    if (map[num]) return false; // সাইকেল ডিটেক্টেড
    map[num] = 1;               // ভিজিটেড মার্ক
    return isHappy(squareSumRecursively(num), map);
  }
  return true;
};

console.log(isHappy(36)); // false
console.log(isHappy(13)); // true
console.log(isHappy(23)); // true

কোড ব্যাখ্যা

squareSumRecursively

  • রিকারসিভলি প্রতিটি ডিজিটের বর্গ যোগ করে
  • `n % 10` - লাস্ট ডিজিট, `Math.floor(n/10)` - বাকি অংশ

isHappy

  • বেস কেস: `num === 1` হলে `true`
  • সাইকেল ডিটেকশন: `map` অবজেক্টে ভিজিটেড নম্বর সংরক্ষণ
  • রিকারসিভ কল: `squareSumRecursively(num)` এর ফলাফলে আবার কল

আউটপুট

false
true
false
true

আধুনিক ও উন্নত পদ্ধতিগুলো

১. Floyd's Cycle Detection (Tortoise & Hare - O(1) স্পেস)

const isHappyFloyd = (n) => {
  const squareSum = (num) => 
    String(num).split('').reduce((sum, d) => sum + d*d, 0);
  
  let slow = n;
  let fast = n;
  
  do {
    slow = squareSum(slow);        // ১ ধাপ
    fast = squareSum(squareSum(fast)); // ২ ধাপ
  } while (slow !== fast);
  
  return slow === 1;
};

২. Set ব্যবহার (ES6+ - ক্লিনার)

const isHappySet = (n) => {
  const seen = new Set();
  const squareSum = (num) => 
    [...String(num)].reduce((sum, d) => sum + d*d, 0);
  
  while (n !== 1 && !seen.has(n)) {
    seen.add(n);
    n = squareSum(n);
  }
  return n === 1;
};

৩. ইটেরেটিভ (স্ট্যাক সেফ)

const isHappyIterative = (n) => {
  const seen = new Set();
  const squareSum = (num) => 
    [...String(num)].reduce((sum, d) => sum + d*d, 0);
  
  while (n !== 1) {
    if (seen.has(n)) return false;
    seen.add(n);
    n = squareSum(n);
  }
  return true;
};

জানা হ্যাপি নম্বর (১-১০০)

1, 7, 10, 13, 19, 23, 28, 31, 32, 44, 49, 68, 70, 79, 82, 86, 91, 94, 97, 100

রোচক তথ্য

  • সব হ্যাপি নম্বর শেষে ১-এ পৌঁছায়
  • আনহ্যাপি নম্বরগুলো ৪ → ১৬ → ৩৭ → ৫৮ → ৮৯ → ১৪৫ → ৪২ → ২০ → ৪ এই সাইকেলে পড়ে
  • বেস-১০ এ অনুমানিক ১২% নম্বর হ্যাপি
  • অনंत হ্যাপি নম্বর আছে (প্রমাণিত)

সারাংশ

রিকারসিভ সমাধান বোঝার জন্য ভালো, কিন্তু প্রোডাকশনে **Floyd's Algorithm (O(1) স্পেস)** বা **Set-ভিত্তিক ইটারেটিভ** ব্যবহার করুন। স্ট্যাক ওভারফ্লো এড়াতে এবং দ্রুত এক্সিকিউশনের জন্য।

  1. জাভাস্ক্রিপ্টে তারিখে মাস যোগ করার উপায়

  2. জাভাস্ক্রিপ্টে Number অবজেক্ট কীভাবে তৈরি করবেন?

  3. জাভাস্ক্রিপ্টে দশমিক সংখ্যা ভ্যালিডেশন

  4. পাইথনে রিকার্শন দিয়ে প্রাকৃতিক সংখ্যাগুলোর যোগফল (Sum of Natural Numbers) বের করা