30-days-of-javascript 2.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/30-days-of-javaScript.txt +1 -0
- package/AffineCipher.js +105 -0
- package/AverageMedian.js +22 -0
- package/Base64ToArrayBuffer.js +48 -0
- package/BinaryExponentiationRecursive.js +20 -0
- package/BinarySearch.js +33 -0
- package/BreadthFirstSearch.js +37 -0
- package/Circle.js +19 -0
- package/Cone.js +30 -0
- package/CreatePermutations.js +38 -0
- package/DecimalToHex.js +28 -0
- package/DecimalToRoman.js +52 -0
- package/Density.js +11 -0
- package/DutchNationalFlagSort.js +33 -0
- package/ExponentialFunction.js +25 -0
- package/FibonacciNumberRecursive.js +16 -0
- package/FisherYatesShuffle.js +18 -0
- package/FloydWarshall.js +47 -0
- package/Haversine.js +44 -0
- package/HexToRGB.js +17 -0
- package/MD5.js +205 -0
- package/Minesweeper.js +38 -0
- package/NumberOfIslands.js +81 -0
- package/PatternMatching.js +33 -0
- package/Problem012.js +64 -0
- package/QuadraticRoots.js +37 -0
- package/QuickSelect.js +65 -0
- package/README.md +1 -0
- package/RadixSort.js +43 -0
- package/RomanToDecimal.js +34 -0
- package/SquareRootLogarithmic.js +41 -0
- package/SwapSort.js +31 -0
- package/dist/index.d.mts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +41 -0
- package/dist/index.mjs +12 -0
- package/package.json +31 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
A 30DaysOfJavaScript challenge is a guide for both beginners and advanced JavaScript developers
|
package/AffineCipher.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description - The affine cipher is a type of monoalphabetic substitution cipher, where each letter in an alphabet is mapped to its numeric equivalent, encrypted using a simple mathematical function, and converted back to a letter
|
|
3
|
+
* @see - [wiki](https://en.wikipedia.org/wiki/Affine_cipher)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { CoPrimeCheck } from '../Maths/CoPrimeCheck'
|
|
7
|
+
// Default key for Affine Cipher
|
|
8
|
+
const key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Fix result for negative value in modulas equation
|
|
12
|
+
* @param {Number} n - Constant number
|
|
13
|
+
* @param {Number} m - Modulos value
|
|
14
|
+
* @return {Number} Return n mod m
|
|
15
|
+
*/
|
|
16
|
+
function mod(n, m) {
|
|
17
|
+
return ((n % m) + m) % m
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Modular multiplicative inverse
|
|
22
|
+
* @param {Number} a - A coefficient
|
|
23
|
+
* @param {Number} m - Modulos value
|
|
24
|
+
* @return {Number} Return modular multiplicative inverse of coefficient a and modulos m
|
|
25
|
+
*/
|
|
26
|
+
function inverseMod(a, m) {
|
|
27
|
+
for (let x = 1; x < m; x++) {
|
|
28
|
+
if (mod(a * x, m) === 1) return x
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Argument validation
|
|
34
|
+
* @param {String} str - String to be checked
|
|
35
|
+
* @param {Number} a - A coefficient to be checked
|
|
36
|
+
* @param {Number} b - B coefficient to be checked
|
|
37
|
+
* @return {Boolean} Result of the checking
|
|
38
|
+
*/
|
|
39
|
+
function isCorrectFormat(str, a, b) {
|
|
40
|
+
if (typeof a !== 'number' || typeof b !== 'number') {
|
|
41
|
+
throw new TypeError('Coefficient a, b should be number')
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (typeof str !== 'string') {
|
|
45
|
+
throw new TypeError('Argument str should be String')
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!CoPrimeCheck(a, 26)) {
|
|
49
|
+
throw new Error(a + ' is not coprime of 26')
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return true
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Find character index based on ASCII order
|
|
57
|
+
* @param {String} char - Character index to be found
|
|
58
|
+
* @return {Boolean} Character index
|
|
59
|
+
*/
|
|
60
|
+
function findCharIndex(char) {
|
|
61
|
+
return char.toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Encrypt a Affine Cipher
|
|
66
|
+
* @param {String} str - String to be encrypted
|
|
67
|
+
* @param {Number} a - A coefficient
|
|
68
|
+
* @param {Number} b - B coefficient
|
|
69
|
+
* @return {String} result - Encrypted string
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
function encrypt(str, a, b) {
|
|
73
|
+
let result = ''
|
|
74
|
+
if (isCorrectFormat(str, a, b)) {
|
|
75
|
+
for (let x = 0; x < str.length; x++) {
|
|
76
|
+
const charIndex = findCharIndex(str[x])
|
|
77
|
+
if (charIndex < 0) result += '-1' + ' '
|
|
78
|
+
else result += key.charAt(mod(a * charIndex + b, 26)) + ' '
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return result.trim()
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Decrypt a Affine Cipher
|
|
86
|
+
* @param {String} str - String to be decrypted
|
|
87
|
+
* @param {Number} a - A coefficient
|
|
88
|
+
* @param {Number} b - B coefficient
|
|
89
|
+
* @return {String} result - Decrypted string
|
|
90
|
+
*/
|
|
91
|
+
function decrypt(str, a, b) {
|
|
92
|
+
let result = ''
|
|
93
|
+
if (isCorrectFormat(str, a, b)) {
|
|
94
|
+
str = str.split(' ')
|
|
95
|
+
for (let x = 0; x < str.length; x++) {
|
|
96
|
+
if (str[x] === '-1') result += ' '
|
|
97
|
+
else {
|
|
98
|
+
const charIndex = findCharIndex(str[x])
|
|
99
|
+
result += key[mod(inverseMod(a, 26) * (charIndex - b), 26)]
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return result
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export { encrypt, decrypt }
|
package/AverageMedian.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Median: https://en.wikipedia.org/wiki/Median
|
|
3
|
+
*
|
|
4
|
+
* function averageMedian
|
|
5
|
+
* to find the median value of an array of numbers
|
|
6
|
+
* the numbers in an array will be sorted in ascending order by the function sortNumbers
|
|
7
|
+
* if the length of the array is even number, the median value will be the average of the two middle numbers
|
|
8
|
+
* else if the length of the array is odd number, the median value will be the middle number in the array
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const averageMedian = (sourceArrayOfNumbers) => {
|
|
12
|
+
const numbers = [...sourceArrayOfNumbers].sort(sortNumbers)
|
|
13
|
+
const numLength = numbers.length
|
|
14
|
+
|
|
15
|
+
return numLength % 2 === 0
|
|
16
|
+
? (numbers[numLength / 2 - 1] + numbers[numLength / 2]) / 2
|
|
17
|
+
: numbers[Math.floor(numLength / 2)]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const sortNumbers = (num1, num2) => num1 - num2
|
|
21
|
+
|
|
22
|
+
export { averageMedian }
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// About base64: https://en.wikipedia.org/wiki/Base64
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Converts a base64 string to an array of bytes
|
|
5
|
+
* @param {string} b64 A base64 string
|
|
6
|
+
* @returns {ArrayBuffer} An ArrayBuffer representing the bytes encoded by the base64 string
|
|
7
|
+
*/
|
|
8
|
+
function base64ToBuffer(b64) {
|
|
9
|
+
// The base64 encoding uses the following set of characters to encode any binary data as text
|
|
10
|
+
const base64Table =
|
|
11
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
|
12
|
+
// Find the index of char '=' first occurrence
|
|
13
|
+
const paddingIdx = b64.indexOf('=')
|
|
14
|
+
// Remove padding chars from base64 string, if there are any
|
|
15
|
+
const b64NoPadding = paddingIdx !== -1 ? b64.slice(0, paddingIdx) : b64
|
|
16
|
+
// Calculate the length of the result buffer
|
|
17
|
+
const bufferLength = Math.floor((b64NoPadding.length * 6) / 8)
|
|
18
|
+
// Create the result buffer
|
|
19
|
+
const result = new ArrayBuffer(bufferLength)
|
|
20
|
+
// Create an instance of Uint8Array, to write to the `result` buffer
|
|
21
|
+
const byteView = new Uint8Array(result)
|
|
22
|
+
|
|
23
|
+
// Loop through all chars in the base64 string, in increments of 4 chars, and in increments of 3 bytes
|
|
24
|
+
for (let i = 0, j = 0; i < b64NoPadding.length; i += 4, j += 3) {
|
|
25
|
+
// Get the index of the next 4 base64 chars
|
|
26
|
+
const b64Char1 = base64Table.indexOf(b64NoPadding[i])
|
|
27
|
+
const b64Char2 = base64Table.indexOf(b64NoPadding[i + 1])
|
|
28
|
+
let b64Char3 = base64Table.indexOf(b64NoPadding[i + 2])
|
|
29
|
+
let b64Char4 = base64Table.indexOf(b64NoPadding[i + 3])
|
|
30
|
+
|
|
31
|
+
// If base64 chars 3 and 4 don't exit, then set them to 0
|
|
32
|
+
if (b64Char3 === -1) b64Char3 = 0
|
|
33
|
+
if (b64Char4 === -1) b64Char4 = 0
|
|
34
|
+
|
|
35
|
+
// Calculate the next 3 bytes
|
|
36
|
+
const byte1 = (b64Char1 << 2) + ((b64Char2 & 48) >> 4)
|
|
37
|
+
const byte2 = ((b64Char2 & 15) << 4) + ((b64Char3 & 60) >> 2)
|
|
38
|
+
const byte3 = ((b64Char3 & 3) << 6) + b64Char4
|
|
39
|
+
|
|
40
|
+
byteView[j] = byte1
|
|
41
|
+
byteView[j + 1] = byte2
|
|
42
|
+
byteView[j + 2] = byte3
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return result
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { base64ToBuffer }
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Modified from:
|
|
3
|
+
https://github.com/TheAlgorithms/Python/blob/master/maths/binary_exponentiation.py
|
|
4
|
+
|
|
5
|
+
Explanation:
|
|
6
|
+
https://en.wikipedia.org/wiki/Exponentiation_by_squaring
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export const binaryExponentiation = (a, n) => {
|
|
10
|
+
// input: a: int, n: int
|
|
11
|
+
// returns: a^n: int
|
|
12
|
+
if (n === 0) {
|
|
13
|
+
return 1
|
|
14
|
+
} else if (n % 2 === 1) {
|
|
15
|
+
return binaryExponentiation(a, n - 1) * a
|
|
16
|
+
} else {
|
|
17
|
+
const b = binaryExponentiation(a, n / 2)
|
|
18
|
+
return b * b
|
|
19
|
+
}
|
|
20
|
+
}
|
package/BinarySearch.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @function BinarySearch
|
|
3
|
+
* @description Search the integer inside the sorted integers array using Binary Search Algorithm.
|
|
4
|
+
* @param {Integer[]} arr - sorted array of integers
|
|
5
|
+
* @param {Integer} low - The input integer
|
|
6
|
+
* @param {Integer} high - The input integer
|
|
7
|
+
* @param {Integer} searchValue - The input integer
|
|
8
|
+
* @return {Integer} - return index of searchValue if found else return -1.
|
|
9
|
+
* @see [BinarySearch](https://en.wikipedia.org/wiki/Binary_search_algorithm)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const binarySearch = (arr, searchValue, low = 0, high = arr.length - 1) => {
|
|
13
|
+
// base case
|
|
14
|
+
if (high < low || arr.length === 0) return -1
|
|
15
|
+
|
|
16
|
+
const mid = low + Math.floor((high - low) / 2)
|
|
17
|
+
|
|
18
|
+
// If the element is present at the middle
|
|
19
|
+
if (arr[mid] === searchValue) {
|
|
20
|
+
return mid
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// If element is smaller than mid, then
|
|
24
|
+
// it can only be present in left subarray
|
|
25
|
+
if (arr[mid] > searchValue) {
|
|
26
|
+
return binarySearch(arr, searchValue, low, mid - 1)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Else the element can only be present in right subarray
|
|
30
|
+
return binarySearch(arr, searchValue, mid + 1, high)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { binarySearch }
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import Queue from '../Data-Structures/Queue/Queue'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Breadth-first search is an algorithm for traversing a graph.
|
|
5
|
+
*
|
|
6
|
+
* It discovers all nodes reachable from the starting position by exploring all of the neighbor nodes at the present
|
|
7
|
+
* depth prior to moving on to the nodes at the next depth level.
|
|
8
|
+
*
|
|
9
|
+
* (description adapted from https://en.wikipedia.org/wiki/Breadth-first_search)
|
|
10
|
+
* @see https://www.koderdojo.com/blog/breadth-first-search-and-shortest-path-in-csharp-and-net-core
|
|
11
|
+
*/
|
|
12
|
+
export function breadthFirstSearch(graph, startingNode) {
|
|
13
|
+
// visited keeps track of all nodes visited
|
|
14
|
+
const visited = new Set()
|
|
15
|
+
|
|
16
|
+
// queue contains the nodes to be explored in the future
|
|
17
|
+
const queue = new Queue()
|
|
18
|
+
queue.enqueue(startingNode)
|
|
19
|
+
|
|
20
|
+
while (!queue.isEmpty()) {
|
|
21
|
+
// start with the queue's first node
|
|
22
|
+
const node = queue.dequeue()
|
|
23
|
+
|
|
24
|
+
if (!visited.has(node)) {
|
|
25
|
+
// mark the node as visited
|
|
26
|
+
visited.add(node)
|
|
27
|
+
const neighbors = graph[node]
|
|
28
|
+
|
|
29
|
+
// put all its neighbors into the queue
|
|
30
|
+
for (let i = 0; i < neighbors.length; i++) {
|
|
31
|
+
queue.enqueue(neighbors[i])
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return visited
|
|
37
|
+
}
|
package/Circle.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This class represents a circle and can calculate it's perimeter and area
|
|
3
|
+
* https://en.wikipedia.org/wiki/Circle
|
|
4
|
+
* @constructor
|
|
5
|
+
* @param {number} radius - The radius of the circle.
|
|
6
|
+
*/
|
|
7
|
+
export default class Circle {
|
|
8
|
+
constructor(radius) {
|
|
9
|
+
this.radius = radius
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
perimeter = () => {
|
|
13
|
+
return this.radius * 2 * Math.PI
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
area = () => {
|
|
17
|
+
return Math.pow(this.radius, 2) * Math.PI
|
|
18
|
+
}
|
|
19
|
+
}
|
package/Cone.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This class represents a circular cone and can calculate its volume and surface area
|
|
3
|
+
* https://en.wikipedia.org/wiki/Cone
|
|
4
|
+
* @constructor
|
|
5
|
+
* @param {number} baseRadius - The radius of the base of the cone.
|
|
6
|
+
* @param {number} height - The height of the cone
|
|
7
|
+
*/
|
|
8
|
+
export default class Cone {
|
|
9
|
+
constructor(baseRadius, height) {
|
|
10
|
+
this.baseRadius = baseRadius
|
|
11
|
+
this.height = height
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
baseArea = () => {
|
|
15
|
+
return Math.pow(this.baseRadius, 2) * Math.PI
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
volume = () => {
|
|
19
|
+
return (this.baseArea() * this.height * 1) / 3
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
surfaceArea = () => {
|
|
23
|
+
return (
|
|
24
|
+
this.baseArea() +
|
|
25
|
+
Math.PI *
|
|
26
|
+
this.baseRadius *
|
|
27
|
+
Math.sqrt(Math.pow(this.baseRadius, 2) + Math.pow(this.height, 2))
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/*
|
|
2
|
+
a permutation of a set is, loosely speaking, an arrangement of its members into a sequence or linear order, or if the set is already ordered, a rearrangement of its elements.
|
|
3
|
+
The word "permutation" also refers to the act or process of changing the linear order of an ordered set
|
|
4
|
+
More at : https://en.wikipedia.org/wiki/Permutation
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const createPermutations = (str) => {
|
|
8
|
+
// convert string to array
|
|
9
|
+
const arr = str.split('')
|
|
10
|
+
|
|
11
|
+
// get array length
|
|
12
|
+
const strLen = arr.length
|
|
13
|
+
// this will hold all the permutations
|
|
14
|
+
const perms = []
|
|
15
|
+
let rest
|
|
16
|
+
let picked
|
|
17
|
+
let restPerms
|
|
18
|
+
let next
|
|
19
|
+
|
|
20
|
+
// if strLen is zero, return the same string
|
|
21
|
+
if (strLen === 0) {
|
|
22
|
+
return [str]
|
|
23
|
+
}
|
|
24
|
+
// loop to the length to get all permutations
|
|
25
|
+
for (let i = 0; i < strLen; i++) {
|
|
26
|
+
rest = Object.create(arr)
|
|
27
|
+
picked = rest.splice(i, 1)
|
|
28
|
+
|
|
29
|
+
restPerms = createPermutations(rest.join(''))
|
|
30
|
+
|
|
31
|
+
for (let j = 0, jLen = restPerms.length; j < jLen; j++) {
|
|
32
|
+
next = picked.concat(restPerms[j])
|
|
33
|
+
perms.push(next.join(''))
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return perms
|
|
37
|
+
}
|
|
38
|
+
export { createPermutations }
|
package/DecimalToHex.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
function intToHex(num) {
|
|
2
|
+
switch (num) {
|
|
3
|
+
case 10:
|
|
4
|
+
return 'A'
|
|
5
|
+
case 11:
|
|
6
|
+
return 'B'
|
|
7
|
+
case 12:
|
|
8
|
+
return 'C'
|
|
9
|
+
case 13:
|
|
10
|
+
return 'D'
|
|
11
|
+
case 14:
|
|
12
|
+
return 'E'
|
|
13
|
+
case 15:
|
|
14
|
+
return 'F'
|
|
15
|
+
}
|
|
16
|
+
return num
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function decimalToHex(num) {
|
|
20
|
+
const hexOut = []
|
|
21
|
+
while (num > 15) {
|
|
22
|
+
hexOut.unshift(intToHex(num % 16))
|
|
23
|
+
num = Math.floor(num / 16)
|
|
24
|
+
}
|
|
25
|
+
return intToHex(num) + hexOut.join('')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { decimalToHex }
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Decimal To Roman
|
|
3
|
+
|
|
4
|
+
This algorithm take decimal number and convert to roman numeral according to standard form (https://en.wikipedia.org/wiki/Roman_numerals#Description)
|
|
5
|
+
|
|
6
|
+
Algorithm & Explanation : https://www.rapidtables.com/convert/number/how-number-to-roman-numerals.html
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const values = {
|
|
10
|
+
M: 1000,
|
|
11
|
+
CM: 900,
|
|
12
|
+
D: 500,
|
|
13
|
+
CD: 400,
|
|
14
|
+
C: 100,
|
|
15
|
+
XC: 90,
|
|
16
|
+
L: 50,
|
|
17
|
+
XL: 40,
|
|
18
|
+
X: 10,
|
|
19
|
+
IX: 9,
|
|
20
|
+
V: 5,
|
|
21
|
+
IV: 4,
|
|
22
|
+
I: 1
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const orders = [
|
|
26
|
+
'M',
|
|
27
|
+
'CM',
|
|
28
|
+
'D',
|
|
29
|
+
'CD',
|
|
30
|
+
'C',
|
|
31
|
+
'XC',
|
|
32
|
+
'L',
|
|
33
|
+
'XL',
|
|
34
|
+
'X',
|
|
35
|
+
'IX',
|
|
36
|
+
'V',
|
|
37
|
+
'IV',
|
|
38
|
+
'I'
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
function decimalToRoman(num) {
|
|
42
|
+
let roman = ''
|
|
43
|
+
for (const symbol of orders) {
|
|
44
|
+
while (num >= values[symbol]) {
|
|
45
|
+
roman += symbol
|
|
46
|
+
num -= values[symbol]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return roman
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { decimalToRoman }
|
package/Density.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
The density of a network is a measure of how many edges exist proportional to
|
|
3
|
+
how many edges would exist in a complete network (where all possible edges).
|
|
4
|
+
https://networkx.org/documentation/networkx-1.9/reference/generated/networkx.classes.function.density.html
|
|
5
|
+
*/
|
|
6
|
+
function density(numberOfNodes, numberOfEdges, isDirected = false) {
|
|
7
|
+
const multi = isDirected ? 1 : 2
|
|
8
|
+
return (multi * numberOfEdges) / (numberOfNodes * (numberOfNodes - 1))
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { density }
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @function dutchNationalFlagSort
|
|
3
|
+
* @description Dutch National Flag Sort is an algorithm to sort an array containing 0s, 1s, and 2s in linear time.
|
|
4
|
+
Time complexity of Dutch National Flag Sort Algorithm is O(n).
|
|
5
|
+
Auxiliary Space required for Dutch National Flag Sort Algorithm is O(1).
|
|
6
|
+
* @param {Integer[]} nums - Array of integers containing 0s, 1s, and 2s.
|
|
7
|
+
* @return {Integer[]} - Array of integers sorted in non-decreasing order.
|
|
8
|
+
* @see [Dutch National Flag Sort](https://en.wikipedia.org/wiki/Dutch_national_flag_problem)
|
|
9
|
+
*/
|
|
10
|
+
export function dutchNationalFlagSort(nums) {
|
|
11
|
+
let low = 0
|
|
12
|
+
let mid = 0
|
|
13
|
+
let high = nums.length - 1
|
|
14
|
+
|
|
15
|
+
while (mid <= high) {
|
|
16
|
+
switch (nums[mid]) {
|
|
17
|
+
case 0:
|
|
18
|
+
;[nums[low], nums[mid]] = [nums[mid], nums[low]]
|
|
19
|
+
low++
|
|
20
|
+
mid++
|
|
21
|
+
break
|
|
22
|
+
case 1:
|
|
23
|
+
mid++
|
|
24
|
+
break
|
|
25
|
+
case 2:
|
|
26
|
+
;[nums[mid], nums[high]] = [nums[high], nums[mid]]
|
|
27
|
+
high--
|
|
28
|
+
break
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return nums
|
|
33
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @function exponentialFunction
|
|
3
|
+
* @description Calculates the n+1 th order Taylor series approximation of exponential function e^x given n
|
|
4
|
+
* @param {Integer} power
|
|
5
|
+
* @param {Integer} order - 1
|
|
6
|
+
* @returns exponentialFunction(2,20) = 7.3890560989301735
|
|
7
|
+
* @url https://en.wikipedia.org/wiki/Exponential_function
|
|
8
|
+
*/
|
|
9
|
+
function exponentialFunction(power, n) {
|
|
10
|
+
let output = 0
|
|
11
|
+
let fac = 1
|
|
12
|
+
if (isNaN(power) || isNaN(n) || n < 0) {
|
|
13
|
+
throw new TypeError('Invalid Input')
|
|
14
|
+
}
|
|
15
|
+
if (n === 0) {
|
|
16
|
+
return 1
|
|
17
|
+
}
|
|
18
|
+
for (let i = 0; i < n; i++) {
|
|
19
|
+
output += power ** i / fac
|
|
20
|
+
fac *= i + 1
|
|
21
|
+
}
|
|
22
|
+
return output
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { exponentialFunction }
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @function Fibonacci
|
|
3
|
+
* @description Function to return the N-th Fibonacci number.
|
|
4
|
+
* @param {Integer} n - The input integer
|
|
5
|
+
* @return {Integer} - Return the N-th Fibonacci number
|
|
6
|
+
* @see [Fibonacci](https://en.wikipedia.org/wiki/Fibonacci_number)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const fibonacci = (n) => {
|
|
10
|
+
if (n < 2) {
|
|
11
|
+
return n
|
|
12
|
+
}
|
|
13
|
+
return fibonacci(n - 2) + fibonacci(n - 1)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { fibonacci }
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const shuffle = (array) => {
|
|
2
|
+
let maxLength = array.length
|
|
3
|
+
let temp
|
|
4
|
+
let idx
|
|
5
|
+
|
|
6
|
+
// While there remain elements to shuffle...
|
|
7
|
+
while (maxLength) {
|
|
8
|
+
// Pick a remaining element...
|
|
9
|
+
idx = Math.floor(Math.random() * maxLength--)
|
|
10
|
+
|
|
11
|
+
// And swap it with the current element
|
|
12
|
+
temp = array[maxLength]
|
|
13
|
+
array[maxLength] = array[idx]
|
|
14
|
+
array[idx] = temp
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return array
|
|
18
|
+
}
|
package/FloydWarshall.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Source:
|
|
3
|
+
https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm
|
|
4
|
+
|
|
5
|
+
Complexity:
|
|
6
|
+
O(|V|^3) where V is the set of vertices
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const FloydWarshall = (dist) => {
|
|
10
|
+
// Input:- dist: 2D Array where dist[i][j] = edge weight b/w i and j
|
|
11
|
+
// Output:- dist: 2D Array where dist[i][j] = shortest dist b/w i and j
|
|
12
|
+
const n = dist.length
|
|
13
|
+
for (let k = 0; k < n; k++) {
|
|
14
|
+
for (let i = 0; i < n; i++) {
|
|
15
|
+
for (let j = 0; j < n; j++) {
|
|
16
|
+
if (dist[i][j] > dist[i][k] + dist[k][j]) {
|
|
17
|
+
// dist from i to j via k is lesser than the current distance
|
|
18
|
+
dist[i][j] = dist[i][k] + dist[k][j]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return dist
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { FloydWarshall }
|
|
27
|
+
|
|
28
|
+
// For the following graph (edge weights are shown in brackets)
|
|
29
|
+
// 4 1 dist[1][2] = dist[2][1] = 1
|
|
30
|
+
// \ (2)/ \ dist[1][3] = dist[3][1] = 2
|
|
31
|
+
// \ / \(1) dist[1][4] = dist[4][1] = Infinity
|
|
32
|
+
// (1)\ / \ dist[3][4] = dist[4][3] = 1
|
|
33
|
+
// 3 2 dist[2][4] = dist[4][2] = Infinity
|
|
34
|
+
// dist[2][3] = dist[3][2] = Infinity
|
|
35
|
+
// Output should be:
|
|
36
|
+
// [ [0, 1, 2, 3],
|
|
37
|
+
// [1, 0, 3, 4],
|
|
38
|
+
// [2, 3, 0, 1],
|
|
39
|
+
// [3, 4, 1, 0] ]
|
|
40
|
+
|
|
41
|
+
// FloydWarshall(
|
|
42
|
+
// [[0, 1, 2, Infinity],
|
|
43
|
+
// [1, 0, Infinity, Infinity],
|
|
44
|
+
// [2, Infinity, 0, 1],
|
|
45
|
+
// [Infinity, Infinity, 1, 0]
|
|
46
|
+
// ]
|
|
47
|
+
// )
|
package/Haversine.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @function HaversineDistance
|
|
3
|
+
* @description Calculate the distance between two coordinates using the haversine formula
|
|
4
|
+
* @param {Integer} latitude1 - The input integer
|
|
5
|
+
* @param {Integer} latitude2 - The input integer
|
|
6
|
+
* @param {Integer} longitude1 - The input integer
|
|
7
|
+
* @param {Integer} longitude2 - The input integer
|
|
8
|
+
* @return {Integer} Haversine Distance.
|
|
9
|
+
* @see [Haversine_Distance](https://pt.wikipedia.org/wiki/F%C3%B3rmula_de_Haversine)
|
|
10
|
+
*/
|
|
11
|
+
const haversineDistance = (
|
|
12
|
+
latitude1 = 0,
|
|
13
|
+
longitude1 = 0,
|
|
14
|
+
latitude2 = 0,
|
|
15
|
+
longitude2 = 0
|
|
16
|
+
) => {
|
|
17
|
+
validateLatOrLong(latitude1)
|
|
18
|
+
validateLatOrLong(latitude2)
|
|
19
|
+
validateLatOrLong(longitude1)
|
|
20
|
+
validateLatOrLong(longitude2)
|
|
21
|
+
const earthRadius = 6371e3 // 6,371km
|
|
22
|
+
const pi = Math.PI
|
|
23
|
+
const cos1 = (latitude1 * pi) / 180.0
|
|
24
|
+
const cos2 = (latitude2 * pi) / 180.0
|
|
25
|
+
const deltaLatitude = ((latitude2 - latitude1) * pi) / 180.0
|
|
26
|
+
const deltaLongitude = ((longitude2 - longitude1) * pi) / 180.0
|
|
27
|
+
|
|
28
|
+
const alpha =
|
|
29
|
+
Math.sin(deltaLatitude / 2) * Math.sin(deltaLatitude / 2) +
|
|
30
|
+
Math.cos(cos1) *
|
|
31
|
+
Math.cos(cos2) *
|
|
32
|
+
Math.sin(deltaLongitude / 2) *
|
|
33
|
+
Math.sin(deltaLongitude / 2)
|
|
34
|
+
const constant = 2 * Math.atan2(Math.sqrt(alpha), Math.sqrt(1 - alpha))
|
|
35
|
+
return earthRadius * constant
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const validateLatOrLong = (value) => {
|
|
39
|
+
if (typeof value !== 'number') {
|
|
40
|
+
throw new TypeError('The value of latitude or longitude should be a number')
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { haversineDistance }
|
package/HexToRGB.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function hexStringToRGB(hexString) {
|
|
2
|
+
let r = hexString.substring(0, 2)
|
|
3
|
+
let g = hexString.substring(2, 4)
|
|
4
|
+
let b = hexString.substring(4, 6)
|
|
5
|
+
|
|
6
|
+
r = parseInt(r, 16)
|
|
7
|
+
g = parseInt(g, 16)
|
|
8
|
+
b = parseInt(b, 16)
|
|
9
|
+
const obj = { r, g, b }
|
|
10
|
+
|
|
11
|
+
return obj
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { hexStringToRGB }
|
|
15
|
+
|
|
16
|
+
// > hexStringToRGB('ffffff')
|
|
17
|
+
// { r: 255, g: 255, b: 255 }
|