0

Say you have the string "Hi". How do you get a value of 8, 9 ("H" is the 8th letter of the alphabet, and "i" is the 9th letter). Then say, add 1 to those integers and make it 9, 10 which can then be made back into the string "Ij"? Is it possible?

sawa
  • 165,429
  • 45
  • 277
  • 381
HLatfullin
  • 13
  • 2
  • 8

4 Answers4

3

Note Cary Swoveland had already given a same answer in a comment to the question.

It is impossible to do that through the numbers 8 and 9 because these numbers do not contain information about the case of the letters. But if you do not insist on converting the string via the number 8 and 9, but instead more meaningful numbers like ASCII code, then you can do it like this:

"Hi".chars.map(&:next).join
# => "Ij"
sawa
  • 165,429
  • 45
  • 277
  • 381
  • I posted a solution below that does what OP wants. Adjust argument to rotate if you want to do a bigger shift. Granted I don't use the 8 and 9 like mentioned in the question, but the answer is very much in the spirit of the question I think. – Michael Kohl Jun 21 '14 at 05:18
2

use ord to get the ASCII index, and chr to bring it back.

'Hi'.chars.map{|x| (x.ord+1).chr}.join
Fabricator
  • 12,722
  • 2
  • 27
  • 40
0

You can also create an enumerable of character ordinals from a string using the codepoints method.

string = "Hi"

string.codepoints.map{|i| (i + 1).chr}.join
=> "Ij"
SteveTurczyn
  • 36,057
  • 6
  • 41
  • 53
0

Preserving case and assuming you want to wrap around at "Z":

upper = [*?A..?Z]
lower = [*?a..?z]
LOOKUP = (upper.zip(upper.rotate) + lower.zip(lower.rotate)).to_h
s.each_char.map { |c| LOOKUP[c] }.join
#=> "Ij"
Michael Kohl
  • 66,324
  • 14
  • 138
  • 158