Skip to content

Instantly share code, notes, and snippets.

@gesslar
Last active July 27, 2023 06:05
Show Gist options
  • Save gesslar/9fa00df3b01e45ada38a8817fd24bc18 to your computer and use it in GitHub Desktop.
Save gesslar/9fa00df3b01e45ada38a8817fd24bc18 to your computer and use it in GitHub Desktop.
Detects palindromes!
// Skippable characters are spaces and punctuation and symbols
const skippable = char => char.match(/[\s\p{P}\p{S}]/u)
// Tests for numeric characters
const numeric = char => char.match(/\d/u)
// The whole meaty sandwich
const is_palindrome = word => {
// Grab the length of the word(s)
const len = word.length
// If we have no word or the word is fewer than 2 characters
// We're not a palindrome
if( word === undefined || len < 2 ) return false
// Palindromes are case-insensitive, so let's just lower-case it.
word = word.toLowerCase()
// We begin at the the 0th character
let begin = 0
// We end at the length-1th character
let end = len - 1
// Do this operation at least once
do {
// What is our current "first" character for comparison
const first = word.charAt(begin)
// What is our current "last" character for comparison
const last = word.charAt(end)
// If we're a number, just return false. Numbers don't belong here.
// This is an _alpha_ club only! And cool punctuations, too.
// But mostly just cos they're decorative.
if(numeric(first) || numeric(last))
return false
// If we're a space or a punctuation, you can stay in the club.
// At the end of the do-while, we increment the begin and decrement
// the end to get new cursor positions. But, if we're skipping, we
// want to let the increment happen for the direction we're traveling
// (forward or backward), but we also want to re-compare against the
// the one that we're not skipping. So, if we're skipping first,
// we want to increment first to try again, but also increment the
// last, and vice versa. This is kind of hard for me to verbalise.
// You just should just risk everything and inhabit my brain for a
// little bit.
if(skippable(first)) {
end++
continue ;
}
if(skippable(last)) {
begin--
continue ;
}
// Now that we got all the above tests out of the way, are we the
// same characters? If not, we're not a palindrome. Flee!
if( first !== last )
return false
// Ok, we passed all of our tests. We're a palindrome.
return true
} while( ++begin < len && --end >= 0 ) ;
// Just in case ™.
return false
}
// A list of test words and phrases
const words = [
"kayak",
"colloquialism",
"deified",
"doorknob",
"rotator",
"repaper",
"deed",
"crusty",
"peep",
"wow",
"noon",
"civic",
"bob",
"racecar",
"level",
"mom",
"kangaroo",
"bird rib",
"taco cat",
"UFO tofu",
"Borrow or rob?",
"To be, or not to be!",
"Never odd or even.",
"We panic in a pew.",
"Won’t lovers revolt now?",
"Ma is a nun, as I am.",
"Don’t nod.",
"Did you eat ALL of the mothballs??",
"Sir, I demand, I am a maid named Iris.",
"Was it a car or a cat I saw? ",
"Yo, Banana Boy! ",
"Eva, can I see bees in a cave?",
"Madam, in Eden, I’m Adam. ",
"A man, a plan, a canal, Panama!",
"Never a foot too far, even. ",
"Red roses run no risk, sir, on Nurse’s order. ",
"He lived as a devil, eh?",
"Ned, I am a maiden. ",
"Now, sir, a war is won!",
"Evade me, Dave!",
"Dennis and Edna sinned. ",
"Step on no pets!"
]
const results = words.map( word => [ word, is_palindrome(word) ] )
console.table(results)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment