Reputation:
I'm trying to solve a problem where when given a string I convert each letter 13 places further in the alphabet. For example
a => n
b => o
c => p
Basically every letter in the string is converted 13 alphabet spaces.
If given the string 'sentence' i'd like it to convert to
'feagrapr'
I have no idea how to do it. I've tried
'sentence'.each_char.select{|x| 13.times{x.next}}
and I still couldn't solve it.
This one has been puzzling me for a while now, and I've given up trying to solve it.
I need your help
Upvotes: 1
Views: 1181
Reputation: 1575
Using String#tr
as TCSGrad suggests is the ideal solution.
Some alternatives:
case
, ord
, and chr
word = 'sentence'
word.gsub(/./) do |c|
case c
when 'a'..'m', 'A'..'M' then (c.ord + 13).chr
when 'n'..'z', 'N'..'Z' then (c.ord - 13).chr
else c
end
end
gsub
and a hash for multiple replacementword = 'sentence'
from = [*'a'..'z', *'A'..'Z']
to = [*'n'..'z', *'a'..'m', *'N'..'Z', *'A'..'M']
cipher = from.zip(to).to_h
word.gsub(/[a-zA-Z]/, cipher)
Note, Array#to_h
requires Ruby 2.1+. For older versions of Ruby, use
cipher = Hash[from.zip(to)]
.
Upvotes: 1
Reputation: 12118
IMHO, there is a better way to achieve the same in idiomatic Ruby:
def rot13(string)
string.tr("A-Za-z", "N-ZA-Mn-za-m")
end
This works because the parameter 13 is hard-coded in the OP's question, in which case the tr
function seems to be just the right tool for the job!
Upvotes: 4
Reputation: 1214
From here -> How do I increment/decrement a character in Ruby for all possible values?
you should do it like:
def increment_char(char)
return 'a' if char == 'z'
char.ord.next.chr
end
def increment_by_13(str)
conc = []
tmp = ''
str.split('').each do |c|
tmp = c
13.times.map{ |i| tmp = increment_char(tmp) }
conc << tmp
end
conc
end
Or close.
Upvotes: -1