mirror of
https://github.com/TheAlgorithms/JavaScript.git
synced 2025-07-04 15:39:42 +08:00
@ -30,7 +30,7 @@ const memoize = (func, cache = new Map()) => {
|
|||||||
/**
|
/**
|
||||||
* Arguments converted to JSON string for use as a key of Map - it's easy to detect collections like -> Object and Array
|
* Arguments converted to JSON string for use as a key of Map - it's easy to detect collections like -> Object and Array
|
||||||
* If the args input is -> [new Set([1, 2, 3, 4]), {name: 'myName', age: 23}]
|
* If the args input is -> [new Set([1, 2, 3, 4]), {name: 'myName', age: 23}]
|
||||||
* Then the agrsKey generate to -> '[[1,2,3,4],{"name":"myName","age":23}]' which is JSON mean string
|
* Then the argsKey generate to -> '[[1,2,3,4],{"name":"myName","age":23}]' which is JSON mean string
|
||||||
* Now it's ready to be a perfect key for Map
|
* Now it's ready to be a perfect key for Map
|
||||||
*/
|
*/
|
||||||
const argsKey = JSON.stringify(args, jsonReplacer)
|
const argsKey = JSON.stringify(args, jsonReplacer)
|
||||||
|
@ -19,7 +19,7 @@ describe('Test Affine Cipher', () => {
|
|||||||
expect(() => encrypt('null', 4, 1)).toThrow()
|
expect(() => encrypt('null', 4, 1)).toThrow()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Test - 3 Pass string value to encrypt and ecrypt function', () => {
|
it('Test - 3 Pass string value to encrypt and decrypt function', () => {
|
||||||
expect(decrypt(encrypt('HELLO WORLD', 5, 8), 5, 8)).toBe('HELLO WORLD')
|
expect(decrypt(encrypt('HELLO WORLD', 5, 8), 5, 8)).toBe('HELLO WORLD')
|
||||||
expect(decrypt(encrypt('ABC DEF', 3, 5), 3, 5)).toBe('ABC DEF')
|
expect(decrypt(encrypt('ABC DEF', 3, 5), 3, 5)).toBe('ABC DEF')
|
||||||
expect(decrypt(encrypt('Brown fox jump over the fence', 7, 3), 7, 3)).toBe(
|
expect(decrypt(encrypt('Brown fox jump over the fence', 7, 3), 7, 3)).toBe(
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { encrypt, decrypt } from '../KeywordShiftedAlphabet'
|
import { encrypt, decrypt } from '../KeywordShiftedAlphabet'
|
||||||
|
|
||||||
test('Hello world! === dcrypt(encrypt(Hello world!))', () => {
|
test('Hello world! === decrypt(encrypt(Hello world!))', () => {
|
||||||
const word = 'Hello world!'
|
const word = 'Hello world!'
|
||||||
const result = decrypt('keyword', encrypt('keyword', word))
|
const result = decrypt('keyword', encrypt('keyword', word))
|
||||||
expect(result).toMatch(word)
|
expect(result).toMatch(word)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('The Algorithms === dcrypt(encrypt(The Algorithms))', () => {
|
test('The Algorithms === decrypt(encrypt(The Algorithms))', () => {
|
||||||
const word = 'The Algorithms'
|
const word = 'The Algorithms'
|
||||||
const result = decrypt('keyword', encrypt('keyword', word))
|
const result = decrypt('keyword', encrypt('keyword', word))
|
||||||
expect(result).toMatch(word)
|
expect(result).toMatch(word)
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { encrypt, decrypt } from '../VigenereCipher'
|
import { encrypt, decrypt } from '../VigenereCipher'
|
||||||
|
|
||||||
test('Hello world! === dcrypt(encrypt(Hello world!))', () => {
|
test('Hello world! === decrypt(encrypt(Hello world!))', () => {
|
||||||
const word = 'Hello world!'
|
const word = 'Hello world!'
|
||||||
const result = decrypt(encrypt(word, 'code'), 'code')
|
const result = decrypt(encrypt(word, 'code'), 'code')
|
||||||
expect(result).toMatch(word)
|
expect(result).toMatch(word)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('The Algorithms === dcrypt(encrypt(The Algorithms))', () => {
|
test('The Algorithms === decrypt(encrypt(The Algorithms))', () => {
|
||||||
const word = 'The Algorithms'
|
const word = 'The Algorithms'
|
||||||
const result = decrypt(encrypt(word, 'code'), 'code')
|
const result = decrypt(encrypt(word, 'code'), 'code')
|
||||||
expect(result).toMatch(word)
|
expect(result).toMatch(word)
|
||||||
|
@ -29,7 +29,7 @@ const hexLookup = (bin) => {
|
|||||||
}
|
}
|
||||||
const binaryToHex = (binaryString) => {
|
const binaryToHex = (binaryString) => {
|
||||||
/*
|
/*
|
||||||
Function for convertung Binary to Hex
|
Function for converting Binary to Hex
|
||||||
|
|
||||||
1. The conversion will start from Least Significant Digit (LSB) to the Most Significant Bit (MSB).
|
1. The conversion will start from Least Significant Digit (LSB) to the Most Significant Bit (MSB).
|
||||||
2. We divide the bits into sections of 4-bits starting from LSB to MSB.
|
2. We divide the bits into sections of 4-bits starting from LSB to MSB.
|
||||||
|
@ -21,9 +21,9 @@ const RailwayTimeConversion = (timeString) => {
|
|||||||
return new TypeError('Argument is not a string.')
|
return new TypeError('Argument is not a string.')
|
||||||
}
|
}
|
||||||
// split the string by ':' character.
|
// split the string by ':' character.
|
||||||
const [hour, minute, scondWithShift] = timeString.split(':')
|
const [hour, minute, secondWithShift] = timeString.split(':')
|
||||||
// split second and shift value.
|
// split second and shift value.
|
||||||
const [second, shift] = [scondWithShift.substr(0, 2), scondWithShift.substr(2)]
|
const [second, shift] = [secondWithShift.substr(0, 2), secondWithShift.substr(2)]
|
||||||
// convert shifted time to not-shift time(Railway time) by using the above explanation.
|
// convert shifted time to not-shift time(Railway time) by using the above explanation.
|
||||||
if (shift === 'PM') {
|
if (shift === 'PM') {
|
||||||
if (parseInt(hour) === 12) { return `${hour}:${minute}:${second}` } else { return `${parseInt(hour) + 12}:${minute}:${second}` }
|
if (parseInt(hour) === 12) { return `${hour}:${minute}:${second}` } else { return `${parseInt(hour) + 12}:${minute}:${second}` }
|
||||||
|
@ -80,19 +80,19 @@ describe('Testing Conversion of Rankine to Kelvin', () => {
|
|||||||
expect(test1).toBe(6)
|
expect(test1).toBe(6)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('Testing Conversion of Reamur to Celsius', () => {
|
describe('Testing Conversion of Reaumur to Celsius', () => {
|
||||||
it('with Reamur value', () => {
|
it('with Reaumur value', () => {
|
||||||
const test1 = tc.reaumurToCelsius(100)
|
const test1 = tc.reaumurToCelsius(100)
|
||||||
expect(test1).toBe(125)
|
expect(test1).toBe(125)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('Testing Conversion of Reamur to Fahrenheit', () => {
|
describe('Testing Conversion of Reaumur to Fahrenheit', () => {
|
||||||
it('with Reamur value', () => {
|
it('with Reaumur value', () => {
|
||||||
const test1 = tc.reaumurToFahrenheit(100)
|
const test1 = tc.reaumurToFahrenheit(100)
|
||||||
expect(test1).toBe(257)
|
expect(test1).toBe(257)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('Testing Conversion of Reamur to Kelvin', () => {
|
describe('Testing Conversion of Reaumur to Kelvin', () => {
|
||||||
it('with Reamur value', () => {
|
it('with Reamur value', () => {
|
||||||
const test1 = tc.reaumurToKelvin(100)
|
const test1 = tc.reaumurToKelvin(100)
|
||||||
expect(test1).toBe(398)
|
expect(test1).toBe(398)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Notes:
|
* Notes:
|
||||||
* - works by using divide and conquer
|
* - works by using divide and conquer
|
||||||
* - the function gets the array A with n Real numbersand returns the local max point index (if more than one exists return the first one)
|
* - the function gets the array A with n Real numbers and returns the local max point index (if more than one exists return the first one)
|
||||||
*
|
*
|
||||||
* @complexity: O(log(n)) (on average )
|
* @complexity: O(log(n)) (on average )
|
||||||
* @complexity: O(log(n)) (worst case)
|
* @complexity: O(log(n)) (worst case)
|
||||||
|
@ -83,8 +83,8 @@ Trie.prototype.remove = function (word, count) {
|
|||||||
if (child.count >= count) child.count -= count
|
if (child.count >= count) child.count -= count
|
||||||
else child.count = 0
|
else child.count = 0
|
||||||
|
|
||||||
// If some occurrences are left we dont delete it or else
|
// If some occurrences are left we don't delete it or else
|
||||||
// if the object forms some other objects prefix we dont delete it
|
// if the object forms some other objects prefix we don't delete it
|
||||||
// For checking an empty object
|
// For checking an empty object
|
||||||
// https://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object
|
// https://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object
|
||||||
if (child.count <= 0 && (Object.keys(child.children).length && child.children.constructor === Object)) {
|
if (child.count <= 0 && (Object.keys(child.children).length && child.children.constructor === Object)) {
|
||||||
@ -110,7 +110,7 @@ Trie.prototype.contains = function (word) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
Trie.prototype.findOccurences = function (word) {
|
Trie.prototype.findOccurrences = function (word) {
|
||||||
// find the node with given prefix
|
// find the node with given prefix
|
||||||
const node = this.findPrefix(word)
|
const node = this.findPrefix(word)
|
||||||
// No such word exists
|
// No such word exists
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* Kadane's algorithm is one of the most efficient ways to
|
/* Kadane's algorithm is one of the most efficient ways to
|
||||||
* calculate the maximum contiguous subarray sum for a given array.
|
* calculate the maximum contiguous subarray sum for a given array.
|
||||||
* Below is the implementation of kadanes's algorithm along with
|
* Below is the implementation of Kadane's algorithm along with
|
||||||
* some sample test cases.
|
* some sample test cases.
|
||||||
* There might be a special case in this problem if al the elements
|
* There might be a special case in this problem if al the elements
|
||||||
* of the given array are negative. In such a case, the maximum negative
|
* of the given array are negative. In such a case, the maximum negative
|
||||||
@ -10,14 +10,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export function kadaneAlgo (array) {
|
export function kadaneAlgo (array) {
|
||||||
let cummulativeSum = 0
|
let cumulativeSum = 0
|
||||||
let maxSum = Number.NEGATIVE_INFINITY // maxSum has the least possible value
|
let maxSum = Number.NEGATIVE_INFINITY // maxSum has the least possible value
|
||||||
for (let i = 0; i < array.length; i++) {
|
for (let i = 0; i < array.length; i++) {
|
||||||
cummulativeSum = cummulativeSum + array[i]
|
cumulativeSum = cumulativeSum + array[i]
|
||||||
if (maxSum < cummulativeSum) {
|
if (maxSum < cumulativeSum) {
|
||||||
maxSum = cummulativeSum
|
maxSum = cumulativeSum
|
||||||
} else if (cummulativeSum < 0) {
|
} else if (cumulativeSum < 0) {
|
||||||
cummulativeSum = 0
|
cumulativeSum = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return maxSum
|
return maxSum
|
||||||
|
@ -63,7 +63,7 @@ const uniquePaths2 = (obstacles) => {
|
|||||||
grid[0][j] = 1
|
grid[0][j] = 1
|
||||||
}
|
}
|
||||||
// Fill the rest of grid by dynamic programming
|
// Fill the rest of grid by dynamic programming
|
||||||
// using following reccurent formula:
|
// using following recurrent formula:
|
||||||
// K[i][j] = K[i - 1][j] + K[i][j - 1]
|
// K[i][j] = K[i - 1][j] + K[i][j - 1]
|
||||||
for (let i = 1; i < rows; i++) {
|
for (let i = 1; i < rows; i++) {
|
||||||
for (let j = 1; j < columns; j++) {
|
for (let j = 1; j < columns; j++) {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* This class represents a circle and can calculate it's perimeter and area
|
* This class represents a circle and can calculate it's perimeter and area
|
||||||
* https://en.wikipedia.org/wiki/Circle
|
* https://en.wikipedia.org/wiki/Circle
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {number} radius - The radius of the circule.
|
* @param {number} radius - The radius of the circle.
|
||||||
*/
|
*/
|
||||||
export default class Circle {
|
export default class Circle {
|
||||||
constructor (radius) {
|
constructor (radius) {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Binary Lifting implementation in Javascript
|
* Binary Lifting implementation in Javascript
|
||||||
* Binary Lifting is a technique that is used to find the kth ancestor of a node in a rooted tree with N nodes
|
* Binary Lifting is a technique that is used to find the kth ancestor of a node in a rooted tree with N nodes
|
||||||
* The technique requires preprocessing the tree in O(N log N) using dynamic programming
|
* The technique requires preprocessing the tree in O(N log N) using dynamic programming
|
||||||
* The techniqe can answer Q queries about kth ancestor of any node in O(Q log N)
|
* The technique can answer Q queries about kth ancestor of any node in O(Q log N)
|
||||||
* It is faster than the naive algorithm that answers Q queries with complexity O(Q K)
|
* It is faster than the naive algorithm that answers Q queries with complexity O(Q K)
|
||||||
* It can be used to find Lowest Common Ancestor of two nodes in O(log N)
|
* It can be used to find Lowest Common Ancestor of two nodes in O(log N)
|
||||||
* Tutorial on Binary Lifting: https://codeforces.com/blog/entry/100826
|
* Tutorial on Binary Lifting: https://codeforces.com/blog/entry/100826
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Author: Adrito Mukherjee
|
* Author: Adrito Mukherjee
|
||||||
* Findind Lowest Common Ancestor By Binary Lifting implementation in JavaScript
|
* Finding Lowest Common Ancestor By Binary Lifting implementation in JavaScript
|
||||||
* The technique requires preprocessing the tree in O(N log N) using dynamic programming)
|
* The technique requires preprocessing the tree in O(N log N) using dynamic programming)
|
||||||
* It can be used to find Lowest Common Ancestor of two nodes in O(log N)
|
* It can be used to find Lowest Common Ancestor of two nodes in O(log N)
|
||||||
* Tutorial on Lowest Common Ancestor: https://www.geeksforgeeks.org/lca-in-a-tree-using-binary-lifting-technique
|
* Tutorial on Lowest Common Ancestor: https://www.geeksforgeeks.org/lca-in-a-tree-using-binary-lifting-technique
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @function findBinomialCoefficient
|
* @function findBinomialCoefficient
|
||||||
* @description -> this function returns bonimial coefficient
|
* @description -> this function returns binomial coefficient
|
||||||
* of two numbers n & k given by n!/((n-k)!k!)
|
* of two numbers n & k given by n!/((n-k)!k!)
|
||||||
* @param {number} n
|
* @param {number} n
|
||||||
* @param {number} k
|
* @param {number} k
|
||||||
|
@ -37,7 +37,7 @@ const CheckKishnamurthyNumber = (number) => {
|
|||||||
sumOfAllDigitFactorial += factorial(lastDigit)
|
sumOfAllDigitFactorial += factorial(lastDigit)
|
||||||
newNumber = Math.floor(newNumber / 10)
|
newNumber = Math.floor(newNumber / 10)
|
||||||
}
|
}
|
||||||
// if the sumOftheFactorial is equal to the given number it means the number is a Krishnamurthy number.
|
// if the sumOfAllDigitFactorial is equal to the given number it means the number is a Krishnamurthy number.
|
||||||
return sumOfAllDigitFactorial === number
|
return sumOfAllDigitFactorial === number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Problem statement and explanation: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
|
* Problem statement and explanation: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
|
||||||
*
|
*
|
||||||
* This algorithm plays an important role for modular arithmetic, and by extension for cyptography algorithms
|
* This algorithm plays an important role for modular arithmetic, and by extension for cryptography algorithms
|
||||||
*
|
*
|
||||||
* Basic explanation:
|
* Basic explanation:
|
||||||
* The Extended Euclidean algorithm is a modification of the standard Euclidean GCD algorithm.
|
* The Extended Euclidean algorithm is a modification of the standard Euclidean GCD algorithm.
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* 1 / 2^50 = 8.8 * 10^-16 (a pretty small number)
|
* 1 / 2^50 = 8.8 * 10^-16 (a pretty small number)
|
||||||
*
|
*
|
||||||
* For comparison, the probability of a cosmic ray causing an error to your
|
* For comparison, the probability of a cosmic ray causing an error to your
|
||||||
* infalible program is around 1.4 * 10^-15. An order of magnitude below!
|
* infallible program is around 1.4 * 10^-15. An order of magnitude below!
|
||||||
*
|
*
|
||||||
* But because nothing is perfect, there's a major flaw to this algorithm, and
|
* But because nothing is perfect, there's a major flaw to this algorithm, and
|
||||||
* the cause are the so called Carmichael Numbers. These are composite numbers n
|
* the cause are the so called Carmichael Numbers. These are composite numbers n
|
||||||
|
@ -9,7 +9,7 @@ describe('tests for mean absolute deviation', () => {
|
|||||||
expect(() => meanAbsoluteDeviation('fgh')).toThrow()
|
expect(() => meanAbsoluteDeviation('fgh')).toThrow()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return the mean absolute devition of an array of numbers', () => {
|
it('should return the mean absolute deviation of an array of numbers', () => {
|
||||||
const meanAbDev = meanAbsoluteDeviation([2, 34, 5, 0, -2])
|
const meanAbDev = meanAbsoluteDeviation([2, 34, 5, 0, -2])
|
||||||
expect(meanAbDev).toBe(10.479999999999999)
|
expect(meanAbDev).toBe(10.479999999999999)
|
||||||
})
|
})
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
// https://projecteuler.net/problem=3
|
// https://projecteuler.net/problem=3
|
||||||
|
|
||||||
export const largestPrime = (num = 600851475143) => {
|
export const largestPrime = (num = 600851475143) => {
|
||||||
let newnumm = num
|
let newnum = num
|
||||||
let largestFact = 0
|
let largestFact = 0
|
||||||
let counter = 2
|
let counter = 2
|
||||||
while (counter * counter <= newnumm) {
|
while (counter * counter <= newnum) {
|
||||||
if (newnumm % counter === 0) {
|
if (newnum % counter === 0) {
|
||||||
newnumm = newnumm / counter
|
newnum = newnum / counter
|
||||||
} else {
|
} else {
|
||||||
counter++
|
counter++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newnumm > largestFact) {
|
if (newnum > largestFact) {
|
||||||
largestFact = newnumm
|
largestFact = newnum
|
||||||
}
|
}
|
||||||
return largestFact
|
return largestFact
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
const largestAdjacentNumber = (grid, consecutive) => {
|
const largestAdjacentNumber = (grid, consecutive) => {
|
||||||
grid = grid.split('\n').join('')
|
grid = grid.split('\n').join('')
|
||||||
const splitedGrid = grid.split('\n')
|
const splitGrid = grid.split('\n')
|
||||||
let largestProd = 0
|
let largestProd = 0
|
||||||
|
|
||||||
for (const row in splitedGrid) {
|
for (const row in splitGrid) {
|
||||||
const currentRow = splitedGrid[row].split('').map(x => Number(x))
|
const currentRow = splitGrid[row].split('').map(x => Number(x))
|
||||||
|
|
||||||
for (let i = 0; i < currentRow.length - consecutive; i++) {
|
for (let i = 0; i < currentRow.length - consecutive; i++) {
|
||||||
const combine = currentRow.slice(i, i + consecutive)
|
const combine = currentRow.slice(i, i + consecutive)
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* collect the abundant numbers, generate and store their sums with each other, and check for numbers not in the llst of sums, adds them and returns their sum.
|
* collect the abundant numbers, generate and store their sums with each other, and check for numbers not in the list of sums, adds them and returns their sum.
|
||||||
* @param {number} [n = 28123]
|
* @param {number} [n = 28123]
|
||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
|
@ -40,7 +40,7 @@ function problem28 (dim) {
|
|||||||
* Third corner: i^2 - 2 * (i - 1)
|
* Third corner: i^2 - 2 * (i - 1)
|
||||||
* Fourth corner: i^2 - 3 * (i - 1)
|
* Fourth corner: i^2 - 3 * (i - 1)
|
||||||
*
|
*
|
||||||
* Doing the sum of each corner and simplifing, we found that the result for each dimension is:
|
* Doing the sum of each corner and simplifying, we found that the result for each dimension is:
|
||||||
* sumDim = 4 * i^2 + 6 * (1 - i)
|
* sumDim = 4 * i^2 + 6 * (1 - i)
|
||||||
*
|
*
|
||||||
* In this case I skip the 1x1 dim matrix because is trivial, that's why I start in a 3x3 matrix
|
* In this case I skip the 1x1 dim matrix because is trivial, that's why I start in a 3x3 matrix
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @function Intosort (As implemented in STD C++ Lib)
|
* @function Introsort (As implemented in STD C++ Lib)
|
||||||
* The function performs introsort which is used in
|
* The function performs introsort which is used in
|
||||||
* C++ Standard LIbrary, the implementation is inspired from]
|
* C++ Standard LIbrary, the implementation is inspired from]
|
||||||
* library routine itself.
|
* library routine itself.
|
||||||
@ -88,7 +88,7 @@ function introsort (array, compare) {
|
|||||||
const THRESHOLD = 16
|
const THRESHOLD = 16
|
||||||
/**
|
/**
|
||||||
* @constant TUNEMAXDEPTH
|
* @constant TUNEMAXDEPTH
|
||||||
* Constant usec to increase or decrease value
|
* Constant used to increase or decrease value
|
||||||
* of maxDepth
|
* of maxDepth
|
||||||
*/
|
*/
|
||||||
const TUNEMAXDEPTH = 1
|
const TUNEMAXDEPTH = 1
|
||||||
|
Reference in New Issue
Block a user