Generate letters to represent number using ruby?

Ryan Montgomery picture Ryan Montgomery · Jan 31, 2013 · Viewed 11.2k times · Source

I would like to generate a sequence of letters i.e. "A", "DE" "GJE", etc. that correspond to a number. The first 26 are pretty easy so 3 returns "C", 26 returns "Z", and 27 would return "AA", 28 "AB", and so on.

The thing I can't quite figure out is how to do this so it will handle any number passed in. So if I pass in 4123 I should get back some combination of 3 letters since (26 * 26 * 26) allows for up to +17,000 combinations.

Any suggestions?

Answer

Dex picture Dex · Jan 17, 2015

A tweak on @sawa original answer for Ruby 2.0 since I couldn't get his to work as is:

class Numeric
  Alpha26 = ("a".."z").to_a
  def to_s26
    return "" if self < 1
    s, q = "", self
    loop do
      q, r = (q - 1).divmod(26)
      s.prepend(Alpha26[r]) 
      break if q.zero?
    end
    s
  end
end

and here it is going in reverse from string to integer:

class String
  Alpha26 = ("a".."z").to_a

  def to_i26
    result = 0
    downcased = downcase
    (1..length).each do |i|
      char = downcased[-i]
      result += 26**(i-1) * (Alpha26.index(char) + 1)
    end
    result
  end

end

Usage:

1234567890.to_s26 
# => "cywoqvj"

"cywoqvj".to_i26  
# => 1234567890

1234567890.to_s26.to_i26
# => 1234567890

"".to_i26
# => 0

0.to_s26
# => ""