Проблема с вашим кодом заключается в том, что вам нужно отслеживать количество неразрывных левых скобок, когда вы шагаете по символам строки, слева направо, число, которое может увеличиваться или уменьшаться. Вы можете получить желаемые строки следующим образом.
def add_closing_parens(str)
n = 0
s = str.each_char.with_object('') do |c,s|
s << c
case c
when '('
n += 1
when ')'
n -= 1
when '?', '.', '!'
if n > 0
s << ')'
n -= 1
end
end
end
n.zero? ? s : nil
end
n
- это число оставленных паренов, которые еще не были закрыты. Я добавил восклицательный знак, так как он может завершить предложение.
add_closing_parens "Hey how are you? (Is (your) name Larry?"
#=> "Hey how are you?) (Is (your) name Larry?)"
add_closing_parens "(((Hey) how are you? how is it going."
#=> "(((Hey) how are you?) how is it going.)"
add_closing_parens "((Hey (how (are) you? What's happenin? Wow!"
#=> "((Hey (how (are) you?) What's happenin?) Wow!)"
add_closing_parens "Hey how (are) you? (What's (happenin? Wow!"
#=> "Hey how (are) you? (What's (happenin?) Wow!)"
str = "(((Hey (how (are) you? What's happenin? Wow!"
add_closing_parens str
#=> nil
Если вы хотите добавить пропущенные правые скобки в конце, замените две последние строки на:
end << ')' * n
после чего:
add_closing_parens str
#=> "(((Hey (how (are) you?) What's happenin?) Wow!))"