// Algorithm / 演算法：
//   Two pointers from both ends. Skip non-alphanumeric characters,
//   compare lowercase forms, and shrink inward.
//   雙指針從兩端往中間走，跳過非字母數字，比較小寫後相等就繼續，遇到不等立即回傳 false。
//   Time O(n), Space O(1).

#include <stdbool.h>   // bool, true, false 型別 / boolean type
#include <ctype.h>     // isalnum, tolower 字元判斷與轉換 / char classification helpers
#include <string.h>    // strlen 取得字串長度 / string length

bool isPalindrome(char* s) {
    int left  = 0;                       // 左指針從字串開頭 / left pointer at start
    int right = (int)strlen(s) - 1;      // 右指針從字串結尾 (strlen 不含 '\0') / right pointer at last char

    while (left < right) {               // 兩指針還沒相遇就繼續 / loop until pointers meet
        // 把 char 轉成 unsigned char 再餵給 isalnum，避免負值造成 undefined behavior
        // Cast to unsigned char before calling isalnum to dodge UB on negative char values
        unsigned char lc = (unsigned char)s[left];
        unsigned char rc = (unsigned char)s[right];

        if (!isalnum(lc)) {              // 左邊不是字母或數字就跳過 / skip non-alnum on the left
            left++;                      // 左指針右移 / advance left pointer
            continue;                    // 重新進入迴圈、重新檢查 / restart the loop iteration
        }
        if (!isalnum(rc)) {              // 右邊不是字母或數字就跳過 / skip non-alnum on the right
            right--;                     // 右指針左移 / advance right pointer
            continue;                    // 重新進入迴圈 / restart
        }

        // 兩邊都是有效字元，統一轉小寫再比較 / both sides valid → lowercase then compare
        if (tolower(lc) != tolower(rc)) {
            return false;                // 一旦不相等就不可能是回文 / mismatch → not a palindrome
        }

        left++;                          // 這一對相等，左指針往內走 / matched pair, move inwards
        right--;                         // 右指針往內走 / move right pointer inwards
    }

    return true;                         // 全部對稱位置都通過檢查 / every symmetric pair matched
}
