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:
Roland Hummel
2023-10-03 23:08:19 +02:00
committed by GitHub
parent 0ca18c2b2c
commit 86d333ee94
392 changed files with 5849 additions and 16622 deletions

View File

@ -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
}

View File

@ -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,

View File

@ -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
}
}

View File

@ -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) {

View File

@ -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')
}

View File

@ -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 }

View File

@ -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.

View File

@ -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) {

View File

@ -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) => {

View File

@ -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

View File

@ -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]')
}

View File

@ -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
}

View File

@ -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 }

View File

@ -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

View File

@ -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)

View File

@ -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]
}
}

View File

@ -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 }

View File

@ -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 }

View File

@ -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 }

View File

@ -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()
}
}

View File

@ -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)) {

View File

@ -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')
}

View File

@ -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 }

View File

@ -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

View File

@ -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)
}

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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 }

View File

@ -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
}

View File

@ -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
}

View File

@ -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)

View File

@ -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 }

View File

@ -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 }

View File

@ -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 }

View File

@ -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++
}

View File

@ -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 }

View File

@ -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 }

View File

@ -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)

View File

@ -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
}

View File

@ -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 }

View File

@ -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
}

View File

@ -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)

View File

@ -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
}
}

View File

@ -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

View File

@ -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
}

View File

@ -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) => {

View File

@ -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)

View File

@ -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
}

View File

@ -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 }

View File

@ -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) {

View File

@ -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
}

View File

@ -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',

View File

@ -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')
}

View File

@ -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)
})
})

View File

@ -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)
})

View File

@ -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', () => {

View File

@ -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)
}
)
})

View File

@ -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
}

View File

@ -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 }
])
})
})

View File

@ -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')
)
})
})

View File

@ -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', () => {

View File

@ -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)
}
)
})

View File

@ -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', () => {

View File

@ -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
)
})
})

View File

@ -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')
})
})

View File

@ -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)
})

View File

@ -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)
})
})

View File

@ -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()
}
)
})

View File

@ -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

View File

@ -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', () => {

View File

@ -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)
})
})

View File

@ -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)
})

View File

@ -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)
})
})

View File

@ -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)
}
)
})

View File

@ -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', () => {

View File

@ -1,4 +1,8 @@
import { factorial, permutation, combination } from '../PermutationAndCombination'
import {
factorial,
permutation,
combination
} from '../PermutationAndCombination'
describe('Factorial', () => {
it('factorial(5)', () => {

View File

@ -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()
})
})

View File

@ -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)
})

View File

@ -1,4 +1,8 @@
import { sumOfDigitsUsingLoop, sumOfDigitsUsingRecursion, sumOfDigitsUsingString } from '../SumOfDigits'
import {
sumOfDigitsUsingLoop,
sumOfDigitsUsingRecursion,
sumOfDigitsUsingString
} from '../SumOfDigits'
test('Testing on sumOfDigitsUsingLoop', () => {
const sum = sumOfDigitsUsingLoop(123)

View File

@ -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)
})

View File

@ -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)
})