# Palindrome and Reverse a String Problems (JavaScript, Python)

### Problem 1

Given a string, the task is to reverse the string and return a reversed string.

### Problem 2

Given a string, return true if the string is a palindrome or false if it is not.

## Code

Just for practicing, I've implemented reverse string and palindrome problems using JavaScript and Python. If you'd like to review the codes and provide any change/improvement recommendations, please do so and I appreciate that.

### JavaScript

// Problem 1
// Given a string, return true if the string is a palindrome
// or false if it is not.  Palindromes are strings that
// form the same word if it is reversed. *Do* include spaces
// and punctuation in determining if the string is a palindrome.
// --- Examples:
//   abba => true
//   abc => false

// Problem 2
// Given a string, return a new string with the reversed
// order of characters
// --- Examples
//   apple => leppa
//   hello => olleh
//   Greetings! => !sgniteerG

// This method tests if the string is a palindrome using four reverse string functions
function check_palindrome(original_string) {
original_string = original_string.toLowerCase();
let reversed_string_1 = reverse_string_built_in(original_string);
let reversed_string_2 = reverse_string_reduce(original_string);
let reversed_string_3 = reverse_string_for_of_loop(original_string);
let reversed_string_4 = reverse_string_negative_for_loop(original_string);

// If the original string is a palindrome
if (reversed_string_1 === original_string && reversed_string_2 === original_string && reversed_string_3 === original_string && reversed_string_4 === original_string) {
return true;
// If the original string is not a palindrome
} else {
return false;
}
}

// This method is an slightly optimized version of checking for palindrome
function check_palindrome_optimized(original_string) {
original_string = original_string.toLowerCase();
count = 0;
return original_string.split('').every((char, i) => {
count++;
if (count > Math.floor(original_string.length / 2)) {
return true
}
return char === original_string[original_string.length - i - 1];
});
}

// This method uses reverse() built in function
function reverse_string_built_in(original_string) {
return original_string.split('').reverse().join('');
}

// This method uses for of loop
function reverse_string_for_of_loop(original_string) {
let reversed_string = '';

for (let char of original_string) {
reversed_string = char + reversed_string;
}

return reversed_string;
}

// Using negative for loop and contact
function reverse_string_negative_for_loop(original_string) {
let reversed_string = '';

for (var i = original_string.length - 1; i >= 0; i--) {
reversed_string = reversed_string.concat(original_string[i]);
}
return reversed_string;
}

//Using reduce() method
function reverse_string_reduce(original_string) {
return original_string.split('').reduce((reversed_string, char) => char + reversed_string, '');
}

// Here, we are testing our palindrome words
words_array = ['apple', 'kayak', 'abc1221cba', 'reviver', 'redivider', '1736', 'deified', 'Anna', 'Able was I ere I saw Elba', "Madam, I'm Adam", 'civic', 'RaDar', 'Never odd or even', 'LeVeL', 'kayak', 'racecar', 'Doc, note: I dissent. A fast never prevents a fatness. I diet on cod', 'redder', 'madam', '1991', 'refer'];

for (let word of words_array) {
if (check_palindrome_optimized(word) === true && check_palindrome(word) === true) {
console.log('π "'.concat(word, '" is a palindrome!'));
} else {
console.log('π "'.concat(word, '" is not a palindrome!'));
}
}

### Python

def reverse_string(original_string):
'''
Returns a reversed string give a string
'''
reversed_string = ''
for char in original_string:
reversed_string = char + reversed_string

return reversed_string

def reverse_string_slice(original_string):
'''Returns a reversed string give a string'''
return original_string[::-1]

def check_palindrome(original_string):
'''Returns true if an input string is a palindrome'''
original_string = original_string.lower()
if reverse_string_slice(original_string) == original_string and reverse_string(original_string) == original_string:
return True
return False

# Here, we are testing our palindrome words
words_array = ['apple', 'kayak', 'abc1221cba', 'reviver', 'redivider', '1736', 'deified', 'Anna', 'Able was I ere I saw Elba', "Madam, I'm Adam", 'civic', 'RaDar',
'Never odd or even', 'LeVeL', 'kayak', 'racecar', 'Doc, note: I dissent. A fast never prevents a fatness. I diet on cod', 'redder', 'madam', '1991', 'refer']

delimiter = '-'*50

for word in words_array:
print(delimiter)
print(f'The reverse of "{word}" is "{reverse_string(word)}"')
if check_palindrome(word) == True:
print(f'π "{word}" is a palindrome!')
else:
print(f'π "{word}" is not a palindrome!')


### Output

--------------------------------------------------
The reverse of "apple" is "elppa"
π "apple" is not a palindrome!
--------------------------------------------------
The reverse of "kayak" is "kayak"
π "kayak" is a palindrome!
--------------------------------------------------
The reverse of "abc1221cba" is "abc1221cba"
π "abc1221cba" is a palindrome!
--------------------------------------------------
The reverse of "reviver" is "reviver"
π "reviver" is a palindrome!
--------------------------------------------------
The reverse of "redivider" is "redivider"
π "redivider" is a palindrome!
--------------------------------------------------
The reverse of "1736" is "6371"
π "1736" is not a palindrome!
--------------------------------------------------
The reverse of "deified" is "deified"
π "deified" is a palindrome!
--------------------------------------------------
The reverse of "Anna" is "annA"
π "Anna" is a palindrome!
--------------------------------------------------
The reverse of "Able was I ere I saw Elba" is "ablE was I ere I saw elbA"
π "Able was I ere I saw Elba" is a palindrome!
--------------------------------------------------
--------------------------------------------------
The reverse of "civic" is "civic"
π "civic" is a palindrome!
--------------------------------------------------
--------------------------------------------------
The reverse of "Never odd or even" is "neve ro ddo reveN"
π "Never odd or even" is not a palindrome!
--------------------------------------------------
The reverse of "LeVeL" is "LeVeL"
π "LeVeL" is a palindrome!
--------------------------------------------------
The reverse of "kayak" is "kayak"
π "kayak" is a palindrome!
--------------------------------------------------
The reverse of "racecar" is "racecar"
π "racecar" is a palindrome!
--------------------------------------------------
The reverse of "Doc, note: I dissent. A fast never prevents a fatness. I diet on cod" is "doc no teid I .ssentaf a stneverp reven tsaf A .tnessid I :eton ,coD"
π "Doc, note: I dissent. A fast never prevents a fatness. I diet on cod" is not a palindrome!
--------------------------------------------------
The reverse of "redder" is "redder"
π "redder" is a palindrome!
--------------------------------------------------
--------------------------------------------------
The reverse of "1991" is "1991"
π "1991" is a palindrome!
--------------------------------------------------
The reverse of "refer" is "refer"
π "refer" is a palindrome!

• I presume, by "string" you mean "a sequence of Latin letters"? Otherwise, your problems would be much harder to solve. See this comment: stackoverflow.com/a/16776621/989121 Oct 15, 2019 at 7:19
• Typically, punctuation is ignored when testing for palindromes, so "Doc, note:..." should return true. Likewise, "Never odd or even" should return true. Oct 15, 2019 at 10:47
• You could also go one step further here and add a reverse method to the String prototype (in js) so you could do: "test".reverse(). This keeps the code nicely encapsulated and re-usable. With it being on the prototype, every instance gets the same function. Oct 15, 2019 at 15:16

## Boolean expression returns

This applies to both your Javascript and Python implementations:

if (reversed_string_1 === original_string && reversed_string_2 === original_string && reversed_string_3 === original_string && reversed_string_4 === original_string) {
return true;
// If the original string is not a palindrome
} else {
return false;
}

if reverse_string_slice(original_string) == original_string and reverse_string(original_string) == original_string:
return True
return False


Your expression is already a boolean; you don't need an if. In other words,

return reverse_string_slice(original_string) == original_string and reverse_string(original_string) == original_string


## Boolean comparison

if check_palindrome(word) == True:


should simply be

if check_palindrome(word):


Also, the convention is that boolean-valued functions are named like is_palindrome.

## words_array

First of all: This isn't an array, because Python doesn't have those. It's a list. Second, just call it words - usually it's not useful to include the type of a variable in its name. Finally: you shouldn't even be using a list, because you won't be mutating (modifying) it; use a tuple (in parens, not brackets).

• Technically, Python does have arrays. However, they are rarely used. The term "array" is also used in the context of numpy.
– GZ0
Oct 15, 2019 at 1:56
• That's fair. It's more accurate to say that Python has arrays, but they aren't first-class. Oct 15, 2019 at 2:17

In Python, your check_palindrome function can be made more efficient and pythonic:

def check_palindrome(original_string):
"""Returns true if an input string is a palindrome"""
original_string = original_string.lower()
return all(r == o for r, o in zip(reversed(original_string), original_string[:len(original_string)//2]))


This only iterates over half of the characters as opposed to your version. You could also use islice from itertools, for example:

def check_palindrome(original_string):
"""Returns true if an input string is a palindrome"""
original_string = original_string.lower()
original = islice(original_string, len(original_string) // 2)
return all(r == o for r, o in zip(reversed(original_string), original))


Also note that docstrings should be double quoted.

• original_string[::len(original_string)//2] should be original_string[:len(original_string)//2].
– GZ0
Oct 15, 2019 at 1:59
• @GZ0 Thanks for the catch. Oct 15, 2019 at 2:02