Reputation: 378
This line is throwing the error:
charLine.each_index { |i| charLine[i] = (charLine[i] + shift)}
edit: charLine[i]
is a number (ascii code) and shift
is a number also
I know it has to do with trying to add the number in the variable shift to the byte ascii code I have in the charLine array index. But I'm not even dealing with strings at all which is why I'm so confused with this error... Here's the method with the error:
def caesarCipher(string)
puts "Original:\n #{string}"
charLine = string.chars
charLine.each_index { |i| charLine[i]=charLine[i].bytes }
charLine.flatten!
puts charLine.inspect
shift = 1
alphabet = ('A'..'Z').to_a
while shift <= alphabet.size
#moving up in the alphabet using ascii code
charLine.each_index { |i| charLine[i] = (charLine[i] + shift)}
#converting back to letters
charLine.each_index { |x| charLine[x] = charLine[x].chr }
puts "Shifted:\n #{charLine.inspect}"
puts "With a letter shift of #{shift}"
shift = shift + 1
@@shiftyArray.push(charLine.flatten)
end
end
Upvotes: 0
Views: 2252
Reputation: 1113
I have managed to reproduce the problem and with some debugging output I can see that the first iteration runs fine and the problem only appears on the second iteration (shift = 2).
In the first iteration charLine is an array of integers, so integer + integer works out fine for this line: charLine.each_index { |i| charLine[i] = (charLine[i] + shift)}
But then charLine is converted into an array of strings on the next line of the loop:
#converting back to letters
charLine.each_index { |x| charLine[x] = charLine[x].chr }
So at the start of second iteration charLine is now an array of Strings, because it wasn't converted back. Then on the .each_line it tries to add up string + integer and it blows up.
The solution is to re-map your string array to integer at the start of every iteration.
charLine.map!(&:ord)
The alternative is to not modify the array and save the results into a temp variable, here is a working example:
def caesar_cipher(string)
shiftyArray = []
charLine = string.split(//)
charLine.map!(&:ord)
shift = 1
alphabet_size = 26
while shift <= alphabet_size
shifted_array = charLine.map { |c| (c + shift) < 122 ? (c + shift) : (c + shift) - 26 }
shifted_array.map!(&:chr)
p shifted_array
shift += 1
shiftyArray.push(shifted_array.join)
end
end
caesar_cipher("testing")
Upvotes: 0
Reputation: 24337
You are trying to add shift
, which is a Fixnum to a String. Just call to_s
on shift to convert it to a string:
charLine.each_index { |i| charLine[i] = (charLine[i] + shift.to_s)}
Upvotes: 1