Created
August 6, 2014 11:48
-
-
Save Rojo/921a85b71db16c8cb95c to your computer and use it in GitHub Desktop.
Int to Mixed Base (And Back)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Couple of functions that transform a given integer into a mixed-base string | |
# representation and back. The string representation is formed by three 'A-Z' | |
# characters (base 26), followed by four '0-9' digits (base 10). | |
# Some examples: | |
# | Integer | Pattern | | |
# | 0 | AAA0000 | | |
# | 1 | AAA0001 | | |
# | 9999 | AAA9999 | | |
# | 10000 | AAB0000 | | |
# | 285240 | ABC5240 | | |
# | 7032122 | BBB2122 | | |
def int2pattern(n) | |
def numeric_part(number) | |
number.to_s.tap { |digits| digits.prepend '0' * (4 - digits.length) } | |
end | |
def alphabetic_part(number) | |
return 'AAA' if number.eql? 0 | |
''.tap do |string| | |
Math.log(number, 26).to_i.downto(0) do |pow| | |
shift = number / 26 ** pow | |
string << ('A'.ord + shift).chr | |
number -= 26 ** pow * shift | |
end | |
string.prepend 'A' * (3 - string.length) | |
end | |
end | |
alphabetic_part(n / 10_000) + numeric_part(n % 10_000) | |
end | |
def pattern2int(s) | |
def alphabetic2int(string) | |
sum = 0 | |
(string.length).downto(1) do |n| | |
sum += (26 ** (n - 1)) * (string[-n].ord - 65) | |
end | |
sum * 10_000 | |
end | |
alphabetic2int($1) + $2.to_i if s =~ /([A-Z]+)(\d+)/ | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative 'int2pattern.rb' | |
describe 'the int2pattern function' do | |
context 'with a number below 10,000' do | |
it 'returns the expected pattern of a 4 digits number' do | |
number = 7695 | |
expect(int2pattern(number)).to eql 'AAA7695' | |
end | |
it 'returns the expected pattern of a 3 digits number' do | |
number = 695 | |
expect(int2pattern(number)).to eql 'AAA0695' | |
end | |
it 'returns the expected pattern of a 2 digits number' do | |
number = 95 | |
expect(int2pattern(number)).to eql 'AAA0095' | |
end | |
it 'returns the expected pattern of a 1 digit number' do | |
number = 5 | |
expect(int2pattern(number)).to eql 'AAA0005' | |
end | |
end | |
context 'with a number of 10,000 and above' do | |
it 'gets the pattern when the alphabetic part ranges 0..26' do | |
number = 178790 | |
expect(int2pattern(number)).to eql 'AAR8790' | |
end | |
it 'gets the pattern when the alphabetic part ranges (26)..(26^2)' do | |
number = 285240 | |
expect(int2pattern(number)).to eql 'ABC5240' | |
end | |
it 'gets the pattern when the alphabetic part ranges (26^2)..(26^3)' do | |
number = 7032122 | |
expect(int2pattern(number)).to eql 'BBB2122' | |
end | |
end | |
end | |
describe 'the pattern2int function' do | |
context 'with pattern representing a number below 10,000' do | |
it 'returns the expected 4 digits number' do | |
pattern = 'AAA7695' | |
expect(pattern2int(pattern)).to eql 7695 | |
end | |
it 'returns the expected 3 digits number' do | |
pattern = 'AAA0695' | |
expect(pattern2int(pattern)).to eql 695 | |
end | |
it 'returns the expected 2 digits number' do | |
pattern = 'AAA0095' | |
expect(pattern2int(pattern)).to eql 95 | |
end | |
it 'returns the expected 1 digit number' do | |
pattern = 'AAA0005' | |
expect(pattern2int(pattern)).to eql 5 | |
end | |
end | |
context 'with pattern representing a number of 10,000 and above' do | |
it 'gets the number when the alphabetic part ranges 0..26' do | |
pattern = 'AAR8790' | |
expect(pattern2int(pattern)).to eql 178790 | |
end | |
it 'gets the number when the alphabetic part ranges (26)..(26^2)' do | |
pattern = 'ABC5240' | |
expect(pattern2int(pattern)).to eql 285240 | |
end | |
it 'gets the number when the alphabetic part ranges (26^2)..(26^3)' do | |
pattern = 'BBB2122' | |
expect(pattern2int(pattern)).to eql 7032122 | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment