Files

240 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: 5ea2815e364d9a2222ea55f8
title: LZW компресія
challengeType: 5
forumTopicId: 385288
dashedName: lzw-compression
---
# --description--
Алгоритм Лемпеля-Зіва-Велча (LZW) забезпечує стискання даних без втрат.
Детальніше про алгоритм можна прочитати у [статті ](https://en.wikipedia.org/wiki/Lempel-Ziv-Welch) Вікіпедія.
# --instructions--
Напишіть функцію, яка бере два параметри. Перший параметр - логічне значення, де `true`позначає стиснути та `false`позначає розвернути. Другий параметр - це рядок або масив для обробки. Якщо це рядок для стиснення, поверніть масив чисел. Якщо це масив чисел для розгортання, поверніть рядок.
# --hints--
`LZW` має бути функцією.
```js
assert(typeof LZW === 'function');
```
`LZW(true, "TOBEORNOTTOBEORTOBEORNOT")` має повернути рядок.
```js
assert(Array.isArray(LZW(true, 'TOBEORNOTTOBEORTOBEORNOT')));
```
`LZW(false, [84, 79, 66, 69, 79, 82, 78, 79, 84, 256, 258, 260, 265, 259, 261, 263])` має повернути рядок.
```js
assert(
typeof LZW(false, [
84,
79,
66,
69,
79,
82,
78,
79,
84,
256,
258,
260,
265,
259,
261,
263
]) === 'string'
);
```
`LZW(true, "TOBEORNOTTOBEORTOBEORNOT")` має повернути `[84, 79, 66, 69, 79, 82, 78, 79, 84, 256, 258, 260, 265, 259, 261, 263]`.
```js
assert.deepEqual(LZW(true, 'TOBEORNOTTOBEORTOBEORNOT'), [
84,
79,
66,
69,
79,
82,
78,
79,
84,
256,
258,
260,
265,
259,
261,
263
]);
```
`LZW(false, [84, 79, 66, 69, 79, 82, 78, 79, 84, 256, 258, 260, 265, 259, 261, 263])` має повернути `"TOBEORNOTTOBEORTOBEORNOT"`.
```js
assert.equal(
LZW(false, [
84,
79,
66,
69,
79,
82,
78,
79,
84,
256,
258,
260,
265,
259,
261,
263
]),
'TOBEORNOTTOBEORTOBEORNOT'
);
```
`LZW(true, "0123456789")` має повернути `[48, 49, 50, 51, 52, 53, 54, 55, 56, 57]`.
```js
assert.deepEqual(LZW(true, '0123456789'), [
48,
49,
50,
51,
52,
53,
54,
55,
56,
57
]);
```
`LZW(false, [48, 49, 50, 51, 52, 53, 54, 55, 56, 57])` має повернути `"0123456789"`.
```js
assert.equal(
LZW(false, [48, 49, 50, 51, 52, 53, 54, 55, 56, 57]),
'0123456789'
);
```
`LZW(true, "BABAABAAA")` має повернути `[66, 65, 256, 257, 65, 260]`.
```js
assert.deepEqual(LZW(true, 'BABAABAAA'), [66, 65, 256, 257, 65, 260]);
```
`LZW(false, [66, 65, 256, 257, 65, 260])` має повернути `"BABAABAAA"`.
```js
assert.equal(LZW(false, [66, 65, 256, 257, 65, 260]), 'BABAABAAA');
```
# --seed--
## --seed-contents--
```js
function LZW (compressData, input) {
}
```
# --solutions--
```js
function LZW (compressData, input) {
function compress(uncompressed) {
// Build the dictionary.
var i,
dictionary = {},
c,
wc,
w = "",
result = [],
dictSize = 256;
for (i = 0; i < 256; i += 1) {
dictionary[String.fromCharCode(i)] = i;
}
for (i = 0; i < uncompressed.length; i += 1) {
c = uncompressed.charAt(i);
wc = w + c;
//Do not use dictionary[wc] because javascript arrays
//will return values for array['pop'], array['push'] etc
// if (dictionary[wc]) {
if (dictionary.hasOwnProperty(wc)) {
w = wc;
} else {
result.push(dictionary[w]);
// Add wc to the dictionary.
dictionary[wc] = dictSize++;
w = String(c);
}
}
// Output the code for w.
if (w !== "") {
result.push(dictionary[w]);
}
return result;
}
function decompress(compressed) {
// Build the dictionary.
var i,
dictionary = [],
w,
result,
k,
entry = "",
dictSize = 256;
for (i = 0; i < 256; i += 1) {
dictionary[i] = String.fromCharCode(i);
}
w = String.fromCharCode(compressed[0]);
result = w;
for (i = 1; i < compressed.length; i += 1) {
k = compressed[i];
if (dictionary[k]) {
entry = dictionary[k];
} else {
if (k === dictSize) {
entry = w + w.charAt(0);
} else {
return null;
}
}
result += entry;
// Add w+entry[0] to the dictionary.
dictionary[dictSize++] = w + entry.charAt(0);
w = entry;
}
return result;
}
if(compressData){
return compress(input)
}else{
return decompress(input)
}
}
```