4

I need to implement a decimal to chars converter. I have 26 chars available, so it's about converting an integer to base 26 system and then, changing each number to it's alphabet counterpart. I don't want to use the characters 0-9 in the final result string. I can use to_s() method and this is how it goes:

82.to_s(26)  #=> "34" / which gives me "de"
120.to_s(26)  #=> "4g" / which should give me "aep", but it's not

Ruby to_s() method returns a value in a format that is not helpful. Number 82 is converted fine, but conversion of 120 returns a value I have no idea how to handle.

Could anyone explain how I can make the 120 convertion (as an example) return aep equivalent? In other words, how to convert from decimal base to 26 but without using numbers in output?

mbajur
  • 4,406
  • 5
  • 49
  • 79
  • 2
    I am not sure why you expect "aep" for 120? In base 26, 120 must be only two symbols. I get "eq". – Neil Slater Jul 22 '13 at 10:55
  • You say you show you're using `to_i`, but your code has `to_s` instead. I have no idea what you are writing about. – sawa Jul 22 '13 at 11:11
  • I'm sorry, it was a typo. – mbajur Jul 22 '13 at 11:19
  • You should be more careful. There is another one left. – sawa Jul 22 '13 at 11:20
  • Sorry for all this, the truth is that i had based this question on someone elses calculations which i don't understand at all. That's why it's all so haotic, i had no idea what i was writing nor questioning about. Thanks for your patience. Writing about something i have no idea about? never again! – mbajur Jul 22 '13 at 11:25

1 Answers1

14

Ruby's Fixnum#to_s( base ) and String#to_i( base ) are for representing numbers in different bases. You cannot use arbitrary characters with them though, they are designed to be compatible with conventions for hex and base64 amongst other things.

If you were not converting to a different base, but simply encoding decimal digits as letters and back, then a simple substitution would be all you needed:

46.to_s.tr( "0123456789", "abcdefghijk" )
=> "eg"

"eg".tr( "abcdefghijk", "0123456789" ).to_i
=> 46

So, if you want to do both, and use a-z to represent your number in base 26:

46.to_s(26).tr( "0123456789abcdefghijklmnopq", "abcdefghijklmnopqrstuvwxyz" )
=> "bu"

"bu".tr( "abcdefghijklmnopqrstuvwxyz", "0123456789abcdefghijklmnopq" ).to_i(26)
=> 46
Neil Slater
  • 26,512
  • 6
  • 76
  • 94
  • yes it's more or less that but the source number base should not be decimal but 26 – mbajur Jul 22 '13 at 10:49
  • In that case, convert to base 26 first - I will show example. – Neil Slater Jul 22 '13 at 10:50
  • ok, looks like i have a problem with explaining what i want to achieve :( Basically - i've done this calculation on paper and converting 120 from decimal base to 26 gave me number equivalent of aep (120%26=16(it's p) and 120/26=4, it all gives 'aep'). Does it makes any sense for you ? – mbajur Jul 22 '13 at 10:59
  • 1
    No, it doesn't make sense, where does the "a" come from? – Neil Slater Jul 22 '13 at 11:01
  • 2
    Note that `"a"` stands for `0` in this system, so whether you prepend the string with `"a"` makes no difference, and it should be omitted. The character `"a"` should not appear as the leftmost character. – sawa Jul 22 '13 at 11:14
  • I had a mistake in my calculations. Also i forgot that `a` stands for `0` and is optional. – mbajur Jul 22 '13 at 11:24