Always good to have variety
Interesting topic. Here’s my take thanks to the snippets above:
local module = {}
module.compress32 = function(booleans_table)
assert(#booleans_table <= 32, "can't compress tables longer than 32")
local compressed_booleans = 0
for i = 1, #booleans_table do
if booleans_table[i] == true then
compressed_booleans += 2 ^ (i - 1)
end
end
return compressed_booleans
end
module.check_compressed_bit = function(compressed_booleans, bit_number)
return bit32.extract(compressed_booleans, bit_number - 1) == 1
end
module.decompress32 = function(compressed_booleans)
local booleans_table = {}
local found_last_true = false
for i = 32, 1, -1 do
print(i)
if module.check_compressed_bit(compressed_booleans, i) == true then
found_last_true = true
booleans_table[i] = true
elseif found_last_true == true then
booleans_table[i] = false
end
end
return booleans_table
end
return module
Additionally
Since everything in datastores is encoded as a JSON string and the limit is string length instead of bit size, would it be useful to have numerical compression too? Basically convert numbers to as high base as possible so they appear shorter in the string. This could be useful for games that need huge numbers with precision or base building games that save a very precise CFrame. Here's an example:local module = {}
local symbol_table = {"1", "2", "3", "4", "5", "6", "7", "8", "9",
"a", "b", "c", "d", "e", "f",
"g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"A", "B", "C", "D", "E", "F",
"G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
symbol_table[0] = "0"
local function get_symbol_index(number_string, i)
return table.find(symbol_table, string.sub(number_string, i, i)) or 0
end
local function to_base_10(number, from_base)
local new_number = 0
for i = 1, #number do
new_number += get_symbol_index(number, #number - (i - 1)) * (from_base ^ (i - 1))
end
return new_number
end
local function to_base_x(base_10_number, to_base)
local new_number = ""
while base_10_number > 0 do
local remainder = base_10_number % to_base
base_10_number = math.floor(base_10_number / to_base)
new_number = symbol_table[remainder].. new_number
end
return new_number
end
module.convert = function(number: string, from_base: number, to_base: number)
if typeof(number) ~= "string" then number = tostring(number) end
local base_10_number = to_base_10(number, from_base)
local new_number = to_base_x(base_10_number, to_base)
return new_number
end
return module