Skip to content

Instantly share code, notes, and snippets.

@netshade
Created June 14, 2012 15:47
Show Gist options
  • Save netshade/2931088 to your computer and use it in GitHub Desktop.
Save netshade/2931088 to your computer and use it in GitHub Desktop.
Silly base 93 numbers
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