125. Valid palindrome

#include <ctype.h>
#include <stdbool.h>
#include <string.h>

bool isPalindrome(char *s) {
    int left = 0, right = strlen(s) - 1;

    while (left < right) {
        while (left < right && !isalnum(s[left])) {
            left++;
        }
        while (left < right && !isalnum(s[right])) {
            right--;
        }

        if (tolower(s[left]) != tolower(s[right])) {
            return false;
        }

        left++;
        right--;
    }

    return true;
}
#include <string>
using namespace std;
class Solution {
public:
  bool isPalindrome(string s) {
    int left = 0, right = s.size() - 1;

    while (left < right) {
      while (left < right && !isalnum(s[left]))
        left++;
      while (left < right && !isalnum(s[right]))
        right--;

      if (tolower(s[left]) != tolower(s[right]))
        return false;

      left++;
      right--;
    }
    return true;
  }
};
package main

import "unicode"

func isPalindrome(s string) bool {
    runes := []rune(s)
    left, right := 0, len(runes)-1

    for left < right {
        for left < right && !unicode.IsLetter(runes[left]) && !unicode.IsDigit(runes[left]) {
            left++
        }
        for left < right && !unicode.IsLetter(runes[right]) && !unicode.IsDigit(runes[right]) {
            right--
        }

        if unicode.ToLower(runes[left]) != unicode.ToLower(runes[right]) {
            return false
        }

        left++
        right--
    }

    return true
}
class Solution {
    public boolean isPalindrome(String s) {
        int left = 0, right = s.length() - 1;

        while (left < right) {
            while (left < right && !Character.isLetterOrDigit(s.charAt(left))) {
                left++;
            }
            while (left < right && !Character.isLetterOrDigit(s.charAt(right))) {
                right--;
            }

            if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) {
                return false;
            }

            left++;
            right--;
        }

        return true;
    }
}
class Solution {
  isPalindrome(s) {
    const isAlnum = (c) => /[a-zA-Z0-9]/.test(c);
    let left = 0;
    let right = s.length - 1;

    while (left < right) {
      while (left < right && !isAlnum(s[left])) left++;
      while (left < right && !isAlnum(s[right])) right--;

      if (s[left].toLowerCase() !== s[right].toLowerCase()) return false;

      left++;
      right--;
    }

    return true;
  }
}
class Solution:
    def isPalindrome(self, s: str) -> bool:
        left, right = 0, len(s) - 1

        while left < right:
            while left < right and not s[left].isalnum():
                left += 1
            while left < right and not s[right].isalnum():
                right -= 1

            if s[left].lower() != s[right].lower():
                return False

            left += 1
            right -= 1

        return True
struct Solution;

impl Solution {
    fn is_palindrome(s: String) -> bool {
        let chars: Vec<char> = s.chars().collect();
        let mut left = 0i32;
        let mut right = chars.len() as i32 - 1;

        while left < right {
            while left < right && !chars[left as usize].is_alphanumeric() {
                left += 1;
            }
            while left < right && !chars[right as usize].is_alphanumeric() {
                right -= 1;
            }

            if chars[left as usize].to_ascii_lowercase() != chars[right as usize].to_ascii_lowercase() {
                return false;
            }

            left += 1;
            right -= 1;
        }

        true
    }
}