use fmt; fn item_encode(count: int, val: u32) u32 = ((count-1)<<24):u32 | (val&0xffffff); fn item_decode(c: u32) (int, u32) = ((((c&0xff000000)>>24)+1):int, c&0xffffff); // caller freeeee export fn rle_encode(d: []u32) []u32 = { let out: []u32 = []; let start = 0z; for (start < len(d)) { let this = d[start]; let ix = start + 1; for (ix < len(d) && d[ix] == this) ix += 1; const val = this; let count = (ix - start): int; fmt::printfln("#{:_06x} x{}",val, count)!; for (count > 0) { append(out, item_encode(count%256, val)); count -= 256; }; start = ix; }; return out; }; // ooooo caller freeeeeee meee export fn rle_decode(d: []u32) []u32 = { let out: []u32 = []; for (const k .. d) { const (count, val) = item_decode(k); append(out, [val...], count: size); }; return out; }; fn dotest(eu: []u32) void = { const ee = rle_encode(eu); defer free(ee); // for (const k .. ee) { // const (count, val) = item_decode(k); // fmt::printfln("0x{:_08x} | #{:_06x} x{}", k, val, count)!; // }; const dd = rle_decode(ee); defer free(dd); assert(len(eu) == len(dd), "length mismatch??"); let good = true; for (let i = 0z; i < len(eu); i += 1) { assert(eu[i] == dd[i], "value wrong"); // fmt::printfln("{} vs {}",eu[i], dd[i])!; // if (eu[i] != dd[i]) { good=false; fmt::println("uh oh")!; }; }; // if (good) fmt::printfln("good yay")!; }; @test fn euou() void = dotest([1,1,1,1,1,2,2,2,3,3,3,3,3,4,4,5,5,5,666,69,9,9]); @test fn oeuoeu2() void = dotest([1,2,3,4,5]); @test fn oeuoeu2() void = dotest([1,1,1]); @test fn oeuoeu2() void = dotest([1,6]); @test fn oeuoeu2() void = dotest([1]);