Search code examples
rubyalgorithmcaesar-cipher

How did "print i[-1]" wrap from z to a in this caesar cipher code?


Like the title says, why do we use "print i[-1]" in this code?

def caesar_cipher (string, number)
  string.scan (/./) do |i|
    if ("a".."z").include? (i.downcase) # Identify letters only. 
      number.times {i = i.next}
    end
    print i[-1] # Wrap from z to a. 
  end
end

caesar_cipher("Testing abzxc.", 5)

I understand all of the code except that particular line. How was ruby able to wrap Z to A? I mean look at this code:

test1 = "z"
puts test1[-1]
# result is Z not A

I was expecting the result to be A but the result is Z. Can someone explain what am I missing here?


Solution

  • If the input is "z", the caesar_cipher("z", 5) will call the i = i.next 5 times, which moves i to the 5th element followed.

    i = "z"
    i = i.next    # aa
    i = i.next    # ab
    i = i.next    # ac
    i = i.next    # ad
    i = i.next    # ae
    

    Now, the i[-1] will extract the last character from the result, and discard the leading carry a.