mirror of
https://github.com/TheAlgorithms/JavaScript.git
synced 2025-07-05 00:01:37 +08:00
feat: Test running overhaul, switch to Prettier & reformat everything (#1407)
* chore: Switch to Node 20 + Vitest * chore: migrate to vitest mock functions * chore: code style (switch to prettier) * test: re-enable long-running test Seems the switch to Node 20 and Vitest has vastly improved the code's and / or the test's runtime! see #1193 * chore: code style * chore: fix failing tests * Updated Documentation in README.md * Update contribution guidelines to state usage of Prettier * fix: set prettier printWidth back to 80 * chore: apply updated code style automatically * fix: set prettier line endings to lf again * chore: apply updated code style automatically --------- Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>
This commit is contained in:
@ -11,18 +11,19 @@
|
||||
/**
|
||||
* @param {Number} input The number whose aliquot sum you want to calculate
|
||||
*/
|
||||
function aliquotSum (input) {
|
||||
function aliquotSum(input) {
|
||||
// input can't be negative
|
||||
if (input < 0) throw new TypeError('Input cannot be Negative')
|
||||
|
||||
// input can't be a decimal
|
||||
if (Math.floor(input) !== input) throw new TypeError('Input cannot be a Decimal')
|
||||
if (Math.floor(input) !== input)
|
||||
throw new TypeError('Input cannot be a Decimal')
|
||||
|
||||
// Dealing with 1, which isn't a prime
|
||||
if (input === 1) return 0
|
||||
|
||||
let sum = 0
|
||||
for (let i = 1; i <= (input / 2); i++) {
|
||||
for (let i = 1; i <= input / 2; i++) {
|
||||
if (input % i === 0) sum += i
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ export const agm = (a, g) => {
|
||||
if (a === g) return a // avoid rounding errors, and increase efficiency
|
||||
let x // temp var
|
||||
do {
|
||||
[a, g, x] = [(a + g) / 2, Math.sqrt(a * g), a]
|
||||
;[a, g, x] = [(a + g) / 2, Math.sqrt(a * g), a]
|
||||
} while (a !== x && !isNaN(a))
|
||||
/*
|
||||
`x !== a` ensures the return value has full precision,
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
Modified from:
|
||||
https://github.com/TheAlgorithms/Python/blob/master/maths/binary_exponentiation.py
|
||||
|
||||
Explanation:
|
||||
https://en.wikipedia.org/wiki/Exponentiation_by_squaring
|
||||
*/
|
||||
|
||||
export const binaryExponentiation = (a, n) => {
|
||||
// input: a: int, n: int
|
||||
// returns: a^n: int
|
||||
if (n === 0) {
|
||||
return 1
|
||||
} else if (n % 2 === 1) {
|
||||
return binaryExponentiation(a, n - 1) * a
|
||||
} else {
|
||||
const b = binaryExponentiation(a, n / 2)
|
||||
return b * b
|
||||
}
|
||||
}
|
||||
/*
|
||||
Modified from:
|
||||
https://github.com/TheAlgorithms/Python/blob/master/maths/binary_exponentiation.py
|
||||
|
||||
Explanation:
|
||||
https://en.wikipedia.org/wiki/Exponentiation_by_squaring
|
||||
*/
|
||||
|
||||
export const binaryExponentiation = (a, n) => {
|
||||
// input: a: int, n: int
|
||||
// returns: a^n: int
|
||||
if (n === 0) {
|
||||
return 1
|
||||
} else if (n % 2 === 1) {
|
||||
return binaryExponentiation(a, n - 1) * a
|
||||
} else {
|
||||
const b = binaryExponentiation(a, n / 2)
|
||||
return b * b
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { calcFactorial } from './Factorial'
|
||||
|
||||
export const findBinomialCoefficient = (n, k) => {
|
||||
if ((typeof n !== 'number') || (typeof k !== 'number')) {
|
||||
if (typeof n !== 'number' || typeof k !== 'number') {
|
||||
throw Error('Type of arguments must be number.')
|
||||
}
|
||||
if (n < 0 || k < 0) {
|
||||
|
@ -18,19 +18,26 @@ const findRoot = (a, b, func, numberOfIterations) => {
|
||||
const res = f(x)
|
||||
return !Number.isNaN(res)
|
||||
}
|
||||
if (!belongsToDomain(a, func) || !belongsToDomain(b, func)) throw Error("Given interval is not a valid subset of function's domain")
|
||||
if (!belongsToDomain(a, func) || !belongsToDomain(b, func))
|
||||
throw Error("Given interval is not a valid subset of function's domain")
|
||||
|
||||
// Bolzano theorem
|
||||
const hasRoot = (a, b, func) => {
|
||||
return func(a) * func(b) < 0
|
||||
}
|
||||
if (hasRoot(a, b, func) === false) { throw Error('Product f(a)*f(b) has to be negative so that Bolzano theorem is applied') }
|
||||
if (hasRoot(a, b, func) === false) {
|
||||
throw Error(
|
||||
'Product f(a)*f(b) has to be negative so that Bolzano theorem is applied'
|
||||
)
|
||||
}
|
||||
|
||||
// Declare m
|
||||
const m = (a + b) / 2
|
||||
|
||||
// Recursion terminal condition
|
||||
if (numberOfIterations === 0) { return m }
|
||||
if (numberOfIterations === 0) {
|
||||
return m
|
||||
}
|
||||
|
||||
// Find the products of f(m) and f(a), f(b)
|
||||
const fm = func(m)
|
||||
@ -39,7 +46,8 @@ const findRoot = (a, b, func, numberOfIterations) => {
|
||||
|
||||
// Depending on the sign of the products above, decide which position will m fill (a's or b's)
|
||||
if (prod1 > 0 && prod2 < 0) return findRoot(m, b, func, --numberOfIterations)
|
||||
else if (prod1 < 0 && prod2 > 0) return findRoot(a, m, func, --numberOfIterations)
|
||||
else if (prod1 < 0 && prod2 > 0)
|
||||
return findRoot(a, m, func, --numberOfIterations)
|
||||
else throw Error('Unexpected behavior')
|
||||
}
|
||||
|
||||
|
@ -1,31 +1,28 @@
|
||||
import { degreeToRadian } from './DegreeToRadian.js'
|
||||
|
||||
/**
|
||||
* @function circularArcLength
|
||||
* @description calculate the length of a circular arc
|
||||
* @param {Integer} radius
|
||||
* @param {Integer} degrees
|
||||
* @returns {Integer} radius * angle_in_radians
|
||||
* @see https://en.wikipedia.org/wiki/Circular_arc
|
||||
* @example circularArcLength(3, 45) = 2.356194490192345
|
||||
*/
|
||||
function circularArcLength (radius, degrees) {
|
||||
* @function circularArcLength
|
||||
* @description calculate the length of a circular arc
|
||||
* @param {Integer} radius
|
||||
* @param {Integer} degrees
|
||||
* @returns {Integer} radius * angle_in_radians
|
||||
* @see https://en.wikipedia.org/wiki/Circular_arc
|
||||
* @example circularArcLength(3, 45) = 2.356194490192345
|
||||
*/
|
||||
function circularArcLength(radius, degrees) {
|
||||
return radius * degreeToRadian(degrees)
|
||||
}
|
||||
/**
|
||||
* @function circularArcArea
|
||||
* @description calculate the area of the sector formed by an arc
|
||||
* @param {Integer} radius
|
||||
* @param {Integer} degrees
|
||||
* @returns {Integer} 0.5 * r * r * angle_in_radians
|
||||
* @see https://en.wikipedia.org/wiki/Circular_arc
|
||||
* @example circularArcArea(3,45) = 3.5342917352885173
|
||||
*/
|
||||
function circularArcArea (radius, degrees) {
|
||||
return Math.pow(radius, 2) * degreeToRadian(degrees) / 2
|
||||
* @function circularArcArea
|
||||
* @description calculate the area of the sector formed by an arc
|
||||
* @param {Integer} radius
|
||||
* @param {Integer} degrees
|
||||
* @returns {Integer} 0.5 * r * r * angle_in_radians
|
||||
* @see https://en.wikipedia.org/wiki/Circular_arc
|
||||
* @example circularArcArea(3,45) = 3.5342917352885173
|
||||
*/
|
||||
function circularArcArea(radius, degrees) {
|
||||
return (Math.pow(radius, 2) * degreeToRadian(degrees)) / 2
|
||||
}
|
||||
|
||||
export {
|
||||
circularArcLength,
|
||||
circularArcArea
|
||||
}
|
||||
export { circularArcLength, circularArcArea }
|
||||
|
@ -13,9 +13,9 @@
|
||||
const GetEuclidGCD = (arg1, arg2) => {
|
||||
let less = arg1 > arg2 ? arg2 : arg1
|
||||
for (less; less >= 2; less--) {
|
||||
if ((arg1 % less === 0) && (arg2 % less === 0)) return (less)
|
||||
if (arg1 % less === 0 && arg2 % less === 0) return less
|
||||
}
|
||||
return (less)
|
||||
return less
|
||||
}
|
||||
|
||||
// CoPrimeCheck function return the boolean in respect of the given number is co-prime or not.
|
||||
|
@ -12,8 +12,8 @@
|
||||
*
|
||||
* @example collatz(1) = { result: 1, steps: [] }
|
||||
* @example collatz(5) = { result: 1, steps: [16, 8, 4, 2, 1] }
|
||||
*/
|
||||
export function collatz (n) {
|
||||
*/
|
||||
export function collatz(n) {
|
||||
const steps = []
|
||||
|
||||
while (n !== 1) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
const euclideanDistance = (longitude1, latitude1, longitude2, latitude2) => {
|
||||
const width = longitude2 - longitude1
|
||||
const height = latitude2 - latitude1
|
||||
return (Math.sqrt(width * width + height * height))
|
||||
return Math.sqrt(width * width + height * height)
|
||||
}
|
||||
|
||||
const manhattanDistance = (longitude1, latitude1, longitude2, latitude2) => {
|
||||
|
@ -19,13 +19,19 @@
|
||||
* @returns {number} count of total number of divisibles
|
||||
*/
|
||||
const countNumbersDivisible = (num1, num2, divider) => {
|
||||
if (typeof num1 !== 'number' || typeof num2 !== 'number' || typeof divider !== 'number') {
|
||||
if (
|
||||
typeof num1 !== 'number' ||
|
||||
typeof num2 !== 'number' ||
|
||||
typeof divider !== 'number'
|
||||
) {
|
||||
throw new Error('Invalid input, please pass only numbers')
|
||||
}
|
||||
|
||||
// Valid number range is num1 < num2, otherwise throw error
|
||||
if (num1 > num2) {
|
||||
throw new Error('Invalid number range, please provide numbers such that num1 < num2')
|
||||
throw new Error(
|
||||
'Invalid number range, please provide numbers such that num1 < num2'
|
||||
)
|
||||
}
|
||||
|
||||
// if divider is out of range then return 0
|
||||
|
@ -20,7 +20,7 @@
|
||||
* @param {number} [base=10]
|
||||
* @returns {array}
|
||||
*/
|
||||
export function decExp (a, b, base = 10, exp = [], d = {}, dlen = 0) {
|
||||
export function decExp(a, b, base = 10, exp = [], d = {}, dlen = 0) {
|
||||
if (base < 2 || base > 10) {
|
||||
throw new RangeError('Unsupported base. Must be in range [2, 10]')
|
||||
}
|
||||
|
@ -1,30 +1,36 @@
|
||||
/**
|
||||
* In mathematics and computational science, the Euler method (also called forward Euler method) is a first-order
|
||||
* numerical procedure for solving ordinary differential equations (ODEs) with a given initial value. It is the most
|
||||
* basic explicit method for numerical integration of ordinary differential equations. The method proceeds in a series
|
||||
* of steps. At each step the y-value is calculated by evaluating the differential equation at the previous step,
|
||||
* multiplying the result with the step-size and adding it to the last y-value: y_n+1 = y_n + stepSize * f(x_n, y_n).
|
||||
*
|
||||
* (description adapted from https://en.wikipedia.org/wiki/Euler_method)
|
||||
* @see https://www.geeksforgeeks.org/euler-method-solving-differential-equation/
|
||||
*/
|
||||
export function eulerStep (xCurrent, stepSize, yCurrent, differentialEquation) {
|
||||
// calculates the next y-value based on the current value of x, y and the stepSize
|
||||
return yCurrent + stepSize * differentialEquation(xCurrent, yCurrent)
|
||||
}
|
||||
|
||||
export function eulerFull (xStart, xEnd, stepSize, yStart, differentialEquation) {
|
||||
// loops through all the steps until xEnd is reached, adds a point for each step and then returns all the points
|
||||
const points = [{ x: xStart, y: yStart }]
|
||||
let yCurrent = yStart
|
||||
let xCurrent = xStart
|
||||
|
||||
while (xCurrent < xEnd) {
|
||||
// Euler method for next step
|
||||
yCurrent = eulerStep(xCurrent, stepSize, yCurrent, differentialEquation)
|
||||
xCurrent += stepSize
|
||||
points.push({ x: xCurrent, y: yCurrent })
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
/**
|
||||
* In mathematics and computational science, the Euler method (also called forward Euler method) is a first-order
|
||||
* numerical procedure for solving ordinary differential equations (ODEs) with a given initial value. It is the most
|
||||
* basic explicit method for numerical integration of ordinary differential equations. The method proceeds in a series
|
||||
* of steps. At each step the y-value is calculated by evaluating the differential equation at the previous step,
|
||||
* multiplying the result with the step-size and adding it to the last y-value: y_n+1 = y_n + stepSize * f(x_n, y_n).
|
||||
*
|
||||
* (description adapted from https://en.wikipedia.org/wiki/Euler_method)
|
||||
* @see https://www.geeksforgeeks.org/euler-method-solving-differential-equation/
|
||||
*/
|
||||
export function eulerStep(xCurrent, stepSize, yCurrent, differentialEquation) {
|
||||
// calculates the next y-value based on the current value of x, y and the stepSize
|
||||
return yCurrent + stepSize * differentialEquation(xCurrent, yCurrent)
|
||||
}
|
||||
|
||||
export function eulerFull(
|
||||
xStart,
|
||||
xEnd,
|
||||
stepSize,
|
||||
yStart,
|
||||
differentialEquation
|
||||
) {
|
||||
// loops through all the steps until xEnd is reached, adds a point for each step and then returns all the points
|
||||
const points = [{ x: xStart, y: yStart }]
|
||||
let yCurrent = yStart
|
||||
let xCurrent = xStart
|
||||
|
||||
while (xCurrent < xEnd) {
|
||||
// Euler method for next step
|
||||
yCurrent = eulerStep(xCurrent, stepSize, yCurrent, differentialEquation)
|
||||
xCurrent += stepSize
|
||||
points.push({ x: xCurrent, y: yCurrent })
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
@ -6,20 +6,20 @@
|
||||
* @returns exponentialFunction(2,20) = 7.3890560989301735
|
||||
* @url https://en.wikipedia.org/wiki/Exponential_function
|
||||
*/
|
||||
function exponentialFunction (power, n) {
|
||||
function exponentialFunction(power, n) {
|
||||
let output = 0
|
||||
let fac = 1
|
||||
if (isNaN(power) || isNaN(n) || n < 0) {
|
||||
throw new TypeError('Invalid Input')
|
||||
}
|
||||
if (n === 0) { return 1 }
|
||||
if (n === 0) {
|
||||
return 1
|
||||
}
|
||||
for (let i = 0; i < n; i++) {
|
||||
output += (power ** i) / fac
|
||||
fac *= (i + 1)
|
||||
output += power ** i / fac
|
||||
fac *= i + 1
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
export {
|
||||
exponentialFunction
|
||||
}
|
||||
export { exponentialFunction }
|
||||
|
@ -25,7 +25,8 @@
|
||||
* @returns Array with GCD and first and second Bézout coefficients
|
||||
*/
|
||||
const extendedEuclideanGCD = (arg1, arg2) => {
|
||||
if (typeof arg1 !== 'number' || typeof arg2 !== 'number') throw new TypeError('Not a Number')
|
||||
if (typeof arg1 !== 'number' || typeof arg2 !== 'number')
|
||||
throw new TypeError('Not a Number')
|
||||
if (arg1 < 1 || arg2 < 1) throw new TypeError('Must be positive numbers')
|
||||
|
||||
// Make the order of coefficients correct, as the algorithm assumes r0 > r1
|
||||
|
@ -14,7 +14,7 @@
|
||||
'use strict'
|
||||
|
||||
const calcRange = (num) => {
|
||||
return [...Array(num).keys()].map(i => i + 1)
|
||||
return [...Array(num).keys()].map((i) => i + 1)
|
||||
}
|
||||
|
||||
const calcFactorial = (num) => {
|
||||
@ -25,7 +25,9 @@ const calcFactorial = (num) => {
|
||||
throw Error('Sorry, factorial does not exist for negative numbers.')
|
||||
}
|
||||
if (!num) {
|
||||
throw Error('Sorry, factorial does not exist for null or undefined numbers.')
|
||||
throw Error(
|
||||
'Sorry, factorial does not exist for null or undefined numbers.'
|
||||
)
|
||||
}
|
||||
if (num > 0) {
|
||||
const range = calcRange(num)
|
||||
|
@ -1,41 +1,46 @@
|
||||
/*
|
||||
* Reference: https://en.wikipedia.org/wiki/Farey_sequence
|
||||
* Inspiration: https://www.youtube.com/watch?v=7LKy3lrkTRA
|
||||
*
|
||||
* Farey Approximation algorithm is an algorithm to
|
||||
* approximate a reduced fraction value for a certain
|
||||
* decimal number x where 0 < x < 1.
|
||||
*
|
||||
* The algorithm works by keeping two fractional upper and
|
||||
* lower bounds which start at 0 / 1 and 1 / 1. These values
|
||||
* are then used to find the "mediate" which is a value between
|
||||
* the two fractions.
|
||||
*
|
||||
* For any two fractions a / b and c / d,
|
||||
* mediate = a + c / b + d
|
||||
*
|
||||
* Then it is checked if the decimal is greater than or less
|
||||
* than the mediate and then the lower or the upper value is
|
||||
* set to be the mediate respectively.
|
||||
*
|
||||
* This is repeated for n times and then the mediate is
|
||||
* returned.
|
||||
*
|
||||
* This is explained in a greater detail in the "Inspiration"
|
||||
* link.
|
||||
*/
|
||||
* Reference: https://en.wikipedia.org/wiki/Farey_sequence
|
||||
* Inspiration: https://www.youtube.com/watch?v=7LKy3lrkTRA
|
||||
*
|
||||
* Farey Approximation algorithm is an algorithm to
|
||||
* approximate a reduced fraction value for a certain
|
||||
* decimal number x where 0 < x < 1.
|
||||
*
|
||||
* The algorithm works by keeping two fractional upper and
|
||||
* lower bounds which start at 0 / 1 and 1 / 1. These values
|
||||
* are then used to find the "mediate" which is a value between
|
||||
* the two fractions.
|
||||
*
|
||||
* For any two fractions a / b and c / d,
|
||||
* mediate = a + c / b + d
|
||||
*
|
||||
* Then it is checked if the decimal is greater than or less
|
||||
* than the mediate and then the lower or the upper value is
|
||||
* set to be the mediate respectively.
|
||||
*
|
||||
* This is repeated for n times and then the mediate is
|
||||
* returned.
|
||||
*
|
||||
* This is explained in a greater detail in the "Inspiration"
|
||||
* link.
|
||||
*/
|
||||
|
||||
function fareyApproximation (decimal, repeat = 20) {
|
||||
let a = 0; let b = 1; let c = 1; let d = 1; let numerator; let denominator
|
||||
function fareyApproximation(decimal, repeat = 20) {
|
||||
let a = 0
|
||||
let b = 1
|
||||
let c = 1
|
||||
let d = 1
|
||||
let numerator
|
||||
let denominator
|
||||
|
||||
for (let i = 0; i < repeat; i++) {
|
||||
numerator = a + c
|
||||
denominator = b + d
|
||||
|
||||
if (decimal > numerator / denominator) {
|
||||
[a, b] = [numerator, denominator]
|
||||
;[a, b] = [numerator, denominator]
|
||||
} else {
|
||||
[c, d] = [numerator, denominator]
|
||||
;[c, d] = [numerator, denominator]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,13 +16,13 @@ const FibonacciIterative = (num) => {
|
||||
return sequence
|
||||
}
|
||||
|
||||
const FibonacciGenerator = function * (neg) {
|
||||
const FibonacciGenerator = function* (neg) {
|
||||
let a = 0
|
||||
let b = 1
|
||||
yield a
|
||||
while (true) {
|
||||
yield b;
|
||||
[a, b] = neg ? [b, a - b] : [b, a + b]
|
||||
yield b
|
||||
;[a, b] = neg ? [b, a - b] : [b, a + b]
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,9 +55,11 @@ const FibonacciRecursiveDP = (stairs) => {
|
||||
if (stairs <= 1) return stairs
|
||||
|
||||
// Memoize stair count
|
||||
if (dict.has(stairs)) return (isNeg ? (-1) ** (stairs + 1) : 1) * dict.get(stairs)
|
||||
if (dict.has(stairs))
|
||||
return (isNeg ? (-1) ** (stairs + 1) : 1) * dict.get(stairs)
|
||||
|
||||
const res = FibonacciRecursiveDP(stairs - 1) + FibonacciRecursiveDP(stairs - 2)
|
||||
const res =
|
||||
FibonacciRecursiveDP(stairs - 1) + FibonacciRecursiveDP(stairs - 2)
|
||||
|
||||
dict.set(stairs, res)
|
||||
|
||||
@ -82,9 +84,7 @@ const FibonacciDpWithoutRecursion = (num) => {
|
||||
table.push(1)
|
||||
table.push(isNeg ? -1 : 1)
|
||||
for (let i = 2; i < num; ++i) {
|
||||
table.push(
|
||||
isNeg ? table[i - 1] - table[i] : table[i] + table[i - 1]
|
||||
)
|
||||
table.push(isNeg ? table[i - 1] - table[i] : table[i] + table[i - 1])
|
||||
}
|
||||
return table
|
||||
}
|
||||
@ -92,7 +92,7 @@ const FibonacciDpWithoutRecursion = (num) => {
|
||||
// Using Matrix exponentiation to find n-th fibonacci in O(log n) time
|
||||
|
||||
const copyMatrix = (A) => {
|
||||
return A.map(row => row.map(cell => cell))
|
||||
return A.map((row) => row.map((cell) => cell))
|
||||
}
|
||||
|
||||
const Identity = (size) => {
|
||||
@ -100,10 +100,14 @@ const Identity = (size) => {
|
||||
const ZERO = isBigInt ? 0n : 0
|
||||
const ONE = isBigInt ? 1n : 1
|
||||
size = Number(size)
|
||||
const I = Array(size).fill(null).map(() => Array(size).fill())
|
||||
return I.map((row, rowIdx) => row.map((_col, colIdx) => {
|
||||
return rowIdx === colIdx ? ONE : ZERO
|
||||
}))
|
||||
const I = Array(size)
|
||||
.fill(null)
|
||||
.map(() => Array(size).fill())
|
||||
return I.map((row, rowIdx) =>
|
||||
row.map((_col, colIdx) => {
|
||||
return rowIdx === colIdx ? ONE : ZERO
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// A of size (l x m) and B of size (m x n)
|
||||
@ -117,7 +121,9 @@ const matrixMultiply = (A, B) => {
|
||||
const l = A.length
|
||||
const m = B.length
|
||||
const n = B[0].length // Assuming non-empty matrices
|
||||
const C = Array(l).fill(null).map(() => Array(n).fill())
|
||||
const C = Array(l)
|
||||
.fill(null)
|
||||
.map(() => Array(n).fill())
|
||||
for (let i = 0; i < l; i++) {
|
||||
for (let j = 0; j < n; j++) {
|
||||
C[i][j] = isBigInt ? 0n : 0
|
||||
@ -179,10 +185,7 @@ const FibonacciMatrixExpo = (num) => {
|
||||
]
|
||||
|
||||
const poweredA = matrixExpo(A, num - ONE) // A raised to the power n-1
|
||||
let F = [
|
||||
[ONE],
|
||||
[ZERO]
|
||||
]
|
||||
let F = [[ONE], [ZERO]]
|
||||
F = matrixMultiply(poweredA, F)
|
||||
return F[0][0] * (isNeg ? (-ONE) ** (num + ONE) : ONE)
|
||||
}
|
||||
@ -195,7 +198,7 @@ const sqrt5 = Math.sqrt(5)
|
||||
const phi = (1 + sqrt5) / 2
|
||||
const psi = (1 - sqrt5) / 2
|
||||
|
||||
const FibonacciUsingFormula = n => Math.round((phi ** n - psi ** n) / sqrt5)
|
||||
const FibonacciUsingFormula = (n) => Math.round((phi ** n - psi ** n) / sqrt5)
|
||||
|
||||
export { FibonacciDpWithoutRecursion }
|
||||
export { FibonacciIterative }
|
||||
|
@ -47,7 +47,7 @@ const findLcmWithHcf = (num1, num2) => {
|
||||
throw Error('Numbers must be whole.')
|
||||
}
|
||||
|
||||
return num1 * num2 / findHCF(num1, num2)
|
||||
return (num1 * num2) / findHCF(num1, num2)
|
||||
}
|
||||
|
||||
export { findLcm, findLcmWithHcf }
|
||||
|
@ -1,42 +1,42 @@
|
||||
/**
|
||||
* @function findMaxRecursion
|
||||
* @description This algorithm will find the maximum value of a array of numbers.
|
||||
*
|
||||
* @param {Integer[]} arr Array of numbers
|
||||
* @param {Integer} left Index of the first element
|
||||
* @param {Integer} right Index of the last element
|
||||
*
|
||||
* @return {Integer} Maximum value of the array
|
||||
*
|
||||
* @see [Maximum value](https://en.wikipedia.org/wiki/Maximum_value)
|
||||
*
|
||||
* @example findMaxRecursion([1, 2, 4, 5]) = 5
|
||||
* @example findMaxRecursion([10, 40, 100, 20]) = 100
|
||||
* @example findMaxRecursion([-1, -2, -4, -5]) = -1
|
||||
*/
|
||||
function findMaxRecursion (arr, left, right) {
|
||||
const len = arr.length
|
||||
|
||||
if (len === 0 || !arr) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (left >= len || left < -len || right >= len || right < -len) {
|
||||
throw new Error('Index out of range')
|
||||
}
|
||||
|
||||
if (left === right) {
|
||||
return arr[left]
|
||||
}
|
||||
|
||||
// n >> m is equivalent to floor(n / pow(2, m)), floor(n / 2) in this case, which is the mid index
|
||||
const mid = (left + right) >> 1
|
||||
|
||||
const leftMax = findMaxRecursion(arr, left, mid)
|
||||
const rightMax = findMaxRecursion(arr, mid + 1, right)
|
||||
|
||||
// Return the maximum
|
||||
return Math.max(leftMax, rightMax)
|
||||
}
|
||||
|
||||
export { findMaxRecursion }
|
||||
/**
|
||||
* @function findMaxRecursion
|
||||
* @description This algorithm will find the maximum value of a array of numbers.
|
||||
*
|
||||
* @param {Integer[]} arr Array of numbers
|
||||
* @param {Integer} left Index of the first element
|
||||
* @param {Integer} right Index of the last element
|
||||
*
|
||||
* @return {Integer} Maximum value of the array
|
||||
*
|
||||
* @see [Maximum value](https://en.wikipedia.org/wiki/Maximum_value)
|
||||
*
|
||||
* @example findMaxRecursion([1, 2, 4, 5]) = 5
|
||||
* @example findMaxRecursion([10, 40, 100, 20]) = 100
|
||||
* @example findMaxRecursion([-1, -2, -4, -5]) = -1
|
||||
*/
|
||||
function findMaxRecursion(arr, left, right) {
|
||||
const len = arr.length
|
||||
|
||||
if (len === 0 || !arr) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (left >= len || left < -len || right >= len || right < -len) {
|
||||
throw new Error('Index out of range')
|
||||
}
|
||||
|
||||
if (left === right) {
|
||||
return arr[left]
|
||||
}
|
||||
|
||||
// n >> m is equivalent to floor(n / pow(2, m)), floor(n / 2) in this case, which is the mid index
|
||||
const mid = (left + right) >> 1
|
||||
|
||||
const leftMax = findMaxRecursion(arr, left, mid)
|
||||
const rightMax = findMaxRecursion(arr, mid + 1, right)
|
||||
|
||||
// Return the maximum
|
||||
return Math.max(leftMax, rightMax)
|
||||
}
|
||||
|
||||
export { findMaxRecursion }
|
||||
|
@ -9,24 +9,32 @@ const FindMinIterator = (_iterable, _selector = undefined) => {
|
||||
const iterator = _iterable[Symbol.iterator]()
|
||||
if (!_selector) {
|
||||
let current = iterator.next()
|
||||
if (current.done) { return undefined }
|
||||
if (current.done) {
|
||||
return undefined
|
||||
}
|
||||
min = current.value
|
||||
|
||||
current = iterator.next()
|
||||
while (!current.done) {
|
||||
const x = current.value
|
||||
if (x < min) { min = x }
|
||||
if (x < min) {
|
||||
min = x
|
||||
}
|
||||
current = iterator.next()
|
||||
}
|
||||
} else {
|
||||
let current = iterator.next()
|
||||
if (current.done) { return undefined }
|
||||
if (current.done) {
|
||||
return undefined
|
||||
}
|
||||
min = _selector(current.value)
|
||||
|
||||
current = iterator.next()
|
||||
while (!current.done) {
|
||||
const x = _selector(current.value)
|
||||
if (x < min) { min = x }
|
||||
if (x < min) {
|
||||
min = x
|
||||
}
|
||||
current = iterator.next()
|
||||
}
|
||||
}
|
||||
|
@ -10,18 +10,24 @@ export const FriendlyNumbers = (firstNumber, secondNumber) => {
|
||||
// output: true if the two integers are friendly numbers, false if they are not friendly numbers
|
||||
|
||||
// First, check that the parameters are valid
|
||||
if (!Number.isInteger(firstNumber) || !Number.isInteger(secondNumber) || firstNumber === 0 || secondNumber === 0 || firstNumber === secondNumber) {
|
||||
if (
|
||||
!Number.isInteger(firstNumber) ||
|
||||
!Number.isInteger(secondNumber) ||
|
||||
firstNumber === 0 ||
|
||||
secondNumber === 0 ||
|
||||
firstNumber === secondNumber
|
||||
) {
|
||||
throw new Error('The two parameters must be distinct, non-null integers')
|
||||
}
|
||||
|
||||
return abundancyIndex(firstNumber) === abundancyIndex(secondNumber)
|
||||
}
|
||||
|
||||
function abundancyIndex (number) {
|
||||
function abundancyIndex(number) {
|
||||
return sumDivisors(number) / number
|
||||
}
|
||||
|
||||
function sumDivisors (number) {
|
||||
function sumDivisors(number) {
|
||||
let runningSumDivisors = number
|
||||
for (let i = 0; i < number / 2; i++) {
|
||||
if (Number.isInteger(number / i)) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
* @param {Number} b integer (may be negative)
|
||||
* @returns {Number} Greatest Common Divisor gcd(a, b)
|
||||
*/
|
||||
export function GetEuclidGCD (a, b) {
|
||||
export function GetEuclidGCD(a, b) {
|
||||
if (typeof a !== 'number' || typeof b !== 'number') {
|
||||
throw new TypeError('Arguments must be numbers')
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ const isOdd = (number) => Boolean(number % 2) // 1 -> true, 0 -> false
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND
|
||||
* @param {number} number
|
||||
* @returns {boolean}
|
||||
*/
|
||||
*/
|
||||
const isOddBitwise = (number) => Boolean(number & 1) // 1 -> true, 0 -> false
|
||||
|
||||
export { isOdd, isOddBitwise }
|
||||
|
@ -10,7 +10,7 @@
|
||||
* jugglerSequence(15) // returns [15, 58, 7, 18, 4, 2, 1]
|
||||
*/
|
||||
|
||||
function jugglerSequence (n) {
|
||||
function jugglerSequence(n) {
|
||||
const sequence = []
|
||||
sequence.push(n)
|
||||
// Calculate terms until last term is not 1
|
||||
|
@ -14,5 +14,5 @@
|
||||
* @returns {boolean} true if this is a leap year, false otherwise.
|
||||
*/
|
||||
export const isLeapYear = (year) => {
|
||||
return ((year % 400) === 0) || (((year % 100) !== 0) && ((year % 4) === 0))
|
||||
return year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)
|
||||
}
|
||||
|
@ -13,12 +13,13 @@
|
||||
/**
|
||||
* @param {Number} index The position of the number you want to get from the Lucas Series
|
||||
*/
|
||||
function lucas (index) {
|
||||
function lucas(index) {
|
||||
// index can't be negative
|
||||
if (index < 0) throw new TypeError('Index cannot be Negative')
|
||||
|
||||
// index can't be a decimal
|
||||
if (Math.floor(index) !== index) throw new TypeError('Index cannot be a Decimal')
|
||||
if (Math.floor(index) !== index)
|
||||
throw new TypeError('Index cannot be a Decimal')
|
||||
|
||||
let a = 2
|
||||
let b = 1
|
||||
|
@ -27,14 +27,15 @@
|
||||
* @param {boolean} useDistanceColorCoding Render in color or black and white.
|
||||
* @return {object} The RGB-data of the rendered Mandelbrot set.
|
||||
*/
|
||||
export function getRGBData (
|
||||
export function getRGBData(
|
||||
imageWidth = 800,
|
||||
imageHeight = 600,
|
||||
figureCenterX = -0.6,
|
||||
figureCenterY = 0,
|
||||
figureWidth = 3.2,
|
||||
maxStep = 50,
|
||||
useDistanceColorCoding = true) {
|
||||
useDistanceColorCoding = true
|
||||
) {
|
||||
if (imageWidth <= 0) {
|
||||
throw new Error('imageWidth should be greater than zero')
|
||||
}
|
||||
@ -48,7 +49,7 @@ export function getRGBData (
|
||||
}
|
||||
|
||||
const rgbData = []
|
||||
const figureHeight = figureWidth / imageWidth * imageHeight
|
||||
const figureHeight = (figureWidth / imageWidth) * imageHeight
|
||||
|
||||
// loop through the image-coordinates
|
||||
for (let imageX = 0; imageX < imageWidth; imageX++) {
|
||||
@ -56,15 +57,15 @@ export function getRGBData (
|
||||
for (let imageY = 0; imageY < imageHeight; imageY++) {
|
||||
// determine the figure-coordinates based on the image-coordinates
|
||||
const figureX = figureCenterX + (imageX / imageWidth - 0.5) * figureWidth
|
||||
const figureY = figureCenterY + (imageY / imageHeight - 0.5) * figureHeight
|
||||
const figureY =
|
||||
figureCenterY + (imageY / imageHeight - 0.5) * figureHeight
|
||||
|
||||
const distance = getDistance(figureX, figureY, maxStep)
|
||||
|
||||
// color the corresponding pixel based on the selected coloring-function
|
||||
rgbData[imageX][imageY] =
|
||||
useDistanceColorCoding
|
||||
? colorCodedColorMap(distance)
|
||||
: blackAndWhiteColorMap(distance)
|
||||
rgbData[imageX][imageY] = useDistanceColorCoding
|
||||
? colorCodedColorMap(distance)
|
||||
: blackAndWhiteColorMap(distance)
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +80,7 @@ export function getRGBData (
|
||||
* @param {number} distance Distance until divergence threshold
|
||||
* @return {object} The RGB-value corresponding to the distance.
|
||||
*/
|
||||
function blackAndWhiteColorMap (distance) {
|
||||
function blackAndWhiteColorMap(distance) {
|
||||
return distance >= 1 ? [0, 0, 0] : [255, 255, 255]
|
||||
}
|
||||
|
||||
@ -91,7 +92,7 @@ function blackAndWhiteColorMap (distance) {
|
||||
* @param {number} distance Distance until divergence threshold
|
||||
* @return {object} The RGB-value corresponding to the distance.
|
||||
*/
|
||||
function colorCodedColorMap (distance) {
|
||||
function colorCodedColorMap(distance) {
|
||||
if (distance >= 1) {
|
||||
return [0, 0, 0]
|
||||
} else {
|
||||
@ -100,7 +101,7 @@ function colorCodedColorMap (distance) {
|
||||
const hue = 360 * distance
|
||||
const saturation = 1
|
||||
const val = 255
|
||||
const hi = (Math.floor(hue / 60)) % 6
|
||||
const hi = Math.floor(hue / 60) % 6
|
||||
const f = hue / 60 - Math.floor(hue / 60)
|
||||
|
||||
const v = val
|
||||
@ -136,7 +137,7 @@ function colorCodedColorMap (distance) {
|
||||
* @param {number} maxStep Maximum number of steps to check for divergent behavior.
|
||||
* @return {number} The relative distance as the ratio of steps taken to maxStep.
|
||||
*/
|
||||
function getDistance (figureX, figureY, maxStep) {
|
||||
function getDistance(figureX, figureY, maxStep) {
|
||||
let a = figureX
|
||||
let b = figureY
|
||||
let currentStep = 0
|
||||
|
@ -19,10 +19,17 @@ const matrixCheck = (matrix) => {
|
||||
|
||||
// tests to see if the matrices have a like side, i.e. the row length on the first matrix matches the column length on the second matrix, or vice versa.
|
||||
const twoMatricesCheck = (first, second) => {
|
||||
const [firstRowLength, secondRowLength, firstColLength, secondColLength] = [first.length, second.length, matrixCheck(first), matrixCheck(second)]
|
||||
const [firstRowLength, secondRowLength, firstColLength, secondColLength] = [
|
||||
first.length,
|
||||
second.length,
|
||||
matrixCheck(first),
|
||||
matrixCheck(second)
|
||||
]
|
||||
|
||||
// These matrices do not have a common side
|
||||
return firstRowLength === secondColLength && secondRowLength === firstColLength
|
||||
return (
|
||||
firstRowLength === secondColLength && secondRowLength === firstColLength
|
||||
)
|
||||
}
|
||||
|
||||
// returns an empty array that has the same number of rows as the left matrix being multiplied.
|
||||
|
@ -6,7 +6,7 @@ import { mean } from './AverageMean.js'
|
||||
* @returns meanAbsoluteDeviation([2,34,5,0,-2]) = 10.480
|
||||
* @url https://en.wikipedia.org/wiki/Average_absolute_deviation
|
||||
*/
|
||||
function meanAbsoluteDeviation (data) {
|
||||
function meanAbsoluteDeviation(data) {
|
||||
if (!Array.isArray(data)) {
|
||||
throw new TypeError('Invalid Input')
|
||||
}
|
||||
@ -18,6 +18,4 @@ function meanAbsoluteDeviation (data) {
|
||||
return absoluteSum / data.length
|
||||
}
|
||||
|
||||
export {
|
||||
meanAbsoluteDeviation
|
||||
}
|
||||
export { meanAbsoluteDeviation }
|
||||
|
@ -1,27 +1,33 @@
|
||||
/**
|
||||
*
|
||||
* @title Midpoint rule for definite integral evaluation
|
||||
* @author [ggkogkou](https://github.com/ggkogkou)
|
||||
* @brief Calculate definite integrals with midpoint method
|
||||
*
|
||||
* @details The idea is to split the interval in a number N of intervals and use as interpolation points the xi
|
||||
* for which it applies that xi = x0 + i*h, where h is a step defined as h = (b-a)/N where a and b are the
|
||||
* first and last points of the interval of the integration [a, b].
|
||||
*
|
||||
* We create a table of the xi and their corresponding f(xi) values and we evaluate the integral by the formula:
|
||||
* I = h * {f(x0+h/2) + f(x1+h/2) + ... + f(xN-1+h/2)}
|
||||
*
|
||||
* N must be > 0 and a<b. By increasing N, we also increase precision
|
||||
*
|
||||
* [More info link](https://tutorial.math.lamar.edu/classes/calcii/approximatingdefintegrals.aspx)
|
||||
*
|
||||
*/
|
||||
*
|
||||
* @title Midpoint rule for definite integral evaluation
|
||||
* @author [ggkogkou](https://github.com/ggkogkou)
|
||||
* @brief Calculate definite integrals with midpoint method
|
||||
*
|
||||
* @details The idea is to split the interval in a number N of intervals and use as interpolation points the xi
|
||||
* for which it applies that xi = x0 + i*h, where h is a step defined as h = (b-a)/N where a and b are the
|
||||
* first and last points of the interval of the integration [a, b].
|
||||
*
|
||||
* We create a table of the xi and their corresponding f(xi) values and we evaluate the integral by the formula:
|
||||
* I = h * {f(x0+h/2) + f(x1+h/2) + ... + f(xN-1+h/2)}
|
||||
*
|
||||
* N must be > 0 and a<b. By increasing N, we also increase precision
|
||||
*
|
||||
* [More info link](https://tutorial.math.lamar.edu/classes/calcii/approximatingdefintegrals.aspx)
|
||||
*
|
||||
*/
|
||||
|
||||
function integralEvaluation (N, a, b, func) {
|
||||
function integralEvaluation(N, a, b, func) {
|
||||
// Check if all restrictions are satisfied for the given N, a, b
|
||||
if (!Number.isInteger(N) || Number.isNaN(a) || Number.isNaN(b)) { throw new TypeError('Expected integer N and finite a, b') }
|
||||
if (N <= 0) { throw Error('N has to be >= 2') } // check if N > 0
|
||||
if (a > b) { throw Error('a must be less or equal than b') } // Check if a < b
|
||||
if (!Number.isInteger(N) || Number.isNaN(a) || Number.isNaN(b)) {
|
||||
throw new TypeError('Expected integer N and finite a, b')
|
||||
}
|
||||
if (N <= 0) {
|
||||
throw Error('N has to be >= 2')
|
||||
} // check if N > 0
|
||||
if (a > b) {
|
||||
throw Error('a must be less or equal than b')
|
||||
} // Check if a < b
|
||||
if (a === b) return 0 // If a === b integral is zero
|
||||
|
||||
// Calculate the step h
|
||||
@ -45,7 +51,11 @@ function integralEvaluation (N, a, b, func) {
|
||||
|
||||
result *= temp
|
||||
|
||||
if (Number.isNaN(result)) { throw Error('Result is NaN. The input interval does not belong to the functions domain') }
|
||||
if (Number.isNaN(result)) {
|
||||
throw Error(
|
||||
'Result is NaN. The input interval does not belong to the functions domain'
|
||||
)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
@ -25,5 +25,9 @@ export const mobiusFunction = (number) => {
|
||||
if (number <= 0) {
|
||||
throw new Error('Number must be greater than zero.')
|
||||
}
|
||||
return primeFactorsArray.length !== new Set(primeFactorsArray).size ? 0 : primeFactorsArray.length % 2 === 0 ? 1 : -1
|
||||
return primeFactorsArray.length !== new Set(primeFactorsArray).size
|
||||
? 0
|
||||
: primeFactorsArray.length % 2 === 0
|
||||
? 1
|
||||
: -1
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import { extendedEuclideanGCD } from './ExtendedEuclideanGCD'
|
||||
*/
|
||||
|
||||
export class ModRing {
|
||||
constructor (MOD) {
|
||||
constructor(MOD) {
|
||||
this.MOD = MOD
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ export class ModRing {
|
||||
/**
|
||||
* Modulus is Distributive property,
|
||||
* As a result, we separate it into numbers in order to keep it within MOD's range
|
||||
*/
|
||||
*/
|
||||
|
||||
add = (arg1, arg2) => {
|
||||
this.isInputValid(arg1, arg2)
|
||||
|
@ -1,22 +1,22 @@
|
||||
/*
|
||||
Modified from:
|
||||
https://github.com/TheAlgorithms/Python/blob/master/maths/binary_exp_mod.py
|
||||
|
||||
Explanation:
|
||||
https://en.wikipedia.org/wiki/Exponentiation_by_squaring
|
||||
*/
|
||||
|
||||
const modularBinaryExponentiation = (a, n, m) => {
|
||||
// input: a: int, n: int, m: int
|
||||
// returns: (a^n) % m: int
|
||||
if (n === 0) {
|
||||
return 1
|
||||
} else if (n % 2 === 1) {
|
||||
return (modularBinaryExponentiation(a, n - 1, m) * a) % m
|
||||
} else {
|
||||
const b = modularBinaryExponentiation(a, n / 2, m)
|
||||
return (b * b) % m
|
||||
}
|
||||
}
|
||||
|
||||
export { modularBinaryExponentiation }
|
||||
/*
|
||||
Modified from:
|
||||
https://github.com/TheAlgorithms/Python/blob/master/maths/binary_exp_mod.py
|
||||
|
||||
Explanation:
|
||||
https://en.wikipedia.org/wiki/Exponentiation_by_squaring
|
||||
*/
|
||||
|
||||
const modularBinaryExponentiation = (a, n, m) => {
|
||||
// input: a: int, n: int, m: int
|
||||
// returns: (a^n) % m: int
|
||||
if (n === 0) {
|
||||
return 1
|
||||
} else if (n % 2 === 1) {
|
||||
return (modularBinaryExponentiation(a, n - 1, m) * a) % m
|
||||
} else {
|
||||
const b = modularBinaryExponentiation(a, n / 2, m)
|
||||
return (b * b) % m
|
||||
}
|
||||
}
|
||||
|
||||
export { modularBinaryExponentiation }
|
||||
|
@ -17,6 +17,7 @@ const numberOfDigit = (n) => Math.abs(n).toString().length
|
||||
* @see https://math.stackexchange.com/questions/2145480/how-does-the-logarithm-returns-the-number-of-digits-of-a-number
|
||||
* @author dev-madhurendra
|
||||
*/
|
||||
const numberOfDigitsUsingLog = (n) => n === 0 ? 1 : Math.floor(Math.log10(Math.abs(n))) + 1
|
||||
const numberOfDigitsUsingLog = (n) =>
|
||||
n === 0 ? 1 : Math.floor(Math.log10(Math.abs(n))) + 1
|
||||
|
||||
export { numberOfDigit, numberOfDigitsUsingLog }
|
||||
|
@ -56,6 +56,7 @@ const PalindromeIterative = (string) => {
|
||||
* const isPalindrome = checkPalindrome('racecar'); // Returns true
|
||||
* const isNotPalindrome = checkPalindrome('hello'); // Returns false
|
||||
*/
|
||||
const checkPalindrome = (str) => str.replace(/\s/g, '') === str.replace(/\s/g, '').split('').reverse().join('')
|
||||
const checkPalindrome = (str) =>
|
||||
str.replace(/\s/g, '') === str.replace(/\s/g, '').split('').reverse().join('')
|
||||
|
||||
export { PalindromeIterative, PalindromeRecursive, checkPalindrome }
|
||||
|
@ -12,13 +12,16 @@ const parityOutlier = (integers) => {
|
||||
let odd, even
|
||||
|
||||
for (const e of integers) {
|
||||
if (!Number.isInteger(e)) { // detect non-integer elements
|
||||
if (!Number.isInteger(e)) {
|
||||
// detect non-integer elements
|
||||
return null
|
||||
}
|
||||
if (e % 2 === 0) { // an even number
|
||||
if (e % 2 === 0) {
|
||||
// an even number
|
||||
even = e
|
||||
evensCount++
|
||||
} else { // an odd number
|
||||
} else {
|
||||
// an odd number
|
||||
odd = e
|
||||
oddsCount++
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
* This uses `round` instead of `floor` or `trunc`, to guard against potential `cbrt` accuracy errors
|
||||
*/
|
||||
|
||||
const perfectCube = (num) => Number.isFinite(num) && Math.round(Math.cbrt(num)) ** 3 === num
|
||||
const perfectCube = (num) =>
|
||||
Number.isFinite(num) && Math.round(Math.cbrt(num)) ** 3 === num
|
||||
|
||||
export { perfectCube }
|
||||
|
@ -5,6 +5,7 @@
|
||||
* This uses `round` instead of `floor` or `trunc`, to guard against potential `sqrt` accuracy errors
|
||||
*/
|
||||
|
||||
const perfectSquare = (num) => Number.isFinite(num) && Math.round(Math.sqrt(num)) ** 2 === num
|
||||
const perfectSquare = (num) =>
|
||||
Number.isFinite(num) && Math.round(Math.sqrt(num)) ** 2 === num
|
||||
|
||||
export { perfectSquare }
|
||||
|
@ -9,7 +9,7 @@
|
||||
* The members of array are coefficients and their indexes as exponents.
|
||||
*/
|
||||
class Polynomial {
|
||||
constructor (array) {
|
||||
constructor(array) {
|
||||
this.coefficientArray = array // array of coefficients
|
||||
this.polynomial = '' // in terms of x e.g. (2x) + (1)
|
||||
this.construct()
|
||||
@ -18,7 +18,7 @@ class Polynomial {
|
||||
/**
|
||||
* Function to construct the polynomial in terms of x using the coefficientArray
|
||||
*/
|
||||
construct () {
|
||||
construct() {
|
||||
this.polynomial = this.coefficientArray
|
||||
.map((coefficient, exponent) => {
|
||||
if (coefficient === 0) {
|
||||
@ -32,9 +32,7 @@ class Polynomial {
|
||||
return `(${coefficient}x^${exponent})`
|
||||
}
|
||||
})
|
||||
.filter((x) =>
|
||||
x !== '0'
|
||||
)
|
||||
.filter((x) => x !== '0')
|
||||
.reverse()
|
||||
.join(' + ')
|
||||
}
|
||||
@ -43,7 +41,7 @@ class Polynomial {
|
||||
* Function to display polynomial in terms of x
|
||||
* @returns {String} of polynomial representation in terms of x
|
||||
*/
|
||||
display () {
|
||||
display() {
|
||||
return this.polynomial
|
||||
}
|
||||
|
||||
@ -51,7 +49,7 @@ class Polynomial {
|
||||
* Function to calculate the value of the polynomial by substituting variable x
|
||||
* @param {Number} value
|
||||
*/
|
||||
evaluate (value) {
|
||||
evaluate(value) {
|
||||
return this.coefficientArray.reduce((result, coefficient, exponent) => {
|
||||
return result + coefficient * Math.pow(value, exponent)
|
||||
}, 0)
|
||||
|
@ -15,7 +15,8 @@ const powLinear = (base, exponent) => {
|
||||
|
||||
let result = 1
|
||||
|
||||
while (exponent--) { // Break the execution while the exponent will 0
|
||||
while (exponent--) {
|
||||
// Break the execution while the exponent will 0
|
||||
result *= base
|
||||
}
|
||||
|
||||
@ -32,11 +33,13 @@ const powLinear = (base, exponent) => {
|
||||
* @example - powFaster(3, 3) => 27 --> 3 * 3 * 3
|
||||
*/
|
||||
const powFaster = (base, exponent) => {
|
||||
if (exponent < 2) { // explanation below - 1
|
||||
if (exponent < 2) {
|
||||
// explanation below - 1
|
||||
return base && ([1, base][exponent] || powFaster(1 / base, -exponent))
|
||||
}
|
||||
|
||||
if (exponent & 1) { // if the existing exponent is odd
|
||||
if (exponent & 1) {
|
||||
// if the existing exponent is odd
|
||||
return base * powFaster(base * base, exponent >> 1) // explanation below - 2
|
||||
}
|
||||
|
||||
|
@ -1,25 +1,25 @@
|
||||
/*
|
||||
Modified from:
|
||||
https://github.com/TheAlgorithms/Python/blob/master/maths/prime_check.py
|
||||
|
||||
Complexity:
|
||||
O(sqrt(n))
|
||||
*/
|
||||
|
||||
const PrimeCheck = (n) => {
|
||||
// input: n: int
|
||||
// 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 = 3; i * i <= n; i += 2) {
|
||||
if (n % i === 0) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export { PrimeCheck }
|
||||
/*
|
||||
Modified from:
|
||||
https://github.com/TheAlgorithms/Python/blob/master/maths/prime_check.py
|
||||
|
||||
Complexity:
|
||||
O(sqrt(n))
|
||||
*/
|
||||
|
||||
const PrimeCheck = (n) => {
|
||||
// input: n: int
|
||||
// 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 = 3; i * i <= n; i += 2) {
|
||||
if (n % i === 0) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export { PrimeCheck }
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
Modified from:
|
||||
https://github.com/TheAlgorithms/Python/blob/master/maths/prime_factors.py
|
||||
*/
|
||||
|
||||
export const PrimeFactors = (n) => {
|
||||
// input: n: int
|
||||
// output: primeFactors: Array of all prime factors of n
|
||||
const primeFactors = []
|
||||
for (let i = 2; i * i <= n; i++) {
|
||||
while (n % i === 0) {
|
||||
primeFactors.push(i)
|
||||
n = Math.floor(n / i)
|
||||
}
|
||||
}
|
||||
if (n > 1) {
|
||||
primeFactors.push(n)
|
||||
}
|
||||
return primeFactors
|
||||
}
|
||||
/*
|
||||
Modified from:
|
||||
https://github.com/TheAlgorithms/Python/blob/master/maths/prime_factors.py
|
||||
*/
|
||||
|
||||
export const PrimeFactors = (n) => {
|
||||
// input: n: int
|
||||
// output: primeFactors: Array of all prime factors of n
|
||||
const primeFactors = []
|
||||
for (let i = 2; i * i <= n; i++) {
|
||||
while (n % i === 0) {
|
||||
primeFactors.push(i)
|
||||
n = Math.floor(n / i)
|
||||
}
|
||||
}
|
||||
if (n > 1) {
|
||||
primeFactors.push(n)
|
||||
}
|
||||
return primeFactors
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
* are a multiple of N, either g^(p/2) + 1 or g^(p/2) - 1 must share a
|
||||
* factor with N, which can then be found using Euclid's GCD algorithm.
|
||||
*/
|
||||
function ShorsAlgorithm (num) {
|
||||
function ShorsAlgorithm(num) {
|
||||
const N = BigInt(num)
|
||||
|
||||
while (true) {
|
||||
@ -61,7 +61,7 @@ function ShorsAlgorithm (num) {
|
||||
* @param {BigInt} B
|
||||
* @returns The value p.
|
||||
*/
|
||||
function findP (A, B) {
|
||||
function findP(A, B) {
|
||||
let p = 1n
|
||||
while (!isValidP(A, B, p)) p++
|
||||
return p
|
||||
@ -75,7 +75,7 @@ function findP (A, B) {
|
||||
* @param {BigInt} p
|
||||
* @returns Whether A, B, and p fulfill A^p = mB + 1.
|
||||
*/
|
||||
function isValidP (A, B, p) {
|
||||
function isValidP(A, B, p) {
|
||||
// A^p = mB + 1 => A^p - 1 = 0 (mod B)
|
||||
return (A ** p - 1n) % B === 0n
|
||||
}
|
||||
@ -87,9 +87,9 @@ function isValidP (A, B, p) {
|
||||
* @param {BigInt} B
|
||||
* @returns Greatest Common Divisor between A and B.
|
||||
*/
|
||||
function gcd (A, B) {
|
||||
function gcd(A, B) {
|
||||
while (B !== 0n) {
|
||||
[A, B] = [B, A % B]
|
||||
;[A, B] = [B, A % B]
|
||||
}
|
||||
|
||||
return Number(A)
|
||||
|
@ -4,14 +4,16 @@
|
||||
* @see {@link https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes}
|
||||
*/
|
||||
|
||||
function sieveOfEratosthenes (max) {
|
||||
function sieveOfEratosthenes(max) {
|
||||
const sieve = []
|
||||
const primes = []
|
||||
|
||||
for (let i = 2; i <= max; ++i) {
|
||||
if (!sieve[i]) { // If i has not been marked then it is prime
|
||||
if (!sieve[i]) {
|
||||
// If i has not been marked then it is prime
|
||||
primes.push(i)
|
||||
for (let j = i << 1; j <= max; j += i) { // Mark all multiples of i as non-prime
|
||||
for (let j = i << 1; j <= max; j += i) {
|
||||
// Mark all multiples of i as non-prime
|
||||
sieve[j] = true
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* @param {Number} input
|
||||
* @returns {-1 | 0 | 1 | NaN} sign of input (and NaN if the input is not a number)
|
||||
*/
|
||||
function signum (input) {
|
||||
function signum(input) {
|
||||
if (input === 0) return 0
|
||||
if (input > 0) return 1
|
||||
if (input < 0) return -1
|
||||
|
@ -1,37 +1,45 @@
|
||||
/*
|
||||
*
|
||||
* @file
|
||||
* @title Composite Simpson's rule for definite integral evaluation
|
||||
* @author: [ggkogkou](https://github.com/ggkogkou)
|
||||
* @brief Calculate definite integrals using composite Simpson's numerical method
|
||||
*
|
||||
* @details The idea is to split the interval in an EVEN number N of intervals and use as interpolation points the xi
|
||||
* for which it applies that xi = x0 + i*h, where h is a step defined as h = (b-a)/N where a and b are the
|
||||
* first and last points of the interval of the integration [a, b].
|
||||
*
|
||||
* We create a table of the xi and their corresponding f(xi) values and we evaluate the integral by the formula:
|
||||
* I = h/3 * {f(x0) + 4*f(x1) + 2*f(x2) + ... + 2*f(xN-2) + 4*f(xN-1) + f(xN)}
|
||||
*
|
||||
* That means that the first and last indexed i f(xi) are multiplied by 1,
|
||||
* the odd indexed f(xi) by 4 and the even by 2.
|
||||
*
|
||||
* N must be even number and a<b. By increasing N, we also increase precision
|
||||
*
|
||||
* More info: [Wikipedia link](https://en.wikipedia.org/wiki/Simpson%27s_rule#Composite_Simpson's_rule)
|
||||
*
|
||||
*/
|
||||
*
|
||||
* @file
|
||||
* @title Composite Simpson's rule for definite integral evaluation
|
||||
* @author: [ggkogkou](https://github.com/ggkogkou)
|
||||
* @brief Calculate definite integrals using composite Simpson's numerical method
|
||||
*
|
||||
* @details The idea is to split the interval in an EVEN number N of intervals and use as interpolation points the xi
|
||||
* for which it applies that xi = x0 + i*h, where h is a step defined as h = (b-a)/N where a and b are the
|
||||
* first and last points of the interval of the integration [a, b].
|
||||
*
|
||||
* We create a table of the xi and their corresponding f(xi) values and we evaluate the integral by the formula:
|
||||
* I = h/3 * {f(x0) + 4*f(x1) + 2*f(x2) + ... + 2*f(xN-2) + 4*f(xN-1) + f(xN)}
|
||||
*
|
||||
* That means that the first and last indexed i f(xi) are multiplied by 1,
|
||||
* the odd indexed f(xi) by 4 and the even by 2.
|
||||
*
|
||||
* N must be even number and a<b. By increasing N, we also increase precision
|
||||
*
|
||||
* More info: [Wikipedia link](https://en.wikipedia.org/wiki/Simpson%27s_rule#Composite_Simpson's_rule)
|
||||
*
|
||||
*/
|
||||
|
||||
function integralEvaluation (N, a, b, func) {
|
||||
function integralEvaluation(N, a, b, func) {
|
||||
// Check if N is an even integer
|
||||
let isNEven = true
|
||||
if (N % 2 !== 0) isNEven = false
|
||||
|
||||
if (!Number.isInteger(N) || Number.isNaN(a) || Number.isNaN(b)) { throw new TypeError('Expected integer N and finite a, b') }
|
||||
if (!isNEven) { throw Error('N is not an even number') }
|
||||
if (N <= 0) { throw Error('N has to be >= 2') }
|
||||
if (!Number.isInteger(N) || Number.isNaN(a) || Number.isNaN(b)) {
|
||||
throw new TypeError('Expected integer N and finite a, b')
|
||||
}
|
||||
if (!isNEven) {
|
||||
throw Error('N is not an even number')
|
||||
}
|
||||
if (N <= 0) {
|
||||
throw Error('N has to be >= 2')
|
||||
}
|
||||
|
||||
// Check if a < b
|
||||
if (a > b) { throw Error('a must be less or equal than b') }
|
||||
if (a > b) {
|
||||
throw Error('a must be less or equal than b')
|
||||
}
|
||||
if (a === b) return 0
|
||||
|
||||
// Calculate the step h
|
||||
@ -58,7 +66,11 @@ function integralEvaluation (N, a, b, func) {
|
||||
|
||||
result *= temp
|
||||
|
||||
if (Number.isNaN(result)) { throw Error("Result is NaN. The input interval doesn't belong to the functions domain") }
|
||||
if (Number.isNaN(result)) {
|
||||
throw Error(
|
||||
"Result is NaN. The input interval doesn't belong to the functions domain"
|
||||
)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Wikipedia: https://en.wikipedia.org/wiki/Softmax_function
|
||||
|
||||
const Softmax = (inputs) => {
|
||||
const eulerExpOfAllInputs = inputs.map(input => Math.exp(input))
|
||||
const eulerExpOfAllInputs = inputs.map((input) => Math.exp(input))
|
||||
const sumOfEulerExpOfAllInputs = eulerExpOfAllInputs.reduce((a, b) => a + b)
|
||||
|
||||
return inputs.map((input) => {
|
||||
|
@ -1,14 +1,18 @@
|
||||
/*
|
||||
* Author: Rak Laptudirm
|
||||
*
|
||||
* https://en.wikipedia.org/wiki/Newton%27s_method
|
||||
*
|
||||
* Finding the square root of a number using Newton's method.
|
||||
*/
|
||||
* 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 = 4) {
|
||||
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}`) }
|
||||
function sqrt(num, precision = 4) {
|
||||
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)
|
||||
|
@ -9,17 +9,20 @@
|
||||
The given input is converted to a string, split into an array of characters.
|
||||
This array is reduced to a number using the method <Array>.reduce
|
||||
*/
|
||||
function sumOfDigitsUsingString (number) {
|
||||
function sumOfDigitsUsingString(number) {
|
||||
if (number < 0) number = -number
|
||||
|
||||
return +(number.toString().split('').reduce((a, b) => (+a) + (+b)))
|
||||
return +number
|
||||
.toString()
|
||||
.split('')
|
||||
.reduce((a, b) => +a + +b)
|
||||
}
|
||||
|
||||
/*
|
||||
The input is divided by 10 in each iteration, till the input is equal to 0
|
||||
The sum of all the digits is returned (The res variable acts as a collector, taking the remainders on each iteration)
|
||||
*/
|
||||
function sumOfDigitsUsingLoop (number) {
|
||||
function sumOfDigitsUsingLoop(number) {
|
||||
if (number < 0) number = -number
|
||||
let res = 0
|
||||
|
||||
@ -34,7 +37,7 @@ function sumOfDigitsUsingLoop (number) {
|
||||
/*
|
||||
We use the fact that the sum of the digits of a one digit number is itself, and check whether the number is less than 10. If so, then we return the number. Else, we take the number divided by 10 and floored, and recursively call the function, while adding it with the number mod 10
|
||||
*/
|
||||
function sumOfDigitsUsingRecursion (number) {
|
||||
function sumOfDigitsUsingRecursion(number) {
|
||||
if (number < 0) number = -number
|
||||
|
||||
if (number < 10) return number
|
||||
@ -42,4 +45,8 @@ function sumOfDigitsUsingRecursion (number) {
|
||||
return (number % 10) + sumOfDigitsUsingRecursion(Math.floor(number / 10))
|
||||
}
|
||||
|
||||
export { sumOfDigitsUsingRecursion, sumOfDigitsUsingLoop, sumOfDigitsUsingString }
|
||||
export {
|
||||
sumOfDigitsUsingRecursion,
|
||||
sumOfDigitsUsingLoop,
|
||||
sumOfDigitsUsingString
|
||||
}
|
||||
|
@ -16,19 +16,23 @@
|
||||
* @param {Number} commonRatio The common ratio of the geometric progression
|
||||
* @param {Number} numOfTerms The number of terms in the progression
|
||||
*/
|
||||
function sumOfGeometricProgression (firstTerm, commonRatio, numOfTerms) {
|
||||
function sumOfGeometricProgression(firstTerm, commonRatio, numOfTerms) {
|
||||
if (!Number.isFinite(numOfTerms)) {
|
||||
/*
|
||||
If the number of Terms is Infinity, the common ratio needs to be less than 1 to be a convergent geometric progression
|
||||
Article on Convergent Series: https://en.wikipedia.org/wiki/Convergent_series
|
||||
*/
|
||||
if (Math.abs(commonRatio) < 1) return firstTerm / (1 - commonRatio)
|
||||
throw new Error('The geometric progression is diverging, and its sum cannot be calculated')
|
||||
throw new Error(
|
||||
'The geometric progression is diverging, and its sum cannot be calculated'
|
||||
)
|
||||
}
|
||||
|
||||
if (commonRatio === 1) return firstTerm * numOfTerms
|
||||
|
||||
return (firstTerm * (Math.pow(commonRatio, numOfTerms) - 1)) / (commonRatio - 1)
|
||||
return (
|
||||
(firstTerm * (Math.pow(commonRatio, numOfTerms) - 1)) / (commonRatio - 1)
|
||||
)
|
||||
}
|
||||
|
||||
export { sumOfGeometricProgression }
|
||||
|
@ -11,8 +11,8 @@ import { PrimeCheck } from './PrimeCheck'
|
||||
*
|
||||
* @example twinPrime(5) = 7
|
||||
* @example twinPrime(4) = -1
|
||||
*/
|
||||
function twinPrime (n) {
|
||||
*/
|
||||
function twinPrime(n) {
|
||||
const prime = PrimeCheck(n)
|
||||
|
||||
if (!prime) {
|
||||
|
@ -21,7 +21,7 @@ const volCuboid = (width, length, height) => {
|
||||
isNumber(width, 'Width')
|
||||
isNumber(length, 'Length')
|
||||
isNumber(height, 'Height')
|
||||
return (width * length * height)
|
||||
return width * length * height
|
||||
}
|
||||
|
||||
/*
|
||||
@ -31,7 +31,7 @@ const volCuboid = (width, length, height) => {
|
||||
*/
|
||||
const volCube = (length) => {
|
||||
isNumber(length, 'Length')
|
||||
return (length ** 3)
|
||||
return length ** 3
|
||||
}
|
||||
|
||||
/*
|
||||
@ -42,7 +42,7 @@ const volCube = (length) => {
|
||||
const volCone = (radius, height) => {
|
||||
isNumber(radius, 'Radius')
|
||||
isNumber(height, 'Height')
|
||||
return (Math.PI * radius ** 2 * height / 3.0)
|
||||
return (Math.PI * radius ** 2 * height) / 3.0
|
||||
}
|
||||
|
||||
/*
|
||||
@ -65,7 +65,7 @@ const volPyramid = (baseLength, baseWidth, height) => {
|
||||
const volCylinder = (radius, height) => {
|
||||
isNumber(radius, 'Radius')
|
||||
isNumber(height, 'Height')
|
||||
return (Math.PI * radius ** 2 * height)
|
||||
return Math.PI * radius ** 2 * height
|
||||
}
|
||||
|
||||
/*
|
||||
@ -77,7 +77,7 @@ const volTriangularPrism = (baseLengthTriangle, heightTriangle, height) => {
|
||||
isNumber(baseLengthTriangle, 'BaseLengthTriangle')
|
||||
isNumber(heightTriangle, 'HeightTriangle')
|
||||
isNumber(height, 'Height')
|
||||
return (1 / 2 * baseLengthTriangle * heightTriangle * height)
|
||||
return (1 / 2) * baseLengthTriangle * heightTriangle * height
|
||||
}
|
||||
|
||||
/*
|
||||
@ -89,7 +89,7 @@ const volPentagonalPrism = (pentagonalLength, pentagonalBaseLength, height) => {
|
||||
isNumber(pentagonalLength, 'PentagonalLength')
|
||||
isNumber(pentagonalBaseLength, 'PentagonalBaseLength')
|
||||
isNumber(height, 'Height')
|
||||
return (5 / 2 * pentagonalLength * pentagonalBaseLength * height)
|
||||
return (5 / 2) * pentagonalLength * pentagonalBaseLength * height
|
||||
}
|
||||
|
||||
/*
|
||||
@ -99,7 +99,7 @@ const volPentagonalPrism = (pentagonalLength, pentagonalBaseLength, height) => {
|
||||
*/
|
||||
const volSphere = (radius) => {
|
||||
isNumber(radius, 'Radius')
|
||||
return (4 / 3 * Math.PI * radius ** 3)
|
||||
return (4 / 3) * Math.PI * radius ** 3
|
||||
}
|
||||
|
||||
/*
|
||||
@ -115,9 +115,19 @@ const volHemisphere = (radius) => {
|
||||
const isNumber = (number, noName = 'number') => {
|
||||
if (typeof number !== 'number') {
|
||||
throw new TypeError('The ' + noName + ' should be Number type')
|
||||
} else if (number < 0 || (!Number.isFinite(number))) {
|
||||
} else if (number < 0 || !Number.isFinite(number)) {
|
||||
throw new Error('The ' + noName + ' only accepts positive values')
|
||||
}
|
||||
}
|
||||
|
||||
export { volCuboid, volCube, volCone, volPyramid, volCylinder, volTriangularPrism, volPentagonalPrism, volSphere, volHemisphere }
|
||||
export {
|
||||
volCuboid,
|
||||
volCube,
|
||||
volCone,
|
||||
volPyramid,
|
||||
volCylinder,
|
||||
volTriangularPrism,
|
||||
volPentagonalPrism,
|
||||
volSphere,
|
||||
volHemisphere
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
// Zeller's Congruence Algorithm finds the day of the week from the Gregorian Date. Wikipedia: https://en.wikipedia.org/wiki/Zeller%27s_congruence
|
||||
export const zellersCongruenceAlgorithm = (day, month, year) => {
|
||||
if (typeof day !== 'number' || typeof month !== 'number' || typeof year !== 'number') {
|
||||
if (
|
||||
typeof day !== 'number' ||
|
||||
typeof month !== 'number' ||
|
||||
typeof year !== 'number'
|
||||
) {
|
||||
throw new TypeError('Arguments are not all numbers.')
|
||||
}
|
||||
const q = day
|
||||
@ -11,8 +15,13 @@ export const zellersCongruenceAlgorithm = (day, month, year) => {
|
||||
y -= 1
|
||||
}
|
||||
day =
|
||||
(q + Math.floor(26 * (m + 1) / 10) + (y % 100) + Math.floor((y % 100) / 4) + Math.floor(Math.floor(y / 100) / 4) + (5 * Math.floor(y / 100))) %
|
||||
7
|
||||
(q +
|
||||
Math.floor((26 * (m + 1)) / 10) +
|
||||
(y % 100) +
|
||||
Math.floor((y % 100) / 4) +
|
||||
Math.floor(Math.floor(y / 100) / 4) +
|
||||
5 * Math.floor(y / 100)) %
|
||||
7
|
||||
const days = [
|
||||
'Saturday',
|
||||
'Sunday',
|
||||
|
@ -6,7 +6,7 @@
|
||||
* time complexity : O(log_10(N))
|
||||
* space complexity : O(1)
|
||||
*/
|
||||
export function isPalindromeIntegerNumber (x) {
|
||||
export function isPalindromeIntegerNumber(x) {
|
||||
if (typeof x !== 'number') {
|
||||
throw new TypeError('Input must be a integer number')
|
||||
}
|
||||
|
@ -12,18 +12,26 @@ describe('Testing findBinomialCoefficient function', () => {
|
||||
})
|
||||
|
||||
it('should throw error when supplied arguments other than number', () => {
|
||||
expect(() => { findBinomialCoefficient('eight', 'three') }).toThrow(Error)
|
||||
expect(() => {
|
||||
findBinomialCoefficient('eight', 'three')
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should throw error when n is less than zero', () => {
|
||||
expect(() => { findBinomialCoefficient(-1, 3) }).toThrow(Error)
|
||||
expect(() => {
|
||||
findBinomialCoefficient(-1, 3)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should throw error when k is less than zero', () => {
|
||||
expect(() => { findBinomialCoefficient(1, -3) }).toThrow(Error)
|
||||
expect(() => {
|
||||
findBinomialCoefficient(1, -3)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should throw error when n and k are less than zero', () => {
|
||||
expect(() => { findBinomialCoefficient(-1, -3) }).toThrow(Error)
|
||||
expect(() => {
|
||||
findBinomialCoefficient(-1, -3)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
})
|
||||
|
@ -1,16 +1,37 @@
|
||||
import { findRoot } from '../BisectionMethod'
|
||||
|
||||
test('Equation f(x) = x^2 - 3*x + 2 = 0, has root x = 1 in [a, b] = [0, 1.5]', () => {
|
||||
const root = findRoot(0, 1.5, (x) => { return Math.pow(x, 2) - 3 * x + 2 }, 8)
|
||||
const root = findRoot(
|
||||
0,
|
||||
1.5,
|
||||
(x) => {
|
||||
return Math.pow(x, 2) - 3 * x + 2
|
||||
},
|
||||
8
|
||||
)
|
||||
expect(root).toBe(0.9990234375)
|
||||
})
|
||||
|
||||
test('Equation f(x) = ln(x) + sqrt(x) + π*x^2 = 0, has root x = 0.36247037 in [a, b] = [0, 10]', () => {
|
||||
const root = findRoot(0, 10, (x) => { return Math.log(x) + Math.sqrt(x) + Math.PI * Math.pow(x, 2) }, 32)
|
||||
const root = findRoot(
|
||||
0,
|
||||
10,
|
||||
(x) => {
|
||||
return Math.log(x) + Math.sqrt(x) + Math.PI * Math.pow(x, 2)
|
||||
},
|
||||
32
|
||||
)
|
||||
expect(Number(Number(root).toPrecision(8))).toBe(0.36247037)
|
||||
})
|
||||
|
||||
test('Equation f(x) = sqrt(x) + e^(2*x) - 8*x = 0, has root x = 0.93945851 in [a, b] = [0.5, 100]', () => {
|
||||
const root = findRoot(0.5, 100, (x) => { return Math.exp(2 * x) + Math.sqrt(x) - 8 * x }, 32)
|
||||
const root = findRoot(
|
||||
0.5,
|
||||
100,
|
||||
(x) => {
|
||||
return Math.exp(2 * x) + Math.sqrt(x) - 8 * x
|
||||
},
|
||||
32
|
||||
)
|
||||
expect(Number(Number(root).toPrecision(8))).toBe(0.93945851)
|
||||
})
|
||||
|
@ -6,7 +6,12 @@ describe('Testing euclideanDistance calculations', () => {
|
||||
expect(euclideanDistance).toBe(15)
|
||||
})
|
||||
it('Should not give any output given non-numeric argument', () => {
|
||||
const euclideanDistance = coordinate.euclideanDistance('ABC', '123', '', '###')
|
||||
const euclideanDistance = coordinate.euclideanDistance(
|
||||
'ABC',
|
||||
'123',
|
||||
'',
|
||||
'###'
|
||||
)
|
||||
expect(euclideanDistance).toBeNaN()
|
||||
})
|
||||
it('Should not give any output given any number of numeric arguments less than 4', () => {
|
||||
@ -27,7 +32,12 @@ describe('Testing manhattanDistance calculations', () => {
|
||||
expect(manhattanDistance).toBe(21)
|
||||
})
|
||||
it('Should not give any output given non-numeric argument', () => {
|
||||
const manhattanDistance = coordinate.manhattanDistance('ABC', '123', '', '###')
|
||||
const manhattanDistance = coordinate.manhattanDistance(
|
||||
'ABC',
|
||||
'123',
|
||||
'',
|
||||
'###'
|
||||
)
|
||||
expect(manhattanDistance).toBeNaN()
|
||||
})
|
||||
it('Should not give any output given any number of numeric arguments less than 4', () => {
|
||||
|
@ -7,14 +7,25 @@ describe('Count the numbers divisible', () => {
|
||||
[25, 100, 30, 3],
|
||||
[25, 70, 10, 5],
|
||||
[1, 23, 30, 0]
|
||||
])('Total number(s) divisible between %i to %i by %i is/are %i', (n1, n2, m, expected) => {
|
||||
expect(countNumbersDivisible(n1, n2, m)).toBe(expected)
|
||||
})
|
||||
])(
|
||||
'Total number(s) divisible between %i to %i by %i is/are %i',
|
||||
(n1, n2, m, expected) => {
|
||||
expect(countNumbersDivisible(n1, n2, m)).toBe(expected)
|
||||
}
|
||||
)
|
||||
|
||||
test.each([
|
||||
['test', 23, 10, 'Invalid input, please pass only numbers'],
|
||||
[44, 30, 10, 'Invalid number range, please provide numbers such that num1 < num2']
|
||||
])('Should throw an error for input %i, %i, %i, %i', (n1, n2, m, expected) => {
|
||||
expect(() => countNumbersDivisible(n1, n2, m)).toThrowError(expected)
|
||||
})
|
||||
[
|
||||
44,
|
||||
30,
|
||||
10,
|
||||
'Invalid number range, please provide numbers such that num1 < num2'
|
||||
]
|
||||
])(
|
||||
'Should throw an error for input %i, %i, %i, %i',
|
||||
(n1, n2, m, expected) => {
|
||||
expect(() => countNumbersDivisible(n1, n2, m)).toThrowError(expected)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { eulerFull } from '../EulerMethod'
|
||||
|
||||
function plotLine (label, points, width, height) {
|
||||
function plotLine(label, points, width, height) {
|
||||
// utility function to plot the results
|
||||
|
||||
// container needed to control the size of the canvas
|
||||
@ -14,17 +14,20 @@ function plotLine (label, points, width, height) {
|
||||
container.append(canvas)
|
||||
|
||||
// Chart-class from chartjs
|
||||
const chart = new Chart(canvas, { // eslint-disable-line
|
||||
const chart = new Chart(canvas, {
|
||||
// eslint-disable-line
|
||||
type: 'scatter',
|
||||
data: {
|
||||
datasets: [{
|
||||
label,
|
||||
data: points,
|
||||
showLine: true,
|
||||
fill: false,
|
||||
tension: 0,
|
||||
borderColor: 'black'
|
||||
}]
|
||||
datasets: [
|
||||
{
|
||||
label,
|
||||
data: points,
|
||||
showLine: true,
|
||||
fill: false,
|
||||
tension: 0,
|
||||
borderColor: 'black'
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
maintainAspectRatio: false,
|
||||
@ -33,17 +36,17 @@ function plotLine (label, points, width, height) {
|
||||
})
|
||||
}
|
||||
|
||||
function exampleEquation1 (x, y) {
|
||||
function exampleEquation1(x, y) {
|
||||
return x
|
||||
}
|
||||
|
||||
// example from https://en.wikipedia.org/wiki/Euler_method
|
||||
function exampleEquation2 (x, y) {
|
||||
function exampleEquation2(x, y) {
|
||||
return y
|
||||
}
|
||||
|
||||
// example from https://www.geeksforgeeks.org/euler-method-solving-differential-equation/
|
||||
function exampleEquation3 (x, y) {
|
||||
function exampleEquation3(x, y) {
|
||||
return x + y + x * y
|
||||
}
|
||||
|
||||
|
@ -2,17 +2,40 @@ import { eulerFull, eulerStep } from '../EulerMethod'
|
||||
|
||||
describe('eulerStep', () => {
|
||||
it('should calculate the next y value correctly', () => {
|
||||
expect(eulerStep(0, 0.1, 0, function (x, y) { return x })).toBe(0)
|
||||
expect(eulerStep(2, 1, 1, function (x, y) { return x * x })).toBe(5)
|
||||
expect(
|
||||
eulerStep(0, 0.1, 0, function (x, y) {
|
||||
return x
|
||||
})
|
||||
).toBe(0)
|
||||
expect(
|
||||
eulerStep(2, 1, 1, function (x, y) {
|
||||
return x * x
|
||||
})
|
||||
).toBe(5)
|
||||
})
|
||||
})
|
||||
|
||||
describe('eulerFull', () => {
|
||||
it('should return all the points found', () => {
|
||||
expect(eulerFull(0, 3, 1, 0, function (x, y) { return x }))
|
||||
.toEqual([{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 1 }, { x: 3, y: 3 }])
|
||||
expect(
|
||||
eulerFull(0, 3, 1, 0, function (x, y) {
|
||||
return x
|
||||
})
|
||||
).toEqual([
|
||||
{ x: 0, y: 0 },
|
||||
{ x: 1, y: 0 },
|
||||
{ x: 2, y: 1 },
|
||||
{ x: 3, y: 3 }
|
||||
])
|
||||
|
||||
expect(eulerFull(3, 4, 0.5, 1, function (x, y) { return x * x }))
|
||||
.toEqual([{ x: 3, y: 1 }, { x: 3.5, y: 5.5 }, { x: 4, y: 11.625 }])
|
||||
expect(
|
||||
eulerFull(3, 4, 0.5, 1, function (x, y) {
|
||||
return x * x
|
||||
})
|
||||
).toEqual([
|
||||
{ x: 3, y: 1 },
|
||||
{ x: 3.5, y: 5.5 },
|
||||
{ x: 4, y: 11.625 }
|
||||
])
|
||||
})
|
||||
})
|
||||
|
@ -6,11 +6,19 @@ describe('extendedEuclideanGCD', () => {
|
||||
expect(extendedEuclideanGCD(46, 240)).toMatchObject([2, 47, -9])
|
||||
})
|
||||
it('should give error on non-positive arguments', () => {
|
||||
expect(() => extendedEuclideanGCD(0, 240)).toThrowError(new TypeError('Must be positive numbers'))
|
||||
expect(() => extendedEuclideanGCD(46, -240)).toThrowError(new TypeError('Must be positive numbers'))
|
||||
expect(() => extendedEuclideanGCD(0, 240)).toThrowError(
|
||||
new TypeError('Must be positive numbers')
|
||||
)
|
||||
expect(() => extendedEuclideanGCD(46, -240)).toThrowError(
|
||||
new TypeError('Must be positive numbers')
|
||||
)
|
||||
})
|
||||
it('should give error on non-numeric arguments', () => {
|
||||
expect(() => extendedEuclideanGCD('240', 46)).toThrowError(new TypeError('Not a Number'))
|
||||
expect(() => extendedEuclideanGCD([240, 46])).toThrowError(new TypeError('Not a Number'))
|
||||
expect(() => extendedEuclideanGCD('240', 46)).toThrowError(
|
||||
new TypeError('Not a Number')
|
||||
)
|
||||
expect(() => extendedEuclideanGCD([240, 46])).toThrowError(
|
||||
new TypeError('Not a Number')
|
||||
)
|
||||
})
|
||||
})
|
||||
|
@ -6,12 +6,18 @@ describe('calcFactorial', () => {
|
||||
})
|
||||
|
||||
it('should throw error for "null" and "undefined"', () => {
|
||||
expect(() => { calcFactorial(null) }).toThrow(Error)
|
||||
expect(() => { calcFactorial(undefined) }).toThrow(Error)
|
||||
expect(() => {
|
||||
calcFactorial(null)
|
||||
}).toThrow(Error)
|
||||
expect(() => {
|
||||
calcFactorial(undefined)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should throw error for negative numbers', () => {
|
||||
expect(() => { calcFactorial(-1) }).toThrow(Error)
|
||||
expect(() => {
|
||||
calcFactorial(-1)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should return the factorial of a positive number', () => {
|
||||
|
@ -100,7 +100,10 @@ describe('Fibonacci', () => {
|
||||
[0, 0],
|
||||
[1, 1],
|
||||
[15, 610]
|
||||
])('should calculate the correct Fibonacci number for n = %i', (n, expected) => {
|
||||
expect(FibonacciUsingFormula(n)).toBe(expected)
|
||||
})
|
||||
])(
|
||||
'should calculate the correct Fibonacci number for n = %i',
|
||||
(n, expected) => {
|
||||
expect(FibonacciUsingFormula(n)).toBe(expected)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -2,16 +2,24 @@ import { findLcm, findLcmWithHcf } from '../FindLcm'
|
||||
|
||||
describe('findLcm', () => {
|
||||
it('should throw a statement for values less than 1', () => {
|
||||
expect(() => { findLcm(0, 0) }).toThrow(Error)
|
||||
expect(() => {
|
||||
findLcm(0, 0)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should throw a statement for one value less than 1', () => {
|
||||
expect(() => { findLcm(1, 0) }).toThrow(Error)
|
||||
expect(() => { findLcm(0, 1) }).toThrow(Error)
|
||||
expect(() => {
|
||||
findLcm(1, 0)
|
||||
}).toThrow(Error)
|
||||
expect(() => {
|
||||
findLcm(0, 1)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should return an error for values non-integer values', () => {
|
||||
expect(() => { findLcm(4.564, 7.39) }).toThrow(Error)
|
||||
expect(() => {
|
||||
findLcm(4.564, 7.39)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should return the LCM of two given integers', () => {
|
||||
@ -21,16 +29,24 @@ describe('findLcm', () => {
|
||||
|
||||
describe('findLcmWithHcf', () => {
|
||||
it('should throw a statement for values less than 1', () => {
|
||||
expect(() => { findLcmWithHcf(0, 0) }).toThrow(Error)
|
||||
expect(() => {
|
||||
findLcmWithHcf(0, 0)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should throw a statement for one value less than 1', () => {
|
||||
expect(() => { findLcmWithHcf(1, 0) }).toThrow(Error)
|
||||
expect(() => { findLcmWithHcf(0, 1) }).toThrow(Error)
|
||||
expect(() => {
|
||||
findLcmWithHcf(1, 0)
|
||||
}).toThrow(Error)
|
||||
expect(() => {
|
||||
findLcmWithHcf(0, 1)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should return an error for values non-integer values', () => {
|
||||
expect(() => { findLcmWithHcf(4.564, 7.39) }).toThrow(Error)
|
||||
expect(() => {
|
||||
findLcmWithHcf(4.564, 7.39)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should return the LCM of two given integers', () => {
|
||||
|
@ -1,58 +1,58 @@
|
||||
import { findMaxRecursion } from '../FindMaxRecursion'
|
||||
|
||||
describe('Test findMaxRecursion function', () => {
|
||||
const positiveAndNegativeArray = [1, 2, 4, 5, -1, -2, -4, -5]
|
||||
const positiveAndNegativeArray1 = [10, 40, 100, 20, -10, -40, -100, -20]
|
||||
|
||||
const positiveArray = [1, 2, 4, 5]
|
||||
const positiveArray1 = [10, 40, 100, 20]
|
||||
|
||||
const negativeArray = [-1, -2, -4, -5]
|
||||
const negativeArray1 = [-10, -40, -100, -20]
|
||||
|
||||
const zeroArray = [0, 0, 0, 0]
|
||||
const emptyArray = []
|
||||
|
||||
it('Testing with positive arrays', () => {
|
||||
expect(findMaxRecursion(positiveArray, 0, positiveArray.length - 1)).toBe(5)
|
||||
expect(findMaxRecursion(positiveArray1, 0, positiveArray1.length - 1)).toBe(
|
||||
100
|
||||
)
|
||||
})
|
||||
|
||||
it('Testing with negative arrays', () => {
|
||||
expect(findMaxRecursion(negativeArray, 0, negativeArray.length - 1)).toBe(
|
||||
-1
|
||||
)
|
||||
expect(findMaxRecursion(negativeArray1, 0, negativeArray1.length - 1)).toBe(
|
||||
-10
|
||||
)
|
||||
})
|
||||
|
||||
it('Testing with positive and negative arrays', () => {
|
||||
expect(
|
||||
findMaxRecursion(
|
||||
positiveAndNegativeArray,
|
||||
0,
|
||||
positiveAndNegativeArray.length - 1
|
||||
)
|
||||
).toBe(5)
|
||||
expect(
|
||||
findMaxRecursion(
|
||||
positiveAndNegativeArray1,
|
||||
0,
|
||||
positiveAndNegativeArray1.length - 1
|
||||
)
|
||||
).toBe(100)
|
||||
})
|
||||
|
||||
it('Testing with zero arrays', () => {
|
||||
expect(findMaxRecursion(zeroArray, 0, zeroArray.length - 1)).toBe(0)
|
||||
})
|
||||
|
||||
it('Testing with empty arrays', () => {
|
||||
expect(findMaxRecursion(emptyArray, 0, emptyArray.length - 1)).toBe(
|
||||
undefined
|
||||
)
|
||||
})
|
||||
})
|
||||
import { findMaxRecursion } from '../FindMaxRecursion'
|
||||
|
||||
describe('Test findMaxRecursion function', () => {
|
||||
const positiveAndNegativeArray = [1, 2, 4, 5, -1, -2, -4, -5]
|
||||
const positiveAndNegativeArray1 = [10, 40, 100, 20, -10, -40, -100, -20]
|
||||
|
||||
const positiveArray = [1, 2, 4, 5]
|
||||
const positiveArray1 = [10, 40, 100, 20]
|
||||
|
||||
const negativeArray = [-1, -2, -4, -5]
|
||||
const negativeArray1 = [-10, -40, -100, -20]
|
||||
|
||||
const zeroArray = [0, 0, 0, 0]
|
||||
const emptyArray = []
|
||||
|
||||
it('Testing with positive arrays', () => {
|
||||
expect(findMaxRecursion(positiveArray, 0, positiveArray.length - 1)).toBe(5)
|
||||
expect(findMaxRecursion(positiveArray1, 0, positiveArray1.length - 1)).toBe(
|
||||
100
|
||||
)
|
||||
})
|
||||
|
||||
it('Testing with negative arrays', () => {
|
||||
expect(findMaxRecursion(negativeArray, 0, negativeArray.length - 1)).toBe(
|
||||
-1
|
||||
)
|
||||
expect(findMaxRecursion(negativeArray1, 0, negativeArray1.length - 1)).toBe(
|
||||
-10
|
||||
)
|
||||
})
|
||||
|
||||
it('Testing with positive and negative arrays', () => {
|
||||
expect(
|
||||
findMaxRecursion(
|
||||
positiveAndNegativeArray,
|
||||
0,
|
||||
positiveAndNegativeArray.length - 1
|
||||
)
|
||||
).toBe(5)
|
||||
expect(
|
||||
findMaxRecursion(
|
||||
positiveAndNegativeArray1,
|
||||
0,
|
||||
positiveAndNegativeArray1.length - 1
|
||||
)
|
||||
).toBe(100)
|
||||
})
|
||||
|
||||
it('Testing with zero arrays', () => {
|
||||
expect(findMaxRecursion(zeroArray, 0, zeroArray.length - 1)).toBe(0)
|
||||
})
|
||||
|
||||
it('Testing with empty arrays', () => {
|
||||
expect(findMaxRecursion(emptyArray, 0, emptyArray.length - 1)).toBe(
|
||||
undefined
|
||||
)
|
||||
})
|
||||
})
|
||||
|
@ -16,16 +16,19 @@ describe('FindMinIterator', () => {
|
||||
expect(FindMinIterator([-1, 10])).toBe(-1)
|
||||
expect(FindMinIterator([0, 100])).toBe(0)
|
||||
expect(FindMinIterator([100, 0])).toBe(0)
|
||||
expect(FindMinIterator([100, 50, 20, 0, -100, 0, 2, 30, 45, 99, 104, 23])).toBe(-100)
|
||||
expect(
|
||||
FindMinIterator([100, 50, 20, 0, -100, 0, 2, 30, 45, 99, 104, 23])
|
||||
).toBe(-100)
|
||||
})
|
||||
|
||||
test('given empty generator then min is undefined', () => {
|
||||
const src = function* () { } // eslint-disable-line
|
||||
const src = function* () {} // eslint-disable-line
|
||||
expect(FindMinIterator(src())).toBeUndefined()
|
||||
})
|
||||
|
||||
test('given generator then min is found', () => {
|
||||
const src = function* () { // eslint-disable-line
|
||||
const src = function* () {
|
||||
// eslint-disable-line
|
||||
yield 1
|
||||
yield -1
|
||||
yield 0
|
||||
@ -34,12 +37,13 @@ describe('FindMinIterator', () => {
|
||||
})
|
||||
|
||||
test('given string generator then min string length is found', () => {
|
||||
const src = function* () { // eslint-disable-line
|
||||
const src = function* () {
|
||||
// eslint-disable-line
|
||||
yield 'abc'
|
||||
yield 'de'
|
||||
yield 'qwerty'
|
||||
}
|
||||
expect(FindMinIterator(src(), _x => _x.length)).toBe(2)
|
||||
expect(FindMinIterator(src(), (_x) => _x.length)).toBe(2)
|
||||
})
|
||||
|
||||
test('given array of objects then min accessor is found', () => {
|
||||
@ -48,7 +52,7 @@ describe('FindMinIterator', () => {
|
||||
{ name: 'Item #2', price: 0.0 },
|
||||
{ name: 'Item #3', price: -1.0 }
|
||||
]
|
||||
expect(FindMinIterator(array, _x => _x.price)).toBe(-1)
|
||||
expect(FindMinIterator(array, _x => _x.name)).toBe('Item #1')
|
||||
expect(FindMinIterator(array, (_x) => _x.price)).toBe(-1)
|
||||
expect(FindMinIterator(array, (_x) => _x.name)).toBe('Item #1')
|
||||
})
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { GetEuclidGCD } from '../GetEuclidGCD'
|
||||
|
||||
function testEuclidGCD (n, m, expected) {
|
||||
function testEuclidGCD(n, m, expected) {
|
||||
test('Testing on ' + n + ' and ' + m + '!', () => {
|
||||
expect(GetEuclidGCD(n, m)).toBe(expected)
|
||||
})
|
||||
|
@ -1,19 +1,29 @@
|
||||
import { hexagonalNumber } from '../HexagonalNumber'
|
||||
|
||||
const expectedValuesArray = [1, 6, 15, 28, 45, 66, 91, 120, 153, 190, 231, 276, 325, 378, 435, 496, 561, 630, 703, 780, 861, 946]
|
||||
const expectedValuesArray = [
|
||||
1, 6, 15, 28, 45, 66, 91, 120, 153, 190, 231, 276, 325, 378, 435, 496, 561,
|
||||
630, 703, 780, 861, 946
|
||||
]
|
||||
|
||||
describe('Testing hexagonalNumber', () => {
|
||||
for (let i = 1; i <= 22; i++) {
|
||||
it('Testing for number = ' + i + ', should return ' + expectedValuesArray[i], () => {
|
||||
expect(hexagonalNumber(i)).toBe(expectedValuesArray[i - 1])
|
||||
})
|
||||
it(
|
||||
'Testing for number = ' + i + ', should return ' + expectedValuesArray[i],
|
||||
() => {
|
||||
expect(hexagonalNumber(i)).toBe(expectedValuesArray[i - 1])
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
it('should throw error when supplied negative numbers', () => {
|
||||
expect(() => { hexagonalNumber(-1) }).toThrow(Error)
|
||||
expect(() => {
|
||||
hexagonalNumber(-1)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should throw error when supplied zero', () => {
|
||||
expect(() => { hexagonalNumber(0) }).toThrow(Error)
|
||||
expect(() => {
|
||||
hexagonalNumber(0)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
})
|
||||
|
@ -17,9 +17,12 @@ describe('isDivisible', () => {
|
||||
[5, -0, false]
|
||||
]
|
||||
|
||||
test.each(testCases)('if parameters are (%i, %i) it returns %p', (dividend, divisor, expected) => {
|
||||
expect(isDivisible(dividend, divisor)).toBe(expected)
|
||||
})
|
||||
test.each(testCases)(
|
||||
'if parameters are (%i, %i) it returns %p',
|
||||
(dividend, divisor, expected) => {
|
||||
expect(isDivisible(dividend, divisor)).toBe(expected)
|
||||
}
|
||||
)
|
||||
|
||||
const errorCases = [
|
||||
[NaN, NaN],
|
||||
@ -31,9 +34,12 @@ describe('isDivisible', () => {
|
||||
[false, 2]
|
||||
]
|
||||
|
||||
test.each(errorCases)('throws an error if parameters are (%p, %p)', (dividend, divisor) => {
|
||||
expect(() => {
|
||||
isDivisible(dividend, divisor)
|
||||
}).toThrow()
|
||||
})
|
||||
test.each(errorCases)(
|
||||
'throws an error if parameters are (%p, %p)',
|
||||
(dividend, divisor) => {
|
||||
expect(() => {
|
||||
isDivisible(dividend, divisor)
|
||||
}).toThrow()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -1,6 +1,11 @@
|
||||
import { isPronic } from '../IsPronic'
|
||||
|
||||
const pronicNumbers = [0, 2, 6, 12, 20, 30, 42, 56, 72, 90, 110, 132, 156, 182, 210, 240, 272, 306, 342, 380, 420, 462, 506, 552, 600, 650, 702, 756, 812, 870, 930, 992, 1056, 1122, 1190, 1260, 1332, 1406, 1482, 1560, 1640, 1722, 1806, 1892, 1980, 2070, 2162, 2256, 2352, 2450, 2550]
|
||||
const pronicNumbers = [
|
||||
0, 2, 6, 12, 20, 30, 42, 56, 72, 90, 110, 132, 156, 182, 210, 240, 272, 306,
|
||||
342, 380, 420, 462, 506, 552, 600, 650, 702, 756, 812, 870, 930, 992, 1056,
|
||||
1122, 1190, 1260, 1332, 1406, 1482, 1560, 1640, 1722, 1806, 1892, 1980, 2070,
|
||||
2162, 2256, 2352, 2450, 2550
|
||||
]
|
||||
|
||||
describe('Testing isPronic function', () => {
|
||||
for (let i = 0; i <= 2500; i++) {
|
||||
|
File diff suppressed because one or more lines are too long
@ -3,7 +3,10 @@ import { PrimeCheck } from '../PrimeCheck'
|
||||
|
||||
describe('LinearSieve', () => {
|
||||
it('should return primes below 100', () => {
|
||||
expect(LinearSieve(100)).toEqual([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97])
|
||||
expect(LinearSieve(100)).toEqual([
|
||||
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67,
|
||||
71, 73, 79, 83, 89, 97
|
||||
])
|
||||
})
|
||||
|
||||
it('should return primes only', () => {
|
||||
|
@ -1,19 +1,32 @@
|
||||
import { liouvilleFunction } from '../LiouvilleFunction'
|
||||
|
||||
const expectedValuesArray = [1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1]
|
||||
const expectedValuesArray = [
|
||||
1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1,
|
||||
-1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1,
|
||||
-1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1,
|
||||
-1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1,
|
||||
-1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1
|
||||
]
|
||||
|
||||
describe('Testing liouville function', () => {
|
||||
for (let i = 1; i <= 100; i++) {
|
||||
it('Testing for number = ' + i + ', should return ' + expectedValuesArray[i], () => {
|
||||
expect(liouvilleFunction(i)).toBe(expectedValuesArray[i - 1])
|
||||
})
|
||||
it(
|
||||
'Testing for number = ' + i + ', should return ' + expectedValuesArray[i],
|
||||
() => {
|
||||
expect(liouvilleFunction(i)).toBe(expectedValuesArray[i - 1])
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
it('should throw error when supplied negative numbers', () => {
|
||||
expect(() => { liouvilleFunction(-1) }).toThrow(Error)
|
||||
expect(() => {
|
||||
liouvilleFunction(-1)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should throw error when supplied zero', () => {
|
||||
expect(() => { liouvilleFunction(0) }).toThrow(Error)
|
||||
expect(() => {
|
||||
liouvilleFunction(0)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
})
|
||||
|
@ -1,16 +1,22 @@
|
||||
import { integralEvaluation } from '../MidpointIntegration'
|
||||
|
||||
test('Should return the integral of f(x) = sqrt(x) in [1, 3] to be equal 2.797434', () => {
|
||||
const result = integralEvaluation(10000, 1, 3, (x) => { return Math.sqrt(x) })
|
||||
const result = integralEvaluation(10000, 1, 3, (x) => {
|
||||
return Math.sqrt(x)
|
||||
})
|
||||
expect(Number(result.toPrecision(6))).toBe(2.79743)
|
||||
})
|
||||
|
||||
test('Should return the integral of f(x) = sqrt(x) + x^2 in [1, 3] to be equal 11.46410161', () => {
|
||||
const result = integralEvaluation(10000, 1, 3, (x) => { return Math.sqrt(x) + Math.pow(x, 2) })
|
||||
const result = integralEvaluation(10000, 1, 3, (x) => {
|
||||
return Math.sqrt(x) + Math.pow(x, 2)
|
||||
})
|
||||
expect(Number(result.toPrecision(10))).toBe(11.46410161)
|
||||
})
|
||||
|
||||
test('Should return the integral of f(x) = log(x) + Pi*x^3 in [5, 12] to be equal 15809.9141543', () => {
|
||||
const result = integralEvaluation(20000, 5, 12, (x) => { return Math.log(x) + Math.PI * Math.pow(x, 3) })
|
||||
const result = integralEvaluation(20000, 5, 12, (x) => {
|
||||
return Math.log(x) + Math.PI * Math.pow(x, 3)
|
||||
})
|
||||
expect(Number(result.toPrecision(10))).toBe(15809.91415)
|
||||
})
|
||||
|
@ -1,19 +1,32 @@
|
||||
import { mobiusFunction } from '../MobiusFunction'
|
||||
|
||||
const expectedValuesArray = [1, -1, -1, 0, -1, 1, -1, 0, 0, 1, -1, 0, -1, 1, 1, 0, -1, 0, -1, 0, 1, 1, -1, 0, 0, 1, 0, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 0, -1, -1, -1, 0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 1, 0, 1, 1, -1, 0, -1, 1, 0, 0, 1, -1, -1, 0, 1, -1, -1, 0, -1, 1, 0, 0, 1, -1, -1, 0, 0, 1, -1, 0, 1, 1, 1, 0, -1, 0, 1, 0, 1, 1, 1, 0, -1, 0, 0, 0]
|
||||
const expectedValuesArray = [
|
||||
1, -1, -1, 0, -1, 1, -1, 0, 0, 1, -1, 0, -1, 1, 1, 0, -1, 0, -1, 0, 1, 1, -1,
|
||||
0, 0, 1, 0, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 0, -1, -1, -1, 0, 0, 1,
|
||||
-1, 0, 0, 0, 1, 0, -1, 0, 1, 0, 1, 1, -1, 0, -1, 1, 0, 0, 1, -1, -1, 0, 1, -1,
|
||||
-1, 0, -1, 1, 0, 0, 1, -1, -1, 0, 0, 1, -1, 0, 1, 1, 1, 0, -1, 0, 1, 0, 1, 1,
|
||||
1, 0, -1, 0, 0, 0
|
||||
]
|
||||
|
||||
describe('Testing mobius function', () => {
|
||||
for (let i = 1; i <= 100; i++) {
|
||||
it('Testing for number = ' + i + ', should return ' + expectedValuesArray[i], () => {
|
||||
expect(mobiusFunction(i)).toBe(expectedValuesArray[i - 1])
|
||||
})
|
||||
it(
|
||||
'Testing for number = ' + i + ', should return ' + expectedValuesArray[i],
|
||||
() => {
|
||||
expect(mobiusFunction(i)).toBe(expectedValuesArray[i - 1])
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
it('should throw error when supplied negative numbers', () => {
|
||||
expect(() => { mobiusFunction(-1) }).toThrow(Error)
|
||||
expect(() => {
|
||||
mobiusFunction(-1)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
|
||||
it('should throw error when supplied zero', () => {
|
||||
expect(() => { mobiusFunction(0) }).toThrow(Error)
|
||||
expect(() => {
|
||||
mobiusFunction(0)
|
||||
}).toThrow(Error)
|
||||
})
|
||||
})
|
||||
|
@ -14,7 +14,10 @@ describe('NumberOfDigits', () => {
|
||||
[123423232, 9],
|
||||
[-123423232, 9],
|
||||
[9999, 4]
|
||||
])('should return the correct number of digits in an integer', (value, expected) => {
|
||||
expect(numberOfDigitsUsingLog(value)).toBe(expected)
|
||||
})
|
||||
])(
|
||||
'should return the correct number of digits in an integer',
|
||||
(value, expected) => {
|
||||
expect(numberOfDigitsUsingLog(value)).toBe(expected)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { PalindromeRecursive, PalindromeIterative, checkPalindrome } from '../Palindrome'
|
||||
import {
|
||||
PalindromeRecursive,
|
||||
PalindromeIterative,
|
||||
checkPalindrome
|
||||
} from '../Palindrome'
|
||||
|
||||
describe('Palindrome', () => {
|
||||
it('should return true for a palindrome for PalindromeRecursive', () => {
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { factorial, permutation, combination } from '../PermutationAndCombination'
|
||||
import {
|
||||
factorial,
|
||||
permutation,
|
||||
combination
|
||||
} from '../PermutationAndCombination'
|
||||
|
||||
describe('Factorial', () => {
|
||||
it('factorial(5)', () => {
|
||||
|
@ -5,7 +5,7 @@ describe('should return an array of prime numbers', () => {
|
||||
it('should have each element in the array as a prime numbers', () => {
|
||||
const n = 100
|
||||
const primes = sieveOfEratosthenes(n)
|
||||
primes.forEach(prime => {
|
||||
primes.forEach((prime) => {
|
||||
expect(PrimeCheck(prime)).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
@ -1,16 +1,22 @@
|
||||
import { integralEvaluation } from '../SimpsonIntegration'
|
||||
|
||||
test('Should return the integral of f(x) = sqrt(x) in [1, 3] to be equal 2.797434', () => {
|
||||
const result = integralEvaluation(16, 1, 3, (x) => { return Math.sqrt(x) })
|
||||
const result = integralEvaluation(16, 1, 3, (x) => {
|
||||
return Math.sqrt(x)
|
||||
})
|
||||
expect(Number(result.toPrecision(7))).toBe(2.797434)
|
||||
})
|
||||
|
||||
test('Should return the integral of f(x) = sqrt(x) + x^2 in [1, 3] to be equal 11.46410161', () => {
|
||||
const result = integralEvaluation(64, 1, 3, (x) => { return Math.sqrt(x) + Math.pow(x, 2) })
|
||||
const result = integralEvaluation(64, 1, 3, (x) => {
|
||||
return Math.sqrt(x) + Math.pow(x, 2)
|
||||
})
|
||||
expect(Number(result.toPrecision(10))).toBe(11.46410161)
|
||||
})
|
||||
|
||||
test('Should return the integral of f(x) = log(x) + Pi*x^3 in [5, 12] to be equal 15809.9141543', () => {
|
||||
const result = integralEvaluation(128, 5, 12, (x) => { return Math.log(x) + Math.PI * Math.pow(x, 3) })
|
||||
const result = integralEvaluation(128, 5, 12, (x) => {
|
||||
return Math.log(x) + Math.PI * Math.pow(x, 3)
|
||||
})
|
||||
expect(Number(result.toPrecision(12))).toBe(15809.9141543)
|
||||
})
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { sumOfDigitsUsingLoop, sumOfDigitsUsingRecursion, sumOfDigitsUsingString } from '../SumOfDigits'
|
||||
import {
|
||||
sumOfDigitsUsingLoop,
|
||||
sumOfDigitsUsingRecursion,
|
||||
sumOfDigitsUsingString
|
||||
} from '../SumOfDigits'
|
||||
|
||||
test('Testing on sumOfDigitsUsingLoop', () => {
|
||||
const sum = sumOfDigitsUsingLoop(123)
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { factorialize } from '../WhileLoopFactorial'
|
||||
|
||||
function testFactorial (n, expected) {
|
||||
function testFactorial(n, expected) {
|
||||
test('Testing on ' + n + '!', () => {
|
||||
expect(factorialize(n)).toBe(expected)
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { zellersCongruenceAlgorithm } from '../ZellersCongruenceAlgorithm'
|
||||
|
||||
function testZeller (day, month, year, expected) {
|
||||
function testZeller(day, month, year, expected) {
|
||||
test('Testing on ' + day + '/' + month + '/' + year, () => {
|
||||
expect(zellersCongruenceAlgorithm(day, month, year)).toBe(expected)
|
||||
})
|
||||
|
Reference in New Issue
Block a user