-
Notifications
You must be signed in to change notification settings - Fork 269
Classics #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Classics #10
Changes from all commits
12f9ba2
c376de5
c801b3e
76b9ace
408dc13
479e925
20280c8
c2eec66
dbd3dbd
8a9d8b8
f04d86c
602df1f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/** | ||
* Most simplest encryption scheme. Read more: [http://practicalcryptography.com/ciphers/caesar-cipher/] | ||
* @param {String} str | ||
* @param {Number} num | ||
*/ | ||
|
||
function caesarCipher(str, num) { | ||
if (!num) throw new Error('Missing argument: num'); | ||
|
||
const lowerCaseString = str.toLowerCase(); | ||
const alphabets = 'abcdefghijklmnopqrstuvwxyz'.split(''); | ||
const totalAlphabets = alphabets.length; | ||
let result = ''; | ||
|
||
// 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]; | ||
|
||
// if character is space, add it to the result and continue to next | ||
if (currentCharacter === ' ') { | ||
result += currentCharacter; | ||
continue; | ||
} | ||
|
||
// determine the new index | ||
/** | ||
* 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 | ||
if (newIndex > totalAlphabets - 1) { | ||
newIndex -= totalAlphabets; | ||
} | ||
|
||
if (newIndex < 0) { | ||
newIndex = totalAlphabets + newIndex; | ||
} | ||
|
||
// check if the character in original string was upper case | ||
if (str[index] === str[index].toUpperCase()) { | ||
result += alphabets[newIndex].toUpperCase(); | ||
} else { | ||
result += alphabets[newIndex]; | ||
} | ||
} | ||
return result; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// 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); | ||
} | ||
|
||
/** | ||
* 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]; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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]. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try to solve problem for input > 2^31 -1 . There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it can be done, I tried that before adding the |
||
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 | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
}); | ||
}); | ||
}); |