Created
July 25, 2012 15:12
-
-
Save silentbicycle/3176689 to your computer and use it in GitHub Desktop.
run-length encoding
This file contains 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
-- Use literal zero for escape before compression data | |
local esc = 0 | |
-- Run-length-encode an array of ints. | |
function encode(ints) | |
local res, i, ct = {}, 1, 1 -- result, index, count | |
while i <= #ints do | |
local v = ints[i] | |
while ints[i+1] == v do | |
ct = ct + 1 | |
i = i + 1 | |
end | |
-- if there's benefit in reducing a series | |
if ct > 3 or (ct >= 2 and v == esc) then | |
res[#res+1] = 0 | |
res[#res+1] = ct | |
res[#res+1] = v | |
-- literal zeroes must be escaped | |
elseif v == esc then | |
for n=1,ct do | |
res[#res+1] = esc | |
res[#res+1] = esc | |
end | |
-- leave other content as-is | |
else | |
for n=1,ct do | |
res[#res+1] = v | |
end | |
end | |
ct = 1 | |
i = i + 1 | |
end | |
return res | |
end | |
-- Decode an array of ints from encode(). | |
function decode(ints) | |
local res = {} | |
local i = 1 | |
while i <= #ints do | |
local v = ints[i] | |
-- check for escaped 0s and series markers after escapes | |
if v == esc then | |
if ints[i+1] == esc then | |
res[#res+1] = esc -- escaped 0 literal | |
i = i + 2 | |
else | |
local count, value = ints[i+1], ints[i+2] | |
for n=1,count do res[#res+1] = value end | |
i = i + 3 | |
end | |
else | |
res[#res+1] = v | |
i = i + 1 | |
end | |
end | |
return res | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment