Files
bitburner-scripts/contracts/LZ-Decompress.js
T
2025-02-22 03:37:47 -07:00

65 lines
2.2 KiB
JavaScript

/*
Lempel-Ziv (LZ) compression is a data compression technique which encodes data using references to earlier parts of the data. In this variant of LZ, data is encoded in two types of chunk. Each chunk begins with a length L, encoded as a single ASCII digit from 1 to 9, followed by the chunk data, which is either:
1. Exactly L characters, which are to be copied directly into the uncompressed data.
2. A reference to an earlier part of the uncompressed data. To do this, the length is followed by a second ASCII digit X: each of the L output characters is a copy of the character X places before it in the uncompressed data.
For both chunk types, a length of 0 instead means the chunk ends immediately, and the next character is the start of a new chunk. The two chunk types alternate, starting with type 1, and the final chunk may be of either type.
You are given the following LZ-encoded string:
2wg127MSbUJRP473Ak5681h74844rfOrky995VcHUV511Q854FDL4
Decode it and output the original string.
Example: decoding '5aaabb450723abb' chunk-by-chunk
5aaabb -> aaabb
5aaabb45 -> aaabbaaab
5aaabb450 -> aaabbaaab
5aaabb45072 -> aaabbaaababababa
5aaabb450723abb -> aaabbaaababababaabb
*/
/** @param {NS} ns */
export function lzDecompress(ns, lz) {
var output = "";
var type = 0;
for(var i = 0; i < lz.length;) {
var length = Number.parseInt(lz[i]);
if(length == 0) {
i++;
continue;
}
if(length == 0) {
ns.tprint("didn't continue!");
}
i++;
if(!isNaN(parseInt(lz[i]) && i != 1) && type == 1) { // Type 2 Chunk
var v = Number.parseInt(lz[i]);
var j = output.length - v;
for(var counter = 0; counter < length; counter++) {
output += output[j];
j = output.length - v;
}
i++;
type = 0;
} else { // Type 1 Chunk
var j = i;
for(; j < i + length; j++) {
output += lz[j];
}
i = j;
type = 1;
}
}
return output;
}
export async function main(ns) {
var lz = ns.args[0];
ns.tprint(lzDecompress(ns, lz));
}