So to begin with, to test for a palindrome, I would start at the first and last character and work my way towards the middle comparing the characters. Once I reach halfway, if all the characters were the same, I know that the string is a palindrome.
However, I believe that the question is asking if any permutation of the string (rearranging the string in any way) can form a palindrome. I could rearrange the string into all possible permutations using recursion, however that would be more complicated than simply answering the question "can I make a palindrome from these characters".
To form a palindrome, all characters with the exception of one (the pivot at the middle in the case of an odd number of characters) must have an equal partner. So if I find more than one character that doesn't have an equal partner, my function would return false. Otherwise I can return true.
Also, one must consider the case of, well... case. If the characters are a mix of upper and lower case, should the function factor in case when looking for equal characters? I would argue no, especially considering phrases that may start with a capitalized word. So I would go ahead and make all my characters lower cased before going through my function.
Here is what I came up with for a function:
func canBePalindrome(string: String) -> Bool {
var uniqueCharacters = 0
var string = string.lowercased()
while string.count > 0 {
let characterToMatch = string.removeFirst()
let matchIndex = string.firstIndex(of: characterToMatch)
if let matchIndex = matchIndex {
string.remove(at: matchIndex)
} else {
uniqueCharacters += 1
if uniqueCharacters > 1 {
return false
}
}
}
return true
}
canBePalindrome(string: "tacocat") // returns true
canBePalindrome(string: "A nut for a jar of tuna") // returns true
canBePalindrome(string: "aaiieennll") // returns true
canBePalindrome(string: "yyoouui") // returns true
canBePalindrome(string: "daily") // returns false
canBePalindrome(string: "Was it a car or a cat I saw") // returns true
Once I realized that the required task was to test if a string can be permutated into a palindrome, writing the function was rather simple. While the string still has characters to remove, I take one out, look for a match and if there is none, increment my unique characters count. If the count goes over 1, the string can't be permutated into a palindrome and we return false. Otherwise, if we remove all the characters from the string, and the unique character count doesn't go over 1, the string can be permutated into a palindrome and we return true.
This is beautiful, thank you!