From 12f9ba2c589e38f8757b9765819c980ef7ca13f0 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sun, 8 Sep 2019 22:46:51 +0530 Subject: [PATCH 01/11] --update: initial implementation --- src/_Classics_/caeser_cipher/index.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/_Classics_/caeser_cipher/index.js diff --git a/src/_Classics_/caeser_cipher/index.js b/src/_Classics_/caeser_cipher/index.js new file mode 100644 index 00000000..9df091b1 --- /dev/null +++ b/src/_Classics_/caeser_cipher/index.js @@ -0,0 +1,24 @@ +function caeserCipher(str, num) { + const lowerCaseString = str.toLowerCase(); + const alphabets = 'abcdefghijklmnopqrstuvwxyz'.split(''); + let result = ''; + + for (let char of lowerCaseString) { + const current = char; + if (current === ' ') { + result += current; + continue; + } + + const currentIndex = alphabets.indexOf(current); + let newIndex = currentIndex + num; + + if (newIndex> alphabets.length - 1) { + newIndex -= alphabets.length; + } + result += alphabets[newIndex]; + } + return result; +} + +console.log(caeserCipher('abcz', 2)); From c376de5b983a468c72f2f0637a348a1469d02051 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sun, 8 Sep 2019 23:05:38 +0530 Subject: [PATCH 02/11] --fix: edge case of upper case alphabet --- src/_Classics_/caeser_cipher/index.js | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/_Classics_/caeser_cipher/index.js b/src/_Classics_/caeser_cipher/index.js index 9df091b1..d5f8cbf0 100644 --- a/src/_Classics_/caeser_cipher/index.js +++ b/src/_Classics_/caeser_cipher/index.js @@ -1,24 +1,35 @@ function caeserCipher(str, num) { const lowerCaseString = str.toLowerCase(); const alphabets = 'abcdefghijklmnopqrstuvwxyz'.split(''); + const totalAlphabets = alphabets.length; let result = ''; - for (let char of lowerCaseString) { - const current = char; - if (current === ' ') { - result += current; + for (let index in lowerCaseString) { + // get the current character + const currentCharacter = lowerCaseString[index]; + + // if character is space, add it to the result and continue to next + if (currentCharacter === ' ') { + result += currentCharacter; continue; } - const currentIndex = alphabets.indexOf(current); + // determine the new index + const currentIndex = alphabets.indexOf(currentCharacter); let newIndex = currentIndex + num; - if (newIndex> alphabets.length - 1) { - newIndex -= alphabets.length; + // if the index passes 25, restart from 0 + if (newIndex> totalAlphabets - 1) { + newIndex -= totalAlphabets; + } + + // check if the character in original string was upper case + if (str[index] === alphabets[currentIndex].toUpperCase()) { + result += alphabets[newIndex].toUpperCase(); } result += alphabets[newIndex]; } return result; } -console.log(caeserCipher('abcz', 2)); +console.log(caeserCipher('abCz', 2)); From c801b3e54ca2304ab37b7acf67c2a1d0e5c275ed Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sun, 8 Sep 2019 23:07:47 +0530 Subject: [PATCH 03/11] --fix: missing case for -ve new index --- src/_Classics_/caeser_cipher/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/_Classics_/caeser_cipher/index.js b/src/_Classics_/caeser_cipher/index.js index d5f8cbf0..03b7890c 100644 --- a/src/_Classics_/caeser_cipher/index.js +++ b/src/_Classics_/caeser_cipher/index.js @@ -23,6 +23,10 @@ function caeserCipher(str, num) { newIndex -= totalAlphabets; } + if (newIndex < 0) { + newIndex = totalAlphabets + newIndex; + } + // check if the character in original string was upper case if (str[index] === alphabets[currentIndex].toUpperCase()) { result += alphabets[newIndex].toUpperCase(); From 76b9ace2652d61ab431b566f35ed84fd96ed32d1 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sun, 8 Sep 2019 23:14:07 +0530 Subject: [PATCH 04/11] --update: final implementation --- src/_Classics_/caeser_cipher/index.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/_Classics_/caeser_cipher/index.js b/src/_Classics_/caeser_cipher/index.js index 03b7890c..c90e2379 100644 --- a/src/_Classics_/caeser_cipher/index.js +++ b/src/_Classics_/caeser_cipher/index.js @@ -1,9 +1,18 @@ +/** + * Most simplest encryption scheme. Read more: [http://practicalcryptography.com/ciphers/caesar-cipher/] + * @param {String} str + * @param {Number} num + */ + function caeserCipher(str, num) { const lowerCaseString = str.toLowerCase(); const alphabets = 'abcdefghijklmnopqrstuvwxyz'.split(''); const totalAlphabets = alphabets.length; let result = ''; + // handle large number, like 300 or -300 + num %= totalAlphabets; + for (let index in lowerCaseString) { // get the current character const currentCharacter = lowerCaseString[index]; @@ -28,12 +37,11 @@ function caeserCipher(str, num) { } // check if the character in original string was upper case - if (str[index] === alphabets[currentIndex].toUpperCase()) { + if (str[index] === str[index].toUpperCase()) { result += alphabets[newIndex].toUpperCase(); + } else { + result += alphabets[newIndex]; } - result += alphabets[newIndex]; } return result; } - -console.log(caeserCipher('abCz', 2)); From 408dc136598b2bf1a41d9630964ba1d9a8119a18 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sun, 8 Sep 2019 23:17:24 +0530 Subject: [PATCH 05/11] --fix: spell fix --- src/_Classics_/caeser_cipher/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_Classics_/caeser_cipher/index.js b/src/_Classics_/caeser_cipher/index.js index c90e2379..de613a2b 100644 --- a/src/_Classics_/caeser_cipher/index.js +++ b/src/_Classics_/caeser_cipher/index.js @@ -4,7 +4,7 @@ * @param {Number} num */ -function caeserCipher(str, num) { +function caesarCipher(str, num) { const lowerCaseString = str.toLowerCase(); const alphabets = 'abcdefghijklmnopqrstuvwxyz'.split(''); const totalAlphabets = alphabets.length; From 479e92582cf87503b84a5ca096fb8ff817357ed4 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Mon, 9 Sep 2019 13:00:15 +0530 Subject: [PATCH 06/11] --update: get pair of index for two numbers sum to N --- src/_Problems_/find-2-nums-adding-to-n/index.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/_Problems_/find-2-nums-adding-to-n/index.js b/src/_Problems_/find-2-nums-adding-to-n/index.js index b01ca1cc..d7bf8a42 100644 --- a/src/_Problems_/find-2-nums-adding-to-n/index.js +++ b/src/_Problems_/find-2-nums-adding-to-n/index.js @@ -16,6 +16,20 @@ function findTwoNumsAddingToN(arr, number) { return pair.length ? pair : false; } +function findIndicesOfTwoNumsAddingToN(nums, target) { + const store = new Set(); + const pair = []; + for (let index in nums) { + if (store.has(target - nums[index])) { + pair.push(nums.indexOf(target - nums[index])); + pair.push(index); + break; + } + store.add(nums[index]); + } + return pair.length ? pair : false; +} + // the Brute force approach function findTwoNumsAddingToN2(arr, number) { const pair = []; From 20280c805d408c352e0587d585666b80a4491fd9 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Mon, 9 Sep 2019 15:04:24 +0530 Subject: [PATCH 07/11] --update: replaced indexof with Map(), throw error on missing arguments --- src/_Classics_/caeser_cipher/index.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/_Classics_/caeser_cipher/index.js b/src/_Classics_/caeser_cipher/index.js index de613a2b..8851bf03 100644 --- a/src/_Classics_/caeser_cipher/index.js +++ b/src/_Classics_/caeser_cipher/index.js @@ -5,6 +5,8 @@ */ function caesarCipher(str, num) { + if (!num) throw new Error('Missing argument: num'); + const lowerCaseString = str.toLowerCase(); const alphabets = 'abcdefghijklmnopqrstuvwxyz'.split(''); const totalAlphabets = alphabets.length; @@ -13,6 +15,12 @@ function caesarCipher(str, num) { // handle large number, like 300 or -300 num %= totalAlphabets; + const alphabetsMap = new Map(); + + for (const index in alphabets) { + alphabetsMap[alphabets[index]] = index; + } + for (let index in lowerCaseString) { // get the current character const currentCharacter = lowerCaseString[index]; @@ -24,7 +32,13 @@ function caesarCipher(str, num) { } // determine the new index - const currentIndex = alphabets.indexOf(currentCharacter); + /** + * const currentIndex = alphabets.indexOf(currentCharacter); + * + * With indexOf complexity will be O(n*26) + * With Map complexity will be O(n). + */ + const currentIndex = Number(alphabetsMap[currentCharacter]); let newIndex = currentIndex + num; // if the index passes 25, restart from 0 From c2eec668a9641cc220515259f9e64bbac90c7033 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Mon, 9 Sep 2019 17:12:52 +0530 Subject: [PATCH 08/11] --update: added fibonacci --- src/_Classics_/fibonacci/index.js | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/_Classics_/fibonacci/index.js diff --git a/src/_Classics_/fibonacci/index.js b/src/_Classics_/fibonacci/index.js new file mode 100644 index 00000000..db21a2ec --- /dev/null +++ b/src/_Classics_/fibonacci/index.js @@ -0,0 +1,10 @@ +// the algorithm has time complexity of O(n^2), very bad! +function fibonacci(position) { + // if position is 1 or 2, the number in fibonacci sequence will be 1 + if (position < 3) { + return 1; + } + // else the element in fibonacci sequence will be the sum of + // element at position(p) (p -1) and (p - 2) + return fibonacci(position - 2) + fibonacci(position - 1); +} From dbd3dbdd42219cbeea1fe6f1e03399d3b72284d1 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Mon, 9 Sep 2019 17:30:53 +0530 Subject: [PATCH 09/11] --update: added optimized fibonacci using cache --- src/_Classics_/fibonacci/index.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/_Classics_/fibonacci/index.js b/src/_Classics_/fibonacci/index.js index db21a2ec..936f01ae 100644 --- a/src/_Classics_/fibonacci/index.js +++ b/src/_Classics_/fibonacci/index.js @@ -8,3 +8,29 @@ function fibonacci(position) { // element at position(p) (p -1) and (p - 2) return fibonacci(position - 2) + fibonacci(position - 1); } + +/** + * Memoization. In computing, memoization or memoisation is an + * optimization technique used primarily to speed up computer + * programs by storing the results of expensive function + * calls and returning the cached result when the + * same inputs occur again + */ + +// Linear time, test with index as 510 for both the functions +function fibonacciMemoized(index, cache) { + cache = cache || []; + + if (cache[index]) { + return cache[index]; + } else { + if (index < 3) { + return 1; + } else { + cache[index] = + fibonacciMemoized(index - 1, cache) + + fibonacciMemoized(index - 2, cache); + } + } + return cache[index]; +} From 8a9d8b8042edb31009257d7a7f7581021b0f590c Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: 2019年9月10日 13:35:15 +0530 Subject: [PATCH 10/11] --update: 32-bit signed int reversal --- src/_Problems_/reverse-number/index.js | 41 ++++++++++++++++ .../reverse-number/reverse-number.test.js | 48 +++++++++++++------ 2 files changed, 75 insertions(+), 14 deletions(-) diff --git a/src/_Problems_/reverse-number/index.js b/src/_Problems_/reverse-number/index.js index a2d6c822..bec47765 100644 --- a/src/_Problems_/reverse-number/index.js +++ b/src/_Problems_/reverse-number/index.js @@ -15,6 +15,47 @@ function reverseNumber(num) { return reverse * Math.sign(num); } +/** + * + * Given a 32-bit signed integer, reverse digits of an integer. + + Example 1: + + Input: 123 + Output: 321 + Example 2: + + Input: -123 + Output: -321 + Example 3: + + Input: 1534236469 + Output: 0 // overflows + Note: + Assume we are dealing with an environment which could only + store integers within the 32-bit signed integer range: [−2^31, 2^31 − 1]. + For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows. + */ + +function reverse32BitInt(x) { + let isNegetive = 0; + if (x < 0) { + x *= -1; + isNegetive = 1; + } + let reverse = 0; + while (x>= 1) { + const r = Math.floor(x % 10); + reverse = reverse * 10 + r; + x = Math.floor(x / 10); + } + if (reverse> 0x7fffffff) { + return 0; + } + return isNegetive ? reverse * -1 : reverse; +} + module.exports = { reverseNumber, + reverse32BitInt }; diff --git a/src/_Problems_/reverse-number/reverse-number.test.js b/src/_Problems_/reverse-number/reverse-number.test.js index 947a4780..b4dff2f5 100644 --- a/src/_Problems_/reverse-number/reverse-number.test.js +++ b/src/_Problems_/reverse-number/reverse-number.test.js @@ -1,23 +1,43 @@ -const { reverseNumber } = require('.'); +const { reverseNumber, reverse32BitInt } = require('.'); describe('Reverse Numbers', () => { - it('Should return a number', () => { - expect(typeof reverseNumber(1) === 'number'); - }); + describe('Normal Reverse', () => { + it('Should return a number', () => { + expect(typeof reverseNumber(1) === 'number'); + }); - it('Should reverse 45 to 54', () => { - expect(reverseNumber(45)).toEqual(54); - }); + it('Should reverse 45 to 54', () => { + expect(reverseNumber(45)).toEqual(54); + }); - it('Should reverse -2 to -2', () => { - expect(reverseNumber(-2)).toEqual(-2); - }); + it('Should reverse -2 to -2', () => { + expect(reverseNumber(-2)).toEqual(-2); + }); + + it('Should reverse -1234567 to -7654321', () => { + expect(reverseNumber(-1234567)).toEqual(-7654321); + }); - it('Should reverse -1234567 to -7654321', () => { - expect(reverseNumber(-1234567)).toEqual(-7654321); + it('Should throw error for invalid argument', () => { + expect(() => reverseNumber('hello')).toThrow('Invalid Argument'); + }); }); - it('Should throw error for invalid argument', () => { - expect(() => reverseNumber('hello')).toThrow('Invalid Argument'); + describe('32-bit signed integer reversal', () => { + it('Should return a number', () => { + expect(typeof reverse32BitInt(1) === 'number'); + }); + + it('Should reverse 123 to 321', () => { + expect(reverse32BitInt(123)).toEqual(321); + }); + + it('Should reverse -871 to -178', () => { + expect(reverse32BitInt(-871)).toEqual(-178); + }); + + it('Should return 0 for 1534236469 because of overflow when reversed', () => { + expect(reverse32BitInt(1534236469)).toEqual(0); + }); }); }); From f04d86c017d66c434c58cd3baee1d88e2090a111 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: 2019年9月23日 01:08:16 +0530 Subject: [PATCH 11/11] --fix: removed outdated files --- .../find-2-nums-adding-to-n/index.js | 46 ------------------- src/_Problems_/find-2nd-max/index.js | 22 --------- 2 files changed, 68 deletions(-) delete mode 100644 src/_Problems_/find-2-nums-adding-to-n/index.js delete mode 100644 src/_Problems_/find-2nd-max/index.js diff --git a/src/_Problems_/find-2-nums-adding-to-n/index.js b/src/_Problems_/find-2-nums-adding-to-n/index.js deleted file mode 100644 index d7bf8a42..00000000 --- a/src/_Problems_/find-2-nums-adding-to-n/index.js +++ /dev/null @@ -1,46 +0,0 @@ -// the best case [O(n)] using SET data structure -function findTwoNumsAddingToN(arr, number) { - const pair = []; - const store = new Set(); - - for (let i = 0; i < arr.length; i += 1) { - // check if the set contains one of the element that sum upto the given number - if (store.has(number - arr[i])) { - pair.push(number - arr[i]); - pair.push(arr[i]); - break; - } - // push the element in the set - store.add(arr[i]); - } - return pair.length ? pair : false; -} - -function findIndicesOfTwoNumsAddingToN(nums, target) { - const store = new Set(); - const pair = []; - for (let index in nums) { - if (store.has(target - nums[index])) { - pair.push(nums.indexOf(target - nums[index])); - pair.push(index); - break; - } - store.add(nums[index]); - } - return pair.length ? pair : false; -} - -// the Brute force approach -function findTwoNumsAddingToN2(arr, number) { - const pair = []; - for (let i = 0; i < arr.length; i += 1) { - for (let j = i + 1; j < arr.length; j += 1) { - if (arr[i] + arr[j] === number) { - pair.push(arr[i], arr[j]); - break; - } - } - } - - return pair.length ? pair : null; -} diff --git a/src/_Problems_/find-2nd-max/index.js b/src/_Problems_/find-2nd-max/index.js deleted file mode 100644 index 5d57c6ab..00000000 --- a/src/_Problems_/find-2nd-max/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * You may find it easy but it's tricky for few - * Input - [9, 2, 3, 6] - * Output - 6 - */ - -function findSecondMax(arr) { - let max = arr[0]; - let max2 = 0; - - for (let el of arr) { - if (el> max) { - max2 = max; - max = el; - } - - if (el < max && el> max2) { - max2 = el; - } - } - return max2; -}

AltStyle によって変換されたページ (->オリジナル) /