4
\$\begingroup\$

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 "Madam, I'm Adam" is "madA m'I ,madaM"
🍎 "Madam, I'm Adam" is not a palindrome!
--------------------------------------------------
The reverse of "civic" is "civic"
🍏 "civic" is a palindrome!
--------------------------------------------------
The reverse of "RaDar" is "raDaR"
🍏 "RaDar" 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 "madam" is "madam"
🍏 "madam" is a palindrome!
--------------------------------------------------
The reverse of "1991" is "1991"
🍏 "1991" is a palindrome!
--------------------------------------------------
The reverse of "refer" is "refer"
🍏 "refer" is a palindrome!
\$\endgroup\$
  • 1
    \$\begingroup\$ 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 \$\endgroup\$ – georg Oct 15 at 7:19
  • 1
    \$\begingroup\$ Typically, punctuation is ignored when testing for palindromes, so "Doc, note:..." should return true. Likewise, "Never odd or even" should return true. \$\endgroup\$ – Baldrickk Oct 15 at 10:47
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Magrangs Oct 15 at 15:16
9
\$\begingroup\$

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).

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

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ original_string[::len(original_string)//2] should be original_string[:len(original_string)//2]. \$\endgroup\$ – GZ0 Oct 15 at 1:59
  • \$\begingroup\$ @GZ0 Thanks for the catch. \$\endgroup\$ – Daniel Mesejo Oct 15 at 2:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.