Created
June 14, 2012 15:47
-
-
Save netshade/2931088 to your computer and use it in GitHub Desktop.
Silly base 93 numbers
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
module CompactUnsignedInt | |
ASCII_RANGE = 33..126 | |
ASCII_LENGTH = ASCII_RANGE.last - ASCII_RANGE.first | |
module InstanceMethods | |
def to_compact_int | |
base = to_i | |
raise "Negative numbers will not convert" if base < 0 | |
base = base.abs | |
result = [] | |
while base != 0 | |
div = base / ASCII_LENGTH | |
rem = base % ASCII_LENGTH | |
result << ((ASCII_RANGE.first + rem).chr) | |
base = div | |
end | |
result.join | |
end | |
end | |
module ClassMethods | |
def from_compact_int(str) | |
str = str.strip | |
result = 0 | |
power = 0 | |
str.each_byte do |b| | |
result += (b - ASCII_RANGE.first) * (ASCII_LENGTH ** power) | |
power += 1 | |
end | |
result | |
end | |
end | |
end | |
Integer.send(:include, CompactUnsignedInt::InstanceMethods) | |
Integer.send(:extend, CompactUnsignedInt::ClassMethods) | |
cnt = 1_000_000 | |
sz = 0 | |
0.upto(cnt).each do |i| | |
compact = i.to_compact_int | |
sz += compact.size | |
raise "Error #{i} : #{compact}" unless i == Integer.from_compact_int(compact) | |
end | |
puts "Average size is #{sz / cnt}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment