Skip to content

Instantly share code, notes, and snippets.

@Rojo
Created August 6, 2014 11:48
Show Gist options
  • Save Rojo/921a85b71db16c8cb95c to your computer and use it in GitHub Desktop.
Save Rojo/921a85b71db16c8cb95c to your computer and use it in GitHub Desktop.
Int to Mixed Base (And Back)
# 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
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