// 演算法 / Algorithm:
// 反覆把 n 換成「各位數平方和」，用 unordered_set 記錄看過的值。
// Repeatedly map n to its digit-square-sum; an unordered_set records seen values.
// 遇到 1 → 快樂數；遇到重複值 → 循環，回傳 false。
// Reach 1 → happy; revisit a value → cycle → false.

#include <unordered_set>   // 提供雜湊集合 unordered_set / provides the hash-set container

class Solution {
public:
    bool isHappy(int n) {
        // unordered_set<int> 是雜湊集合，insert / count 平均 O(1)。
        // unordered_set<int> is a hash set with average O(1) insert and lookup.
        std::unordered_set<int> seen;

        // 迴圈條件：n 不是 1，且 n 還沒出現過。
        // Loop while n is neither 1 nor a value we've already seen.
        // seen.count(n) 回傳 n 在集合中的個數（0 或 1），當作「是否存在」用。
        // seen.count(n) returns 0 or 1, used here as a "does it exist?" test.
        while (n != 1 && seen.count(n) == 0) {
            seen.insert(n);          // 把目前的 n 記下來 / remember the current value
            n = squareDigitSum(n);   // 換成下一個值 / move to the next value
        }

        // 跳出迴圈有兩種可能：n==1（快樂）或 n 是重複值（循環）。
        // We exit either because n == 1 (happy) or because n repeated (cycle).
        return n == 1;               // 只有 n 恰好是 1 才回傳 true / true only when n is exactly 1
    }

private:
    // 計算各位數平方和 / compute the sum of squares of n's digits
    int squareDigitSum(int n) {
        int sum = 0;                 // 平方和累加器 / accumulator
        while (n > 0) {              // 逐位取出，直到取完 / process each digit
            int d = n % 10;          // 取最低位 / last digit via modulo
            sum += d * d;            // 平方後累加 / add its square
            n /= 10;                 // 去掉最低位 / drop that digit
        }
        return sum;                  // 回傳結果 / return the sum
    }
};
