1

I'm trying to solve the longest palindrome problem in Ruby, and I found the answer on stackoverflow:

ANSWER:

Suppose the string has n characters. First see if the entire string is a palindrome. If it is, return the string. Fini! If not, see if either of the two substrings of length n-1 is a palindrome. If one is, return it. If not, examine substrings of length n-2, and so on. As long as the string contains at least one letter, the longest palindrome will be found.

def longest_palindrome(str)
  arr = str.downcase.chars
  str.length.downto(1) do |n|
    ana = arr.each_cons(n).detect { |b| b == b.reverse }
    return ana.join if ana
  end
end

puts longest_palindrome "ilikeracecar"

But I'm having trouble understanding this line:

return ana.join if ana

What does

if ana

mean?

Also why wouldn't this work?

def longest_palindrome(str)
  arr = str.downcase.chars
  str.length.downto(1) do |n|
    ana = arr.each_cons(n).detect { |b| b == b.reverse }
    return ana.join
  end
end

When I run this, it gives me

undefined method `join' for nil:NilClass (NoMethodError)

But I don't understand why ana would be nil when I've detected the first array that meets the condition which would be ["r", "a", "c", "e", "c", "a", "r"] so shouldn't this be in ana?

iswg
  • 195
  • 1
  • 10

1 Answers1

3

Each time this code runs:

ana = arr.each_cons(n).detect { |b| b == b.reverse }

ana gets a new value. detect will either return the first element that is a palindrome or nil. So in the case where n is a length such that there is no palindrome, ana will be nil.

return ana.join if ana

means "if ana is true (e.g. non-nil), return ana.join". In your modified code, sometimes ana is nil, and you try to join it anyway.

It might be easier to understand the code if you add some logging:

def longest_palindrome(str)
  arr = str.downcase.chars
  str.length.downto(1) do |n|
    puts "n = #{n}"
    ana = arr.each_cons(n).detect { |b| b == b.reverse }
    if ana == nil then
      puts "ana is nil"
    else
      puts "ana = #{ana.join}"
    end
    return ana.join if ana
  end
end

puts longest_palindrome('a racecar')

Output:

n = 9
ana is nil
n = 8
ana is nil
n = 7
ana = racecar
racecar

As you can see, ana is nil until you get down to size 7.

user94559
  • 59,196
  • 6
  • 103
  • 103