diff --git a/javascript/lib/data-structures/chapter-1/1_4.js b/javascript/lib/data-structures/chapter-1/1_4.js new file mode 100644 index 00000000..710eee97 --- /dev/null +++ b/javascript/lib/data-structures/chapter-1/1_4.js @@ -0,0 +1,38 @@ +module.exports = Strings_1_4 = (function() { + return { + // Replace spaces to %20 in the given string. + // @param {String} str + // @retuns {String} - string with replaced spaces + replaceSpaces: function(str) { + var strArr = [], + strLen = str.length, + spaceCount = 0, + newLength, + i = 0; + + for (;i < strLen; i++) { + strArr[i] = str.charAt(i); + + if (strArr[i] === ' ') { + spaceCount++; + } + } + + newLength = strLen + 2*spaceCount; + + for (i = strLen - 1; i >= 0; i--) { + if (strArr[i] === ' ') { + strArr[newLength - 1] = '0'; + strArr[newLength - 2] = '2'; + strArr[newLength - 3] = '%'; + newLength = newLength - 3; + } else { + strArr[newLength - 1] = str[i]; + newLength = newLength - 1; + } + } + + return strArr.join(''); + } + }; +}()); diff --git a/javascript/lib/data-structures/chapter-1/1_5.js b/javascript/lib/data-structures/chapter-1/1_5.js new file mode 100644 index 00000000..c9ceeea9 --- /dev/null +++ b/javascript/lib/data-structures/chapter-1/1_5.js @@ -0,0 +1,69 @@ +module.exports = Strings_1_5 = (function() { + return { + // Compress string. + // Solution with arrays without string concatenation. Should be theoretically faster. + // @param {String} str - input string + // @retuns {String} - compressed string + compressString: function compressString(str) { + var compressedStringLength = countCompressedStringLength(str), + compressedCharArray, + compressedCharArrayIndex = 0, + previousSymbol = str[0], + previousSymbolCount = 1, + currentSymbol, + i; + + if (compressedStringLength >= str.length) { + return str; + } + + compressedCharArray = new Array(compressedStringLength); + + for (i = 1; i < str.length; i++) { + currentSymbol = str.charAt(i); + + if (currentSymbol === previousSymbol) { + previousSymbolCount++; + } else { + compressedCharArray[compressedCharArrayIndex++] = previousSymbol; + compressedCharArray[compressedCharArrayIndex++] = previousSymbolCount; + previousSymbol = currentSymbol; + previousSymbolCount = 1; + } + } + + compressedCharArray[compressedCharArrayIndex++] = previousSymbol; + compressedCharArray[compressedCharArrayIndex] = previousSymbolCount; + + return compressedCharArray.join(''); + + function countCompressedStringLength(str) { + if (typeof str === 'undefined' || str === null || str === '') { + return 0; + } + + var previousSymbol = str[0], + previousSymbolCount = 1, + currentSymbol, + compressedStringLength = 0, + i; + + for (i = 1; i < str.length; i++) { + currentSymbol = str.charAt(i); + + if (currentSymbol === previousSymbol) { + previousSymbolCount++; + } else { + compressedStringLength += (1 + previousSymbolCount.toString().length); + previousSymbol = currentSymbol; + previousSymbolCount = 1; + } + } + + compressedStringLength += (1 + previousSymbolCount.toString().length); + + return compressedStringLength; + } + } + }; +}()); diff --git a/javascript/lib/data-structures/chapter-1/1_6.js b/javascript/lib/data-structures/chapter-1/1_6.js new file mode 100644 index 00000000..ea31235a --- /dev/null +++ b/javascript/lib/data-structures/chapter-1/1_6.js @@ -0,0 +1,40 @@ +module.exports = Strings_1_6 = (function() { + return { + /** + * Rotate grid by 90 degrees. Grid is assumed to be NxN size. + * @param {Number[][]} grid - two-dimensional array of size NxN + */ + rotate: function rotate(grid) { + var N = grid.length, + layer, + i, + offset, + first, + last, + top; + + for (layer = 0; layer < Math.floor(N / 2); ++layer) { + first = layer; + last = N - 1 - layer; + + for(i = first; i < last; ++i) { + offset = i - first; + + top = grid[first][i]; // save top + + // left -> top + grid[first][i] = grid[last-offset][first]; + + // bottom -> left + grid[last-offset][first] = grid[last][last - offset]; + + // right -> bottom + grid[last][last - offset] = grid[i][last]; + + // top -> right + grid[i][last] = top; // right <- saved top + } + } + } + }; +}()); diff --git a/javascript/test/data-structures/chapter-1/1_4_Spec.js b/javascript/test/data-structures/chapter-1/1_4_Spec.js new file mode 100644 index 00000000..dae7f434 --- /dev/null +++ b/javascript/test/data-structures/chapter-1/1_4_Spec.js @@ -0,0 +1,8 @@ +require('../../test_helper'); +describe(Strings_1_4, function () { + describe('replaceSpaces', function () { + it('knows how to replace spaces', function () { + expect(Strings_1_4.replaceSpaces(' abcdef gh ')).to.equal('%20abcdef%20%20gh%20%20'); + }); + }); +}); diff --git a/javascript/test/data-structures/chapter-1/1_5_Spec.js b/javascript/test/data-structures/chapter-1/1_5_Spec.js new file mode 100644 index 00000000..7907b1d3 --- /dev/null +++ b/javascript/test/data-structures/chapter-1/1_5_Spec.js @@ -0,0 +1,11 @@ +require('../../test_helper'); +describe('Strings_1_5', function () { + describe('compressString', function () { + it('returns compressed string when it is smaller than original one', function () { + expect(Strings_1_5.compressString('aabcccccaaa')).to.equal('a2b1c5a3'); + }); + it('returns original string when it is not smaller than original one', function () { + expect(Strings_1_5.compressString('aabb')).to.equal('aabb'); + }); + }); +}); diff --git a/javascript/test/data-structures/chapter-1/1_6_Spec.js b/javascript/test/data-structures/chapter-1/1_6_Spec.js new file mode 100644 index 00000000..da50b882 --- /dev/null +++ b/javascript/test/data-structures/chapter-1/1_6_Spec.js @@ -0,0 +1,22 @@ +require('../../test_helper'); +describe('Strings_1_6', function () { + describe('rotate', function () { + it('rotates two-dimensional array by 90 degrees', function () { + var grid = [ + [1,2,3,4], + [5,6,7,8], + [9,10,11,12], + [13,14,15,16] + ]; + + Strings_1_6.rotate(grid); + + expect(grid).to.deep.equal([ + [13,9,5,1], + [14,10,6,2], + [15,11,7,3], + [16,12,8,4] + ]); + }); + }); +});