To get this to work reliably with all the possible whitespace characters, a simple change will suffice:
letters = sentence.gsub(/[[:space:]]/, '').downcase
letters == letters.reverse
[[:space:]] matches all unicode whitespace, including tabs, returns, non-breaking spaces and other wacky anomolies.
So, for instance, now this works:
puts palindrome?("ÑévëR \u00A0\u2002ødd ør \tëvéÑ\n\r\t ") # => true
However, the following won't work, because
String#downcase only works with ASCII:
puts palindrome?("ÑévëR ødd ør \tëvéñ\n\r\t ") # => false
Neither will the following, because the accented chars won't match:
puts palindrome?("Never odd ør \tëvén\n\r\t ") # => false
If you need to accurately convert accented characters to their root letters, you would need to use something like ActiveSupport's Multibyte Chars.