Merge branch 'TheAlgorithms:master' into fix-maths-is-divisible

This commit is contained in:
Masa-Shin
2021-05-23 17:36:53 +09:00
45 changed files with 883 additions and 213 deletions

40
Maths/EulersTotient.js Normal file
View File

@@ -0,0 +1,40 @@
/*
Source:
https://en.wikipedia.org/wiki/Euler%27s_totient_function
EulersTotient(n) = n * product(1 - 1/p for all prime p dividing n)
Complexity:
O(sqrt(n))
*/
const EulersTotient = (n) => {
// input: n: int
// output: phi(n): count of numbers b/w 1 and n that are coprime to n
let res = n
for (let i = 2; i * i <= n; i++) {
if (n % i === 0) {
while (n % i === 0) {
n = Math.floor(n / i)
}
// i is a prime diving n, multiply res by 1 - 1/i
// res = res * (1 - 1/i) = res - (res / i)
res = res - Math.floor(res / i)
}
}
if (n > 1) {
res = res - Math.floor(res / n)
}
return res
}
const main = () => {
// EulersTotient(9) = 6 as 1, 2, 4, 5, 7, and 8 are coprime to 9
// > 6
console.log(EulersTotient(9))
// EulersTotient(10) = 4 as 1, 3, 7, 9 are coprime to 10
// > 4
console.log(EulersTotient(10))
}
main()

View File

@@ -63,7 +63,7 @@ const FibonacciDpWithoutRecursion = (number) => {
const table = []
table.push(1)
table.push(1)
for (var i = 2; i < number; ++i) {
for (let i = 2; i < number; ++i) {
table.push(table[i - 1] + table[i - 2])
}
return table

View File

@@ -0,0 +1,84 @@
/*
Source:
https://en.wikipedia.org/wiki/Exponentiation_by_squaring
Complexity:
O(d^3 log n)
where: d is the dimension of the square matrix
n is the power the matrix is raised to
*/
const Identity = (n) => {
// Input: n: int
// Output: res: Identity matrix of size n x n
// Complexity: O(n^2)
const res = []
for (let i = 0; i < n; i++) {
res[i] = []
for (let j = 0; j < n; j++) {
res[i][j] = i === j ? 1 : 0
}
}
return res
}
const MatMult = (matA, matB) => {
// Input: matA: 2D Array of Numbers of size n x n
// matB: 2D Array of Numbers of size n x n
// Output: matA x matB: 2D Array of Numbers of size n x n
// Complexity: O(n^3)
const n = matA.length
const matC = []
for (let i = 0; i < n; i++) {
matC[i] = []
for (let j = 0; j < n; j++) {
matC[i][j] = 0
}
}
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
for (let k = 0; k < n; k++) {
matC[i][j] += matA[i][k] * matB[k][j]
}
}
}
return matC
}
const MatrixExponentiationRecursive = (mat, m) => {
// Input: mat: 2D Array of Numbers of size n x n
// Output: mat^n: 2D Array of Numbers of size n x n
// Complexity: O(n^3 log m)
if (m === 0) {
// return identity matrix of size n x n
return Identity(mat.length)
} else if (m % 2 === 1) {
// tmp = mat ^ m-1
const tmp = MatrixExponentiationRecursive(mat, m - 1)
/// return tmp * mat = (mat ^ m-1) * mat = mat ^ m
return MatMult(tmp, mat)
} else {
// tmp = mat ^ m/2
const tmp = MatrixExponentiationRecursive(mat, m >> 1)
// return tmp * tmp = (mat ^ m/2) ^ 2 = mat ^ m
return MatMult(tmp, tmp)
}
}
const main = () => {
const mat = [[1, 0, 2], [2, 1, 0], [0, 2, 1]]
// mat ^ 0 = [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ]
console.log(MatrixExponentiationRecursive(mat, 0))
// mat ^ 1 = [ [ 1, 0, 2 ], [ 2, 1, 0 ], [ 0, 2, 1 ] ]
console.log(MatrixExponentiationRecursive(mat, 1))
// mat ^ 2 = [ [ 1, 4, 4 ], [ 4, 1, 4 ], [ 4, 4, 1 ] ]
console.log(MatrixExponentiationRecursive(mat, 2))
// mat ^ 5 = [ [ 1, 4, 4 ], [ 4, 1, 4 ], [ 4, 4, 1 ] ]
console.log(MatrixExponentiationRecursive(mat, 5))
}
main()

View File

@@ -32,11 +32,9 @@ class Polynomial {
return `(${coefficient}x^${exponent})`
}
})
.filter((x) => {
if (x !== '0') {
return x
}
})
.filter((x) =>
x !== '0'
)
.reverse()
.join(' + ')
}

View File

@@ -11,8 +11,10 @@ const PrimeCheck = (n) => {
// output: boolean
if (n === 1) return false
if (n === 0) return false
if (n === 2) return true
if (n % 2 === 0) return false
for (let i = 2; i * i <= n; i++) {
for (let i = 3; i * i <= n; i += 2) {
if (n % i === 0) {
return false
}

33
Maths/PrimeFactors.js Normal file
View File

@@ -0,0 +1,33 @@
/*
Modified from:
https://github.com/TheAlgorithms/Python/blob/master/maths/prime_factors.py
*/
const PrimeFactors = (n) => {
// input: n: int
// output: primeFactors: Array of all prime factors of n
const primeFactors = []
for (let i = 2; i <= n; i++) {
if (n % i === 0) {
while (n % i === 0) {
primeFactors.push(i)
n = Math.floor(n / i)
}
}
}
if (n > 1) {
primeFactors.push(n)
}
return primeFactors
}
const main = () => {
// PrimeFactors(100)
// > [ 2, 2, 5, 5 ]
console.log(PrimeFactors(100))
// PrimeFactors(2560)
// > [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 5 ]
console.log(PrimeFactors(2560))
}
main()

View File

@@ -10,7 +10,15 @@ const sieveOfEratosthenes = (n) => {
const sqrtn = Math.ceil(Math.sqrt(n))
for (let i = 2; i <= sqrtn; i++) {
if (primes[i]) {
for (let j = 2 * i; j <= n; j += i) {
for (let j = i * i; j <= n; j += i) {
/*
Optimization.
Let j start from i * i, not 2 * i, because smaller multiples of i have been marked false.
For example, let i = 4.
We do not have to check from 8(4 * 2) to 12(4 * 3)
because they have been already marked false when i=2 and i=3.
*/
primes[j] = false
}
}

19
Maths/SquareRoot.js Normal file
View File

@@ -0,0 +1,19 @@
/*
* Author: Rak Laptudirm
*
* https://en.wikipedia.org/wiki/Newton%27s_method
*
* Finding the square root of a number using Newton's method.
*/
function sqrt (num, precision = 10) {
if (!Number.isFinite(num)) { throw new TypeError(`Expected a number, received ${typeof num}`) }
if (!Number.isFinite(precision)) { throw new TypeError(`Expected a number, received ${typeof precision}`) }
let sqrt = 1
for (let i = 0; i < precision; i++) {
sqrt -= (sqrt * sqrt - num) / (2 * sqrt)
}
return sqrt
}
export { sqrt }