Skip to content
61 changes: 61 additions & 0 deletions src/_Classics_/caeser_cipher/index.js
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;
}
36 changes: 36 additions & 0 deletions src/_Classics_/fibonacci/index.js
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];
}
41 changes: 41 additions & 0 deletions src/_Problems_/reverse-number/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to solve problem for input > 2^31 -1 .
It is also possible.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it can be done, I tried that before adding the return 0; block. I simply posted the solution for one of the coding challenge platforms.

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
};
48 changes: 34 additions & 14 deletions src/_Problems_/reverse-number/reverse-number.test.js
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);
});
});
});