├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ ├── feature_request.yml │ └── other.yml ├── dependabot.yml ├── pull_request_template.md ├── stale.yml └── workflows │ ├── Ci.yml │ ├── UpdateDirectory.js │ ├── UpdateDirectory.yml │ └── UploadCoverageReport.yml ├── .gitignore ├── .gitpod.yml ├── .husky └── pre-commit ├── .prettierignore ├── .prettierrc ├── Backtracking ├── AllCombinationsOfSizeK.js ├── GeneratePermutations.js ├── KnightTour.js ├── MColoringProblem.js ├── NQueens.js ├── RatInAMaze.js ├── Sudoku.js ├── SumOfSubset.js ├── generateParentheses.js └── tests │ ├── AllCombinationsOfSizeK.test.js │ ├── GenerateParentheses.test.js │ ├── GeneratePermutations.test.js │ ├── KnightTour.test.js │ ├── MColoringProblem.test.js │ ├── NQueens.test.js │ ├── RatInAMaze.test.js │ ├── Sudoku.test.js │ └── SumOfSubset.test.js ├── Bit-Manipulation ├── BinaryCountSetBits.js ├── GenerateSubSets.js ├── GrayCodes.js ├── IsPowerOfTwo.js ├── IsPowerofFour.js ├── LogTwo.js ├── NextPowerOfTwo.js ├── SetBit.js ├── UniqueElementInAnArray.js └── test │ ├── BinaryCountSetBits.test.js │ ├── GenerateSubSets.test.js │ ├── GrayCodes.test.js │ ├── IsPowerOfFour.test.js │ ├── IsPowerOfTwo.test.js │ ├── LogTwo.test.js │ ├── NextPowerOfTwo.test.js │ ├── SetBit.test.js │ └── UniqueElementInAnArray.test.js ├── CONTRIBUTING.md ├── Cache ├── LFUCache.js ├── LRUCache.js ├── Memoize.js └── test │ ├── LFUCache.test.js │ ├── LRUCache.test.js │ ├── Memoize.test.js │ └── cacheTest.js ├── Cellular-Automata ├── ConwaysGameOfLife.js ├── Elementary.js └── test │ ├── ConwaysGameOfLife.test.js │ └── Elementary.test.js ├── Ciphers ├── AffineCipher.js ├── Atbash.js ├── CaesarCipher.js ├── KeyFinder.js ├── KeywordShiftedAlphabet.js ├── MorseCode.js ├── ROT13.js ├── VigenereCipher.js ├── XORCipher.js └── test │ ├── AffineCipher.test.js │ ├── Atbash.test.js │ ├── CaesarCipher.test.js │ ├── KeywordShiftedAlphabet.test.js │ ├── MorseCode.test.js │ ├── ROT13.test.js │ ├── VigenereCipher.test.js │ └── XORCipher.test.js ├── Compression ├── RLE.js └── test │ └── RLE.test.js ├── Conversions ├── ArbitraryBase.js ├── ArrayBufferToBase64.js ├── Base64ToArrayBuffer.js ├── BinaryToDecimal.js ├── BinaryToHex.js ├── DateDayDifference.js ├── DateToDay.js ├── DecimalToBinary.js ├── DecimalToHex.js ├── DecimalToOctal.js ├── DecimalToRoman.js ├── HexToBinary.js ├── HexToDecimal.js ├── HexToRGB.js ├── LengthConversion.js ├── LitersToImperialGallons.js ├── LitersToUSGallons.js ├── LowerCaseConversion.js ├── MeterToFeetConversion.js ├── OctToDecimal.js ├── OuncesToKilograms.js ├── RGBToHex.js ├── RailwayTimeConversion.js ├── RgbHslConversion.js ├── RgbHsvConversion.js ├── RomanToDecimal.js ├── TemperatureConversion.js ├── TitleCaseConversion.js ├── UpperCaseConversion.js └── test │ ├── ArbitraryBase.test.js │ ├── ArrayBufferToBase64.test.js │ ├── Base64ToArrayBuffer.test.js │ ├── BinaryToDecimal.test.js │ ├── BinaryToHex.test.js │ ├── DateDayDiffernce.test.js │ ├── DateToDay.test.js │ ├── DecimalToBinary.test.js │ ├── DecimalToHex.test.js │ ├── DecimalToOctal.test.js │ ├── DecimalToRoman.test.js │ ├── HexToBinary.test.js │ ├── HexToDecimal.test.js │ ├── HexToRGB.test.js │ ├── LengthConversion.test.js │ ├── LitersToImperialGallons.test.js │ ├── LitersToUSGallons.test.js │ ├── LowerCaseConversion.test.js │ ├── MeterToFeetConversion.test.js │ ├── OctToDecimal.test.js │ ├── OuncesToKilogram.test.js │ ├── RGBToHex.test.js │ ├── RailwayTimeConversion.test.js │ ├── RgbHslConversion.test.js │ ├── RgbHsvConversion.test.js │ ├── RomanToDecimal.test.js │ ├── TemperatureConversion.test.js │ ├── TitleCaseConversion.test.js │ └── UpperCaseConverstion.test.js ├── DIRECTORY.md ├── Data-Structures ├── Array │ ├── LocalMaximomPoint.js │ ├── NumberOfLocalMaximumPoints.js │ ├── QuickSelect.js │ ├── Reverse.js │ └── test │ │ ├── LocalMaximomPoint.test.js │ │ ├── NumberOfLocalMaximumPoints.test.js │ │ ├── QuickSelect.test.js │ │ └── Reverse.test.js ├── Graph │ ├── Graph.js │ ├── Graph2.js │ ├── Graph3.js │ └── test │ │ ├── Graph2.test.js │ │ └── Graph3.test.js ├── Heap │ ├── BinaryHeap.js │ ├── KeyPriorityQueue.js │ ├── MinPriorityQueue.js │ └── test │ │ ├── BinaryHeap.test.js │ │ ├── KeyPriorityQueue.test.js │ │ └── MinPriorityQueue.test.js ├── Linked-List │ ├── AddTwoNumbers.js │ ├── CycleDetection.js │ ├── CycleDetectionII.js │ ├── DoublyLinkedList.js │ ├── MergeTwoSortedLinkedLists.js │ ├── ReverseSinglyLinkedList.js │ ├── SinglyCircularLinkedList.js │ ├── SinglyLinkedList.js │ └── test │ │ ├── AddTwoNumbers.test.js │ │ ├── CycleDetection.test.js │ │ ├── CycleDetectionII.test.js │ │ ├── DoublyLinkedList.test.js │ │ ├── MergeTwoSortedLinkedLists.test.js │ │ ├── ReverseSinglyLinkedList.test.js │ │ ├── SinglyCircularLinkedList.test.js │ │ └── SinglyLinkedList.test.js ├── Queue │ ├── CircularQueue.js │ ├── Queue.js │ ├── QueueUsing2Stacks.js │ └── test │ │ ├── Queue.test.js │ │ └── QueueUsing2Stacks.test.js ├── Stack │ ├── EvaluateExpression.js │ ├── Stack.js │ ├── StackES6.js │ └── test │ │ └── EvaluateExpression.test.js ├── Tree │ ├── AVLTree.js │ ├── BinarySearchTree.js │ ├── SegmentTree.js │ ├── Trie.js │ └── test │ │ ├── AVLTree.test.js │ │ ├── BinarySearchTree.test.js │ │ └── SegmentTree.test.js └── Vectors │ ├── Vector2.js │ └── test │ └── Vector2.test.js ├── Dynamic-Programming ├── Abbreviation.js ├── CatalanNumbers.js ├── ClimbingStairs.js ├── CoinChange.js ├── EditDistance.js ├── FastFibonacciNumber.js ├── FibonacciNumber.js ├── FindMonthCalendar.js ├── KadaneAlgo.js ├── LevenshteinDistance.js ├── LongestCommonSubsequence.js ├── LongestIncreasingSubsequence.js ├── LongestPalindromicSubsequence.js ├── LongestValidParentheses.js ├── MaxNonAdjacentSum.js ├── MaxProductOfThree.js ├── MinimumCostPath.js ├── NumberOfSubsetEqualToGivenSum.js ├── RodCutting.js ├── Shuf.js ├── SieveOfEratosthenes.js ├── Sliding-Window │ ├── HouseRobber.js │ ├── LongestSubstringWithoutRepeatingCharacters.js │ ├── MaxConsecutiveOnes.js │ ├── MaxConsecutiveOnesIII.js │ ├── PermutationinString.js │ └── test │ │ ├── HouseRobber.test.js │ │ ├── LongestSubstringWithoutRepeatingCharacters.test.js │ │ ├── MaxConsecutiveOnes.test.js │ │ ├── MaxConsecutiveOnesIII.test.js │ │ └── PermutationinString.test.js ├── SudokuSolver.js ├── TrappingRainWater.js ├── TribonacciNumber.js ├── UniquePaths.js ├── UniquePaths2.js ├── ZeroOneKnapsack.js └── tests │ ├── Abbreviation.test.js │ ├── CatalanNumbers.test.js │ ├── ClimbingStairs.test.js │ ├── CoinChange.test.js │ ├── EditDistance.test.js │ ├── FastFibonacciNumber.test.js │ ├── FibonacciNumber.test.js │ ├── KadaneAlgo.test.js │ ├── LevenshteinDistance.test.js │ ├── LongestCommonSubsequence.test.js │ ├── LongestIncreasingSubsequence.test.js │ ├── LongestPalindromicSubsequence.test.js │ ├── LongestValidParentheses.test.js │ ├── MaxProductOfThree.test.js │ ├── NumberOfSubsetEqualToGivenSum.test.js │ ├── RodCutting.test.js │ ├── SieveOfEratosthenes.test.js │ ├── TrappingRainWater.test.js │ ├── TribonacciNumber.test.js │ ├── UniquePaths.test.js │ ├── UniquePaths2.test.js │ └── ZeroOneKnapsack.test.js ├── Geometry ├── Circle.js ├── Cone.js ├── ConvexHullGraham.js ├── Pyramid.js ├── Sphere.js └── Test │ ├── Circle.test.js │ ├── Cone.test.js │ ├── ConvexHullGraham.test.js │ ├── Pyramid.test.js │ └── Sphere.test.js ├── Graphs ├── BellmanFord.js ├── BinaryLifting.js ├── BreadthFirstSearch.js ├── BreadthFirstShortestPath.js ├── ConnectedComponents.js ├── Density.js ├── DepthFirstSearchIterative.js ├── DepthFirstSearchRecursive.js ├── Dijkstra.js ├── DijkstraSmallestPath.js ├── FloydWarshall.js ├── Kosaraju.js ├── KruskalMST.js ├── LCABinaryLifting.js ├── NodeNeighbors.js ├── NumberOfIslands.js ├── PrimMST.js └── test │ ├── BellmanFord.test.js │ ├── BinaryLifting.test.js │ ├── BreadthFirstSearch.test.js │ ├── BreadthFirstShortestPath.test.js │ ├── Kosaraju.test.js │ ├── LCABinaryLifting.test.js │ ├── NumberOfIslands.test.js │ └── PrimMST.test.js ├── Hashes ├── MD5.js ├── SHA1.js ├── SHA256.js └── tests │ ├── MD5.test.js │ ├── SHA1.test.js │ └── SHA256.test.js ├── LICENSE ├── Maths ├── Abs.js ├── AliquotSum.js ├── Area.js ├── ArithmeticGeometricMean.js ├── ArmstrongNumber.js ├── AutomorphicNumber.js ├── AverageMean.js ├── AverageMedian.js ├── BinaryConvert.js ├── BinaryExponentiationIterative.js ├── BinaryExponentiationRecursive.js ├── BinomialCoefficient.js ├── BisectionMethod.js ├── CheckKishnamurthyNumber.js ├── CircularArc.js ├── CoPrimeCheck.js ├── CollatzSequence.js ├── Coordinate.js ├── CountNumbersDivisible.js ├── DecimalExpansion.js ├── DecimalIsolate.js ├── DegreeToRadian.js ├── Determinant.js ├── EuclideanDistance.js ├── EulerMethod.js ├── EulersTotient.js ├── EulersTotientFunction.js ├── ExponentialFunction.js ├── ExtendedEuclideanGCD.js ├── Factorial.js ├── Factors.js ├── FareyApproximation.js ├── FermatPrimalityTest.js ├── Fibonacci.js ├── FigurateNumber.js ├── FindHcf.js ├── FindLcm.js ├── FindMaxRecursion.js ├── FindMin.js ├── FindMinIterator.js ├── FriendlyNumbers.js ├── GetEuclidGCD.js ├── GridGet.js ├── HexagonalNumber.js ├── IntToBase.js ├── IsDivisible.js ├── IsEven.js ├── IsOdd.js ├── IsPronic.js ├── IsSquareFree.js ├── JugglerSequence.js ├── LeapYear.js ├── LinearSieve.js ├── LiouvilleFunction.js ├── LucasSeries.js ├── Mandelbrot.js ├── MatrixExponentiationRecursive.js ├── MatrixMultiplication.js ├── MeanAbsoluteDeviation.js ├── MeanSquareError.js ├── MidpointIntegration.js ├── MobiusFunction.js ├── ModularArithmetic.js ├── ModularBinaryExponentiationRecursive.js ├── NumberOfDigits.js ├── Palindrome.js ├── ParityOutlier.js ├── PascalTriangle.js ├── PerfectCube.js ├── PerfectNumber.js ├── PerfectSquare.js ├── PermutationAndCombination.js ├── PiApproximationMonteCarlo.js ├── Polynomial.js ├── Pow.js ├── PowLogarithmic.js ├── PrimeCheck.js ├── PrimeFactors.js ├── QuadraticRoots.js ├── RadianToDegree.js ├── ReverseNumber.js ├── ReversePolishNotation.js ├── RowEchelon.js ├── ShorsAlgorithm.js ├── SieveOfEratosthenes.js ├── Signum.js ├── SimpsonIntegration.js ├── Softmax.js ├── SquareRoot.js ├── SquareRootLogarithmic.js ├── SumOfDigits.js ├── SumOfGeometricProgression.js ├── TwoSum.js ├── Volume.js ├── WhileLoopFactorial.js ├── ZellersCongruenceAlgorithm.js ├── isPalindromeIntegerNumber.js └── test │ ├── Abs.test.js │ ├── AliquotSum.test.js │ ├── Area.test.js │ ├── ArithmeticGeometricMean.test.js │ ├── ArmstrongNumber.test.js │ ├── AutomorphicNumber.test.js │ ├── AverageMean.test.js │ ├── AverageMedian.test.js │ ├── BInaryConvert.test.js │ ├── BinaryExponentiationIterative.test.js │ ├── BinaryExponentiationRecursive.test.js │ ├── BinomialCoefficient.test.js │ ├── BisectionMethod.test.js │ ├── CheckKishnamurthyNumber.test.js │ ├── CircularArc.test.js │ ├── CoPrimeCheck.test.js │ ├── CollatzSequence.test.js │ ├── Coordinate.test.js │ ├── CountNumbersDivisible.test.js │ ├── DecimalExpansion.test.js │ ├── DegreeToRadian.test.js │ ├── Determinant.test.js │ ├── EuclideanDistance.test.js │ ├── EulerMethod.manual-test.js │ ├── EulerMethod.test.js │ ├── EulersTotient.test.js │ ├── EulersTotientFunction.test.js │ ├── ExponentialFunction.test.js │ ├── ExtendedEuclideanGCD.test.js │ ├── Factorial.test.js │ ├── Factors.test.js │ ├── FareyApproximation.test.js │ ├── FermatPrimalityTest.test.js │ ├── Fibonacci.test.js │ ├── FigurateNumber.test.js │ ├── FindHcf.test.js │ ├── FindLcm.test.js │ ├── FindMaxRecursion.test.js │ ├── FindMin.test.js │ ├── FindMinIterator.test.js │ ├── GetEuclidGCD.test.js │ ├── GridGet.test.js │ ├── HexagonalNumber.test.js │ ├── IntToBase.test.js │ ├── IsDivisible.test.js │ ├── IsEven.test.js │ ├── IsOdd.test.js │ ├── IsPronic.test.js │ ├── IsSquareFree.test.js │ ├── JugglerSequence.test.js │ ├── LeapYear.test.js │ ├── LinearSieve.test.js │ ├── LiouvilleFunction.test.js │ ├── LucasSeries.test.js │ ├── Mandelbrot.manual-test.js │ ├── Mandelbrot.test.js │ ├── MeanAbsoluteDeviation.test.js │ ├── MeanSquareError.test.js │ ├── MidpointIntegration.test.js │ ├── MobiusFunction.test.js │ ├── ModularArithmetic.test.js │ ├── ModularBinaryExponentiationRecursive.test.js │ ├── NumberOfDigits.test.js │ ├── Palindrome.test.js │ ├── ParityOutlier.test.js │ ├── PascalTriangle.test.js │ ├── PerfectCube.test.js │ ├── PerfectNumber.test.js │ ├── PerfectSquare.test.js │ ├── PermutationAndCombination.test.js │ ├── PiApproximationMonteCarlo.test.js │ ├── Polynomial.test.js │ ├── Pow.test.js │ ├── PowLogarithmic.test.js │ ├── PrimeCheck.test.js │ ├── PrimeFactors.test.js │ ├── QuadraticRoots.test.js │ ├── RadianToDegree.test.js │ ├── ReverseNumber.test.js │ ├── ReversePolishNotation.test.js │ ├── RowEchelon.test.js │ ├── ShorsAlgorithm.test.js │ ├── SieveOfEratosthenes.test.js │ ├── Signum.test.js │ ├── SimpsonIntegration.test.js │ ├── Softmax.test.js │ ├── SquareRoot.test.js │ ├── SquareRootLogarithmic.test.js │ ├── SumOfDigits.test.js │ ├── SumOfGeometricProgression.test.js │ ├── TwoSum.test.js │ ├── Volume.test.js │ ├── WhileLoopFactorial.test.js │ ├── ZellersCongruenceAlgorithm.test.js │ └── isPalindromeIntegerNumber.test.js ├── Navigation ├── Haversine.js └── test │ └── Haversine.test.js ├── Project-Euler ├── Problem001.js ├── Problem002.js ├── Problem003.js ├── Problem004.js ├── Problem005.js ├── Problem006.js ├── Problem007.js ├── Problem008.js ├── Problem009.js ├── Problem010.js ├── Problem011.js ├── Problem012.js ├── Problem013.js ├── Problem014.js ├── Problem015.js ├── Problem016.js ├── Problem017.js ├── Problem018.js ├── Problem019.js ├── Problem020.js ├── Problem021.js ├── Problem023.js ├── Problem025.js ├── Problem028.js ├── Problem035.js ├── Problem044.js └── test │ ├── Problem001.test.js │ ├── Problem002.test.js │ ├── Problem003.test.js │ ├── Problem004.test.js │ ├── Problem005.test.js │ ├── Problem006.test.js │ ├── Problem007.test.js │ ├── Problem008.test.js │ ├── Problem009.test.js │ ├── Problem010.test.js │ ├── Problem011.test.js │ ├── Problem012.test.js │ ├── Problem013.test.js │ ├── Problem014.test.js │ ├── Problem016.test.js │ ├── Problem017.test.js │ ├── Problem018.test.js │ ├── Problem019.test.js │ ├── Problem020.test.js │ ├── Problem021.test.js │ ├── Problem023.test.js │ ├── Problem025.test.js │ ├── Problem028.test.js │ ├── Problem035.test.js │ └── Problem044.test.js ├── README.md ├── Recursive ├── BinaryEquivalent.js ├── BinarySearch.js ├── Factorial.js ├── FibonacciNumberRecursive.js ├── FloodFill.js ├── KochSnowflake.js ├── KochSnowflake.manual-test.js ├── LetterCombination.js ├── Palindrome.js ├── PalindromePartitioning.js ├── Partition.js ├── SubsequenceRecursive.js ├── TowerOfHanoi.js └── test │ ├── BinaryEquivalent.test.js │ ├── BinarySearch.test.js │ ├── Factorial.test.js │ ├── FibonacciNumberRecursive.test.js │ ├── FloodFill.test.js │ ├── KochSnowflake.test.js │ ├── LetterCombination.test.js │ ├── Palindrome.test.js │ ├── PalindromePartitioning.test.js │ └── Partition.test.js ├── Search ├── BinarySearch.js ├── ExponentialSearch.js ├── FibonacciSearch.js ├── InterpolationSearch.js ├── JumpSearch.js ├── LinearSearch.js ├── Minesweeper.js ├── QuickSelectSearch.js ├── RabinKarp.js ├── SlidingWindow.js ├── StringSearch.js ├── TernarySearch.js ├── UnionFind.js └── test │ ├── BinarySearch.test.js │ ├── ExponentialSearch.test.js │ ├── FibonacciSearch.test.js │ ├── InterpolationSearch.test.js │ ├── LinearSearch.test.js │ ├── Minesweeper.test.js │ ├── RabinKarp.test.js │ ├── SlidingWindow.test.js │ ├── TernarySearch.test.js │ ├── UnionFind.test.js │ └── jumpSearch.test.js ├── Sorts ├── AlphaNumericalSort.js ├── BeadSort.js ├── BinaryInsertionSort.js ├── BogoSort.js ├── BubbleSort.js ├── BucketSort.js ├── CocktailShakerSort.js ├── CombSort.js ├── CountingSort.js ├── CycleSort.js ├── DutchNationalFlagSort.js ├── FindSecondLargestElement.js ├── FisherYatesShuffle.js ├── FlashSort.js ├── GnomeSort.js ├── HeapSort.js ├── HeapSortV2.js ├── InsertionSort.js ├── IntroSort.js ├── MergeSort.js ├── OddEvenSort.js ├── PancakeSort.js ├── PigeonHoleSort.js ├── QuickSort.js ├── QuickSortRecursive.js ├── RadixSort.js ├── SelectionSort.js ├── ShellSort.js ├── SimplifiedWiggleSort.js ├── StoogeSort.js ├── SwapSort.js ├── TimSort.js ├── TopologicalSort.js └── test │ ├── AlphaNumericalSort.test.js │ ├── BeadSort.test.js │ ├── BinaryInsertionSort.test.js │ ├── BogoSort.test.js │ ├── BubbleSort.test.js │ ├── BucketSort.test.js │ ├── CocktailShakerSort.test.js │ ├── CombSort.test.js │ ├── CountingSort.test.js │ ├── CycleSort.test.js │ ├── DutchNationalFlagSort.test.js │ ├── FindSecondLargestElement.test.js │ ├── FisherYatesShuffle.test.js │ ├── FlashSort.test.js │ ├── GnomeSort.test.js │ ├── HeapSort.test.js │ ├── HeapSortV2.test.js │ ├── InsertionSort.test.js │ ├── MergeSort.test.js │ ├── OddEvenSort.test.js │ ├── PancakeSort.test.js │ ├── PigeonHoleSort.test.js │ ├── QuickSort.test.js │ ├── QuickSortRecursive.test.js │ ├── RadixSort.test.js │ ├── SecondLargestElement.test.js │ ├── SelectionSort.test.js │ ├── ShellSort.test.js │ ├── SimplifiedWiggleSort.test.js │ ├── StoogeSort.test.js │ ├── SwapSort.test.js │ └── TimSort.test.js ├── String ├── AlphaNumericPalindrome.js ├── AlternativeStringArrange.js ├── BoyerMoore.js ├── CheckAnagram.js ├── CheckCamelCase.js ├── CheckExceeding.js ├── CheckFlatCase.js ├── CheckKebabCase.js ├── CheckPalindrome.js ├── CheckPangram.js ├── CheckPascalCase.js ├── CheckRearrangePalindrome.js ├── CheckSnakeCase.js ├── CheckWordOccurrence.js ├── CountLetters.js ├── CountSubstrings.js ├── CountVowels.js ├── CreatePermutations.js ├── DiceCoefficient.js ├── FirstUniqueCharacter.js ├── FormatPhoneNumber.js ├── GenerateGUID.js ├── HammingDistance.js ├── IsPalindrome.js ├── KMPPatternSearching.js ├── LengthofLongestSubstringWithoutRepetition.js ├── LevenshteinDistance.js ├── Lower.js ├── MaxCharacter.js ├── MaxWord.js ├── PatternMatching.js ├── PercentageOfLetters.js ├── PermutateString.js ├── ReverseString.js ├── ReverseWords.js ├── ScrambleStrings.js ├── Upper.js ├── ValidateCreditCard.js ├── ValidateEmail.js ├── ZFunction.js └── test │ ├── AlphaNumericPalindrome.test.js │ ├── AlternativeStringArrange.test.js │ ├── BoyerMoore.test.js │ ├── CheckAnagram.test.js │ ├── CheckCamelCase.test.js │ ├── CheckExceeding.test.js │ ├── CheckFlatCase.test.js │ ├── CheckKebabCase.test.js │ ├── CheckPalindrome.test.js │ ├── CheckPangram.test.js │ ├── CheckPascalCase.test.js │ ├── CheckRearrangePalindrome.test.js │ ├── CheckSnakeCase.test.js │ ├── CheckWordOcurrence.test.js │ ├── CountLetters.test.js │ ├── CountSubstrings.test.js │ ├── CountVowels.test.js │ ├── CreatePermutations.test.js │ ├── DiceCoefficient.test.js │ ├── FirstUniqueCharacter.test.js │ ├── FormatPhoneNumber.test.js │ ├── HammingDistance.test.js │ ├── IsPalindrome.test.js │ ├── KMPPatternSearching.test.js │ ├── LengthofLongestSubstringWithoutRepetition.test.js │ ├── LevenshteinDistance.test.js │ ├── Lower.test.js │ ├── MaxCharacter.test.js │ ├── MaxWord.test.js │ ├── PatternMatching.test.js │ ├── PercentageOfLetters.test.js │ ├── PermutateString.test.js │ ├── ReverseString.test.js │ ├── ReverseWords.test.js │ ├── ScrambleStrings.test.js │ ├── Upper.test.js │ ├── ValidateCreditCard.test.js │ ├── ValidateEmail.test.js │ └── ZFunction.test.js ├── Timing-Functions ├── GetMonthDays.js ├── IntervalTimer.js ├── ParseDate.js └── test │ ├── GetMonthDays.test.js │ └── ParseDate.test.js ├── Trees ├── BreadthFirstTreeTraversal.js ├── DepthFirstSearch.js ├── FenwickTree.js └── test │ ├── BreadthFirstTreeTraversal.test.js │ ├── DepthFirstSearch.test.js │ └── FenwickTree.test.js ├── package-lock.json ├── package.json └── vitest.config.ts /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @raklaptudirm @appgurueu 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Discord community 4 | url: https://the-algorithms.com/discord/ 5 | about: Have any questions or found any bugs? Contact us via our Discord community. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/other.yml: -------------------------------------------------------------------------------- 1 | name: Other issue 2 | description: Use this for any other issues. Do NOT create blank issues 3 | title: "[OTHER]: " 4 | labels: ["awaiting triage"] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: What would you like to share? 10 | description: Provide a clear and concise explanation of your issue. 11 | validations: 12 | required: true 13 | - type: textarea 14 | id: extrainfo 15 | attributes: 16 | label: Additional information 17 | description: Is there anything else we should know about this issue? 18 | validations: 19 | required: false 20 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Keep GitHub Actions up to date with Dependabot... 2 | # https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot 3 | version: 2 4 | updates: 5 | - package-ecosystem: "github-actions" 6 | directory: "/" 7 | schedule: 8 | interval: "daily" 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # misc 5 | .DS_Store 6 | .env.local 7 | .env.development.local 8 | .env.test.local 9 | .env.production.local 10 | 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # intelliJ workspace folder 16 | .idea 17 | 18 | /coverage 19 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | github: 2 | prebuilds: 3 | addBadge: true 4 | addComment: false 5 | addCheck: false 6 | master: true 7 | branches: true 8 | pullRequestsFromForks: true 9 | 10 | tasks: 11 | - init: npm install 12 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run check-style 5 | npm run test 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .github 2 | DIRECTORY.md 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "bracketSpacing": true, 4 | "endOfLine": "lf", 5 | "insertPragma": false, 6 | "printWidth": 80, 7 | "proseWrap": "preserve", 8 | "quoteProps": "as-needed", 9 | "requirePragma": false, 10 | "semi": false, 11 | "singleQuote": true, 12 | "tabWidth": 2, 13 | "trailingComma": "none", 14 | "useTabs": false 15 | } 16 | -------------------------------------------------------------------------------- /Backtracking/AllCombinationsOfSizeK.js: -------------------------------------------------------------------------------- 1 | function generateCombinations(n, k) { 2 | let currentCombination = [] 3 | let allCombinations = [] // will be used for storing all combinations 4 | let currentValue = 1 5 | 6 | function findCombinations() { 7 | if (currentCombination.length === k) { 8 | // Add the array of size k to the allCombinations array 9 | allCombinations.push([...currentCombination]) 10 | return 11 | } 12 | if (currentValue > n) { 13 | // Check for exceeding the range 14 | return 15 | } 16 | currentCombination.push(currentValue++) 17 | findCombinations() 18 | currentCombination.pop() 19 | findCombinations() 20 | currentValue-- 21 | } 22 | 23 | findCombinations() 24 | 25 | return allCombinations 26 | } 27 | 28 | export { generateCombinations } 29 | -------------------------------------------------------------------------------- /Backtracking/tests/AllCombinationsOfSizeK.test.js: -------------------------------------------------------------------------------- 1 | import { generateCombinations } from '../AllCombinationsOfSizeK' 2 | 3 | describe('AllCombinationsOfSizeK', () => { 4 | it('should return 3x2 matrix solution for n = 3 and k = 2', () => { 5 | const res = generateCombinations(3, 2) 6 | expect(res).toEqual([ 7 | [1, 2], 8 | [1, 3], 9 | [2, 3] 10 | ]) 11 | }) 12 | 13 | it('should return 6x2 matrix solution for n = 4 and k = 2', () => { 14 | const res = generateCombinations(4, 2) 15 | expect(res).toEqual([ 16 | [1, 2], 17 | [1, 3], 18 | [1, 4], 19 | [2, 3], 20 | [2, 4], 21 | [3, 4] 22 | ]) 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /Backtracking/tests/GenerateParentheses.test.js: -------------------------------------------------------------------------------- 1 | import { generateParentheses } from '../generateParentheses' 2 | 3 | test('generate all valid parentheses of input 3', () => { 4 | expect(generateParentheses(3)).toStrictEqual([ 5 | '((()))', 6 | '(()())', 7 | '(())()', 8 | '()(())', 9 | '()()()' 10 | ]) 11 | }) 12 | -------------------------------------------------------------------------------- /Backtracking/tests/MColoringProblem.test.js: -------------------------------------------------------------------------------- 1 | import { mColoring } from '../MColoringProblem' 2 | 3 | describe('MColoringProblem', () => { 4 | it('should color a triangle with 3 colors', () => { 5 | const graph = [ 6 | [0, 1, 1], 7 | [1, 0, 1], 8 | [1, 1, 0] 9 | ] 10 | const solution = mColoring(graph, 3) 11 | expect(solution).not.toBeNull() 12 | }) 13 | 14 | it('should not color a triangle with 2 colors', () => { 15 | const graph = [ 16 | [0, 1, 1], 17 | [1, 0, 1], 18 | [1, 1, 0] 19 | ] 20 | const solution = mColoring(graph, 2) 21 | expect(solution).toBeNull() 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /Backtracking/tests/NQueens.test.js: -------------------------------------------------------------------------------- 1 | import { NQueens } from '../NQueens' 2 | 3 | describe('NQueens', () => { 4 | it('should return 2 solutions for 4x4 size board', () => { 5 | const _4Queens = new NQueens(4) 6 | _4Queens.solve() 7 | expect(_4Queens.solutionCount).toEqual(2) 8 | }) 9 | 10 | it('should return 92 solutions for 8x8 size board', () => { 11 | const _8Queens = new NQueens(8) 12 | _8Queens.solve() 13 | expect(_8Queens.solutionCount).toEqual(92) 14 | }) 15 | 16 | it('should throw RangeError for negative size board', () => { 17 | expect(() => { 18 | return new NQueens(-1) 19 | }).toThrow(RangeError) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /Backtracking/tests/SumOfSubset.test.js: -------------------------------------------------------------------------------- 1 | import { sumOfSubset } from '../SumOfSubset' 2 | 3 | describe('SumOfSubset', () => { 4 | it('should return the subsets that add up to the given number', () => { 5 | // W = [2, 5, 7, 8, 12, 16, 23, 40] 6 | // K = 25 7 | 8 | const nums = [2, 5, 7, 8, 12, 16, 23, 40] 9 | 10 | const subsets = sumOfSubset(nums, [], 0, 0, 25) 11 | 12 | expect(subsets).toEqual([ 13 | [2, 7, 16], 14 | [2, 23], 15 | [5, 8, 12] 16 | ]) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Bit-Manipulation/BinaryCountSetBits.js: -------------------------------------------------------------------------------- 1 | /* 2 | author: vivek9patel 3 | license: GPL-3.0 or later 4 | 5 | This script will find number of 1's 6 | in binary representation of given number 7 | 8 | */ 9 | 10 | function BinaryCountSetBits(a) { 11 | 'use strict' 12 | 13 | // check whether input is an integer, some non-integer number like, 21.1 have non-terminating binary expansions and hence their binary expansion will contain infinite ones, thus the handling of non-integers (including strings,objects etc. as it is meaningless) has been omitted 14 | 15 | if (!Number.isInteger(a)) throw new TypeError('Argument not an Integer') 16 | 17 | let count = 0 18 | while (a) { 19 | a &= a - 1 20 | count++ 21 | } 22 | 23 | return count 24 | } 25 | 26 | export { BinaryCountSetBits } 27 | -------------------------------------------------------------------------------- /Bit-Manipulation/IsPowerofFour.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author : dev-madhurendra 3 | * Checks whether the given number is a power of four or not. 4 | * 5 | * A number is considered a power of four if and only if there is a single '1' bit in its binary representation, 6 | * and that '1' bit is at the first position, followed by an even number of '0' bits. 7 | * 8 | * @param {number} n - The input number to check. 9 | * @returns {boolean} True if the number is a power of four, false otherwise. 10 | * 11 | * @example 12 | * const result = isPowerOfFour(16); // Returns true (16 is 4^2) 13 | * const result2 = isPowerOfFour(5); // Returns false (5 is not a power of four) 14 | */ 15 | const isPowerOfFour = (n) => n > 0 && (n & (n - 1)) === 0 && n % 3 === 1 16 | 17 | export { isPowerOfFour } 18 | -------------------------------------------------------------------------------- /Bit-Manipulation/LogTwo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * https://handwiki.org/wiki/Binary_logarithm 3 | * Approximate log2 using only bitwise operators 4 | * @param {number} n 5 | * @returns {number} Log2 approximation equal to floor(log2(n)) 6 | */ 7 | export const logTwo = (n) => { 8 | let result = 0 9 | while (n >> 1) { 10 | n >>= 1 11 | result++ 12 | } 13 | return result 14 | } 15 | -------------------------------------------------------------------------------- /Bit-Manipulation/NextPowerOfTwo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * This script will find next power of two 4 | * of given number. 5 | * More about it: 6 | * https://www.techiedelight.com/round-next-highest-power-2/ 7 | * 8 | */ 9 | 10 | export const nextPowerOfTwo = (n) => { 11 | if (n > 0 && (n & (n - 1)) === 0) return n 12 | let result = 1 13 | while (n > 0) { 14 | result = result << 1 15 | n = n >> 1 16 | } 17 | return result 18 | } 19 | -------------------------------------------------------------------------------- /Bit-Manipulation/UniqueElementInAnArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Finds the unique element in an array where all other elements are repeated twice. 3 | * 4 | * @param {number[]} arr - The input array of integers. 5 | * @returns {number} The unique element. 6 | * 7 | * @example 8 | * const arr = [1, 2, 1, 2, 3]; 9 | * const uniqueElement = findUniqueElement(arr); // Returns 3 10 | */ 11 | const findUniqueElement = (arr) => arr.reduce((acc, val) => acc ^ val, 0) 12 | 13 | export { findUniqueElement } 14 | -------------------------------------------------------------------------------- /Bit-Manipulation/test/GrayCodes.test.js: -------------------------------------------------------------------------------- 1 | import { generateGrayCodes } from '../GrayCodes.js' 2 | 3 | describe('Gray codes', () => { 4 | test.each([ 5 | [0, [0b0]], 6 | [1, [0b0, 0b1]], 7 | [2, [0b00, 0b01, 0b11, 0b10]], 8 | [3, [0b000, 0b001, 0b011, 0b010, 0b110, 0b111, 0b101, 0b100]], 9 | [ 10 | 4, 11 | [ 12 | 0b0000, 0b0001, 0b0011, 0b0010, 0b0110, 0b0111, 0b0101, 0b0100, 0b1100, 13 | 0b1101, 0b1111, 0b1110, 0b1010, 0b1011, 0b1001, 0b1000 14 | ] 15 | ] 16 | ])('n = %i -> %j', (n, expected) => { 17 | expect(generateGrayCodes(n)).toEqual(expected) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Bit-Manipulation/test/IsPowerOfFour.test.js: -------------------------------------------------------------------------------- 1 | import { isPowerOfFour } from '../IsPowerofFour' 2 | 3 | describe('IsPowerOfFour', () => { 4 | it.each([ 5 | [0, false], 6 | [4, true], 7 | [16, true], 8 | [12, false], 9 | [64, true], 10 | [-64, false] 11 | ])('should return the number is power of four or not', (n, expected) => { 12 | expect(isPowerOfFour(n)).toBe(expected) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Bit-Manipulation/test/IsPowerOfTwo.test.js: -------------------------------------------------------------------------------- 1 | import { IsPowerOfTwo } from '../IsPowerOfTwo' 2 | 3 | test('Check if 0 is a power of 2 or not:', () => { 4 | const res = IsPowerOfTwo(0) 5 | expect(res).toBe(false) 6 | }) 7 | 8 | test('Check if 1 is a power of 2 or not:', () => { 9 | const res = IsPowerOfTwo(1) 10 | expect(res).toBe(true) 11 | }) 12 | 13 | test('Check if 4 is a power of 2 or not:', () => { 14 | const res = IsPowerOfTwo(4) 15 | expect(res).toBe(true) 16 | }) 17 | 18 | test('Check if 1024 is a power of 2 or not:', () => { 19 | const res = IsPowerOfTwo(1024) 20 | expect(res).toBe(true) 21 | }) 22 | 23 | test('Check if 1025 is a power of 2 or not:', () => { 24 | const res = IsPowerOfTwo(1025) 25 | expect(res).toBe(false) 26 | }) 27 | -------------------------------------------------------------------------------- /Bit-Manipulation/test/LogTwo.test.js: -------------------------------------------------------------------------------- 1 | import { logTwo } from '../LogTwo' 2 | 3 | for (let i = 1; i < 100; i++) { 4 | test('log2(' + i + ')', () => { 5 | expect(logTwo(i)).toBe(Math.floor(Math.log2(i))) 6 | }) 7 | } 8 | -------------------------------------------------------------------------------- /Bit-Manipulation/test/NextPowerOfTwo.test.js: -------------------------------------------------------------------------------- 1 | import { nextPowerOfTwo } from '../NextPowerOfTwo' 2 | 3 | describe('NextPowerOfTwo', () => { 4 | it.each` 5 | input | result 6 | ${0} | ${1} 7 | ${1} | ${1} 8 | ${2} | ${2} 9 | ${3} | ${4} 10 | ${5} | ${8} 11 | ${125} | ${128} 12 | ${1024} | ${1024} 13 | ${10000} | ${16384} 14 | `('returns $result when is given $input', ({ input, result }) => { 15 | const res = nextPowerOfTwo(input) 16 | expect(res).toBe(result) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Bit-Manipulation/test/SetBit.test.js: -------------------------------------------------------------------------------- 1 | import { setBit } from '../SetBit' 2 | 3 | test('Set bit number 0 in 1:', () => { 4 | const setBitPos = setBit(1, 0) 5 | expect(setBitPos).toBe(1) 6 | }) 7 | 8 | test('Set bit number 0 in 2:', () => { 9 | const setBitPos = setBit(2, 0) 10 | expect(setBitPos).toBe(3) 11 | }) 12 | 13 | test('Set bit number 1 in 10:', () => { 14 | const setBitPos = setBit(10, 1) 15 | expect(setBitPos).toBe(10) 16 | }) 17 | 18 | test('Set bit number 2 in 10:', () => { 19 | const setBitPos = setBit(10, 2) 20 | expect(setBitPos).toBe(14) 21 | }) 22 | -------------------------------------------------------------------------------- /Bit-Manipulation/test/UniqueElementInAnArray.test.js: -------------------------------------------------------------------------------- 1 | import { findUniqueElement } from '../UniqueElementInAnArray' 2 | 3 | describe('UniqueElementInAnArray', () => { 4 | it.each([ 5 | [[1, 2, 1, 3, 3], 2], 6 | [[1, 2, 3, 4, 5, 4, 3, 2, 1], 5] 7 | ])('should return an unique element from an array', (arr, expected) => { 8 | expect(findUniqueElement(arr)).toBe(expected) 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /Cellular-Automata/test/ConwaysGameOfLife.test.js: -------------------------------------------------------------------------------- 1 | import { newGeneration } from '../ConwaysGameOfLife' 2 | 3 | describe('newGeneration', () => { 4 | it('should produce the next generation according to the rules', () => { 5 | expect( 6 | newGeneration([ 7 | [0, 1, 0], 8 | [0, 1, 0], 9 | [0, 1, 0] 10 | ]) 11 | ).toEqual([ 12 | [0, 0, 0], 13 | [1, 1, 1], 14 | [0, 0, 0] 15 | ]) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /Ciphers/XORCipher.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function XORCipher 3 | * @description - Encrypt using an XOR cipher 4 | * The XOR cipher is a type of additive cipher. 5 | * Each character is bitwise XORed with the key. 6 | * We loop through the input string, XORing each 7 | * character with the key. 8 | * @param {string} str - string to be encrypted 9 | * @param {number} key - key for encryption 10 | * @return {string} encrypted string 11 | */ 12 | const XORCipher = (str, key) => { 13 | if (typeof str !== 'string' || !Number.isInteger(key)) { 14 | throw new TypeError('Arguments type are invalid') 15 | } 16 | 17 | return str.replace(/./g, (char) => 18 | String.fromCharCode(char.charCodeAt() ^ key) 19 | ) 20 | } 21 | 22 | export default XORCipher 23 | -------------------------------------------------------------------------------- /Ciphers/test/Atbash.test.js: -------------------------------------------------------------------------------- 1 | import Atbash from '../Atbash' 2 | 3 | describe('Testing Atbash function', () => { 4 | it('Test - 1, passing a non-string as an argument', () => { 5 | expect(() => Atbash(0x345)).toThrow() 6 | expect(() => Atbash(123)).toThrow() 7 | expect(() => Atbash(123n)).toThrow() 8 | expect(() => Atbash(false)).toThrow() 9 | expect(() => Atbash({})).toThrow() 10 | expect(() => Atbash([])).toThrow() 11 | }) 12 | 13 | it('Test - 2, passing a string as an argument', () => { 14 | const clearText = 'The quick brown fox jumps over the lazy dog' 15 | const cryptText = Atbash(clearText) 16 | expect(Atbash(cryptText)).toBe(clearText) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Ciphers/test/KeywordShiftedAlphabet.test.js: -------------------------------------------------------------------------------- 1 | import { encrypt, decrypt } from '../KeywordShiftedAlphabet' 2 | 3 | test('Hello world! === decrypt(encrypt(Hello world!))', () => { 4 | const word = 'Hello world!' 5 | const result = decrypt('keyword', encrypt('keyword', word)) 6 | expect(result).toMatch(word) 7 | }) 8 | 9 | test('The Algorithms === decrypt(encrypt(The Algorithms))', () => { 10 | const word = 'The Algorithms' 11 | const result = decrypt('keyword', encrypt('keyword', word)) 12 | expect(result).toMatch(word) 13 | }) 14 | -------------------------------------------------------------------------------- /Ciphers/test/MorseCode.test.js: -------------------------------------------------------------------------------- 1 | import { morse } from '../MorseCode' 2 | 3 | describe('Testing morse function', () => { 4 | it('should return an enciphered string with a given input string', () => { 5 | expect(morse('Hello World!')).toBe( 6 | '**** * *-** *-** --- *-- --- *-* *-** -** -*-*--' 7 | ) 8 | expect(morse('1+1=2')).toBe('*---- *-*-* *---- -***- **---') 9 | }) 10 | 11 | it('should leave symbols that does not have its corresponding morse representation', () => { 12 | expect(morse('© 2023 GitHub, Inc.')).toBe( 13 | '© **--- ----- **--- ***-- --* ** - **** **- -*** --**-- ** -* -*-* *-*-*-' 14 | ) 15 | }) 16 | 17 | it('should be able to accept custom morse code symbols', () => { 18 | expect(morse('Nodejs', '.', '|')).toBe('|. ||| |.. . .||| ...') 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /Ciphers/test/ROT13.test.js: -------------------------------------------------------------------------------- 1 | import ROT13 from '../ROT13' 2 | 3 | describe('Testing ROT13 function', () => { 4 | it('Test - 1, passing a non-string as an argument', () => { 5 | expect(() => ROT13(0x345)).toThrow() 6 | expect(() => ROT13(123)).toThrow() 7 | expect(() => ROT13(123n)).toThrow() 8 | expect(() => ROT13(false)).toThrow() 9 | expect(() => ROT13({})).toThrow() 10 | expect(() => ROT13([])).toThrow() 11 | }) 12 | 13 | it('Test - 2, passing a string as an argument', () => { 14 | expect(ROT13('Uryyb Jbeyq')).toBe('Hello World') 15 | expect(ROT13('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')).toBe( 16 | 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm' 17 | ) 18 | expect(ROT13('The quick brown fox jumps over the lazy dog')).toBe( 19 | 'Gur dhvpx oebja sbk whzcf bire gur ynml qbt' 20 | ) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /Ciphers/test/VigenereCipher.test.js: -------------------------------------------------------------------------------- 1 | import { encrypt, decrypt } from '../VigenereCipher' 2 | 3 | test('Hello world! === decrypt(encrypt(Hello world!))', () => { 4 | const word = 'Hello world!' 5 | const result = decrypt(encrypt(word, 'code'), 'code') 6 | expect(result).toMatch(word) 7 | }) 8 | 9 | test('The Algorithms === decrypt(encrypt(The Algorithms))', () => { 10 | const word = 'The Algorithms' 11 | const result = decrypt(encrypt(word, 'code'), 'code') 12 | expect(result).toMatch(word) 13 | }) 14 | -------------------------------------------------------------------------------- /Ciphers/test/XORCipher.test.js: -------------------------------------------------------------------------------- 1 | import XORCipher from '../XORCipher' 2 | 3 | describe('Testing XORCipher function', () => { 4 | it('Test - 1, passing a non-string as an argument', () => { 5 | expect(() => XORCipher(false, 0x345)).toThrow() 6 | expect(() => XORCipher(true, 123)).toThrow() 7 | expect(() => XORCipher(1n, 123n)).toThrow() 8 | expect(() => XORCipher(false, 0.34)).toThrow() 9 | expect(() => XORCipher({})).toThrow() 10 | expect(() => XORCipher([])).toThrow() 11 | }) 12 | 13 | it('Test - 2, passing a string & number as an argument', () => { 14 | // NB: Node REPL might not output the null char '\x00' (charcode 0) 15 | expect(XORCipher('test string', 32)).toBe('TEST\x00STRING') 16 | expect(XORCipher('TEST\x00STRING', 32)).toBe('test string') 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Compression/test/RLE.test.js: -------------------------------------------------------------------------------- 1 | import { Compress, Decompress } from '../RLE' 2 | 3 | describe('Test RLE Compressor/Decompressor', () => { 4 | it('Test - 1, Pass long repetitive strings', () => { 5 | expect(Compress('AAAAAAAAAAAAAA')).toBe('14A') 6 | expect(Compress('AAABBQQQQQFG')).toBe('3A2B5Q1F1G') 7 | }) 8 | 9 | it('Test - 2, Pass compressed strings', () => { 10 | expect(Decompress('14A')).toBe('AAAAAAAAAAAAAA') 11 | expect(Decompress('3A2B5Q1F1G')).toBe('AAABBQQQQQFG') 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /Conversions/BinaryToDecimal.js: -------------------------------------------------------------------------------- 1 | export default function binaryToDecimal(binaryString) { 2 | let decimalNumber = 0 3 | const binaryDigits = binaryString.split('').reverse() // Splits the binary number into reversed single digits 4 | binaryDigits.forEach((binaryDigit, index) => { 5 | decimalNumber += binaryDigit * Math.pow(2, index) // Summation of all the decimal converted digits 6 | }) 7 | return decimalNumber 8 | } 9 | -------------------------------------------------------------------------------- /Conversions/DecimalToBinary.js: -------------------------------------------------------------------------------- 1 | function decimalToBinary(num) { 2 | const bin = [] 3 | while (num > 0) { 4 | bin.unshift(num % 2) 5 | num >>= 1 // basically /= 2 without remainder if any 6 | } 7 | return bin.join('') 8 | } 9 | 10 | export { decimalToBinary } 11 | 12 | // > decimalToBinary(2) 13 | // '10' 14 | 15 | // > decimalToBinary(7) 16 | // '111' 17 | 18 | // > decimalToBinary(35) 19 | // '100011' 20 | -------------------------------------------------------------------------------- /Conversions/DecimalToHex.js: -------------------------------------------------------------------------------- 1 | function intToHex(num) { 2 | switch (num) { 3 | case 10: 4 | return 'A' 5 | case 11: 6 | return 'B' 7 | case 12: 8 | return 'C' 9 | case 13: 10 | return 'D' 11 | case 14: 12 | return 'E' 13 | case 15: 14 | return 'F' 15 | } 16 | return num 17 | } 18 | 19 | function decimalToHex(num) { 20 | const hexOut = [] 21 | while (num > 15) { 22 | hexOut.unshift(intToHex(num % 16)) 23 | num = Math.floor(num / 16) 24 | } 25 | return intToHex(num) + hexOut.join('') 26 | } 27 | 28 | export { decimalToHex } 29 | -------------------------------------------------------------------------------- /Conversions/DecimalToOctal.js: -------------------------------------------------------------------------------- 1 | function decimalToOctal(num) { 2 | let oct = 0 3 | let c = 0 4 | while (num > 0) { 5 | const r = num % 8 6 | oct = oct + r * Math.pow(10, c++) 7 | num = Math.floor(num / 8) // basically /= 8 without remainder if any 8 | } 9 | return oct 10 | } 11 | 12 | export { decimalToOctal } 13 | 14 | // > decimalToOctal(2) 15 | // 2 16 | 17 | // > decimalToOctal(8) 18 | // 10 19 | 20 | // > decimalToOctal(65) 21 | // 101 22 | 23 | // > decimalToOctal(216) 24 | // 330 25 | 26 | // > decimalToOctal(512) 27 | // 1000 28 | -------------------------------------------------------------------------------- /Conversions/HexToRGB.js: -------------------------------------------------------------------------------- 1 | function hexStringToRGB(hexString) { 2 | let r = hexString.substring(0, 2) 3 | let g = hexString.substring(2, 4) 4 | let b = hexString.substring(4, 6) 5 | 6 | r = parseInt(r, 16) 7 | g = parseInt(g, 16) 8 | b = parseInt(b, 16) 9 | const obj = { r, g, b } 10 | 11 | return obj 12 | } 13 | 14 | export { hexStringToRGB } 15 | 16 | // > hexStringToRGB('ffffff') 17 | // { r: 255, g: 255, b: 255 } 18 | -------------------------------------------------------------------------------- /Conversions/LitersToImperialGallons.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This function converts liters to imperial gallons 3 | * @constructor 4 | * @param {number} liters - Amount of liters to convert to gallons 5 | * @see https://en.wikipedia.org/wiki/Gallon 6 | */ 7 | const litersToImperialGallons = (liters) => { 8 | return liters / 4.54609 9 | } 10 | 11 | export default litersToImperialGallons 12 | -------------------------------------------------------------------------------- /Conversions/LitersToUSGallons.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This function converts liters to US gallons 3 | * https://en.wikipedia.org/wiki/Gallon 4 | * @constructor 5 | * @param {number} liters - Amount of liters to convert to gallons 6 | */ 7 | const litersToUSGallons = (liters) => { 8 | return liters / 3.785411784 9 | } 10 | 11 | export default litersToUSGallons 12 | -------------------------------------------------------------------------------- /Conversions/MeterToFeetConversion.js: -------------------------------------------------------------------------------- 1 | // Foot: https://en.wikipedia.org/wiki/Foot_(unit) 2 | const feetToMeter = (feet) => { 3 | return feet * 0.3048 4 | } 5 | 6 | const meterToFeet = (meter) => { 7 | return meter / 0.3048 8 | } 9 | 10 | export { feetToMeter, meterToFeet } 11 | -------------------------------------------------------------------------------- /Conversions/OctToDecimal.js: -------------------------------------------------------------------------------- 1 | function octalToDecimal(num) { 2 | let dec = 0 3 | let base = 1 4 | while (num > 0) { 5 | const r = num % 10 6 | num = Math.floor(num / 10) 7 | dec = dec + r * base 8 | base = base * 8 9 | } 10 | return dec 11 | } 12 | 13 | export { octalToDecimal } 14 | 15 | // > octalToDecimal(56) 16 | // 46 17 | 18 | // > octalToDecimal(2365) 19 | // 1269 20 | -------------------------------------------------------------------------------- /Conversions/OuncesToKilograms.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This function converts ounces to kilograms 3 | * https://en.wikipedia.org/wiki/Ounce 4 | * @constructor 5 | * @param {number} oz - Amount of ounces to convert to kilograms 6 | */ 7 | const ouncesToKilograms = (oz) => { 8 | return (oz * 28.3498) / 1000 9 | } 10 | 11 | export default ouncesToKilograms 12 | -------------------------------------------------------------------------------- /Conversions/RGBToHex.js: -------------------------------------------------------------------------------- 1 | function RGBToHex(r, g, b) { 2 | if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number') { 3 | throw new TypeError('argument is not a Number') 4 | } 5 | 6 | const toHex = (n) => (n || '0').toString(16).padStart(2, '0') 7 | 8 | return `#${toHex(r)}${toHex(g)}${toHex(b)}` 9 | } 10 | 11 | export { RGBToHex } 12 | 13 | // > RGBToHex(255, 255, 255) 14 | // '#ffffff' 15 | 16 | // > RGBToHex(255, 99, 71) 17 | // '#ff6347' 18 | -------------------------------------------------------------------------------- /Conversions/RomanToDecimal.js: -------------------------------------------------------------------------------- 1 | const values = { 2 | I: 1, 3 | V: 5, 4 | X: 10, 5 | L: 50, 6 | C: 100, 7 | D: 500, 8 | M: 1000 9 | } 10 | 11 | export function romanToDecimal(romanNumber) { 12 | let prev = ' ' 13 | 14 | let sum = 0 15 | 16 | let newPrev = 0 17 | for (let i = romanNumber.length - 1; i >= 0; i--) { 18 | const c = romanNumber.charAt(i) 19 | 20 | if (prev !== ' ') { 21 | newPrev = values[prev] > newPrev ? values[prev] : newPrev 22 | } 23 | 24 | const currentNum = values[c] 25 | if (currentNum >= newPrev) { 26 | sum += currentNum 27 | } else { 28 | sum -= currentNum 29 | } 30 | 31 | prev = c 32 | } 33 | return sum 34 | } 35 | -------------------------------------------------------------------------------- /Conversions/test/BinaryToDecimal.test.js: -------------------------------------------------------------------------------- 1 | import binaryToDecimal from '../BinaryToDecimal' 2 | 3 | describe('BinaryToDecimal', () => { 4 | it('expects to return correct decimal value', () => { 5 | expect(binaryToDecimal('1000')).toBe(8) 6 | }) 7 | 8 | it('expects to return correct hexadecimal value for more than one hex digit', () => { 9 | expect(binaryToDecimal('01101000')).toBe(104) 10 | }) 11 | 12 | it('expects to return correct hexadecimal value for padding-required binary', () => { 13 | expect(binaryToDecimal('1000101')).toBe(69) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Conversions/test/BinaryToHex.test.js: -------------------------------------------------------------------------------- 1 | import binaryToHex from '../BinaryToHex' 2 | 3 | describe('BinaryToHex', () => { 4 | it('expects to return correct hexadecimal value', () => { 5 | expect(binaryToHex('1000')).toBe('8') 6 | }) 7 | 8 | it('expects to return correct hexadecimal value for more than one hex digit', () => { 9 | expect(binaryToHex('11101010')).toBe('EA') 10 | }) 11 | 12 | it('expects to return correct hexadecimal value for padding-required binary', () => { 13 | expect(binaryToHex('1001101')).toBe('4D') 14 | }) 15 | 16 | it('expects to return correct hexadecimal value, matching (num).toString(16)', () => { 17 | expect(binaryToHex('1111')).toBe( 18 | parseInt('1111', 2).toString(16).toUpperCase() 19 | ) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /Conversions/test/DecimalToBinary.test.js: -------------------------------------------------------------------------------- 1 | import { decimalToBinary } from '../DecimalToBinary' 2 | 3 | test('The Binary representation of 35 is 100011', () => { 4 | const res = decimalToBinary(35) 5 | expect(res).toBe('100011') 6 | }) 7 | 8 | test('The Binary representation of 1 is 1', () => { 9 | const res = decimalToBinary(1) 10 | expect(res).toBe('1') 11 | }) 12 | 13 | test('The Binary representation of 1000 is 1111101000', () => { 14 | const res = decimalToBinary(1000) 15 | expect(res).toBe('1111101000') 16 | }) 17 | 18 | test('The Binary representation of 2 is 10', () => { 19 | const res = decimalToBinary(2) 20 | expect(res).toBe('10') 21 | }) 22 | 23 | test('The Binary representation of 17 is 10001', () => { 24 | const res = decimalToBinary(17) 25 | expect(res).toBe('10001') 26 | }) 27 | -------------------------------------------------------------------------------- /Conversions/test/DecimalToHex.test.js: -------------------------------------------------------------------------------- 1 | import { decimalToHex } from '../DecimalToHex' 2 | 3 | describe('DecimalToHex', () => { 4 | it('expects to return correct hexadecimal value', () => { 5 | expect(decimalToHex(255)).toBe('FF') 6 | }) 7 | 8 | it('expects to return correct hexadecimal value, matching (num).toString(16)', () => { 9 | expect(decimalToHex(32768)).toBe((32768).toString(16).toUpperCase()) 10 | }) 11 | 12 | it('expects to not handle negative numbers', () => { 13 | expect(decimalToHex(-32768)).not.toBe((-32768).toString(16).toUpperCase()) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Conversions/test/DecimalToOctal.test.js: -------------------------------------------------------------------------------- 1 | import { decimalToOctal } from '../DecimalToOctal' 2 | 3 | test('The Octal representation of 8 is 10', () => { 4 | const res = decimalToOctal(8) 5 | expect(res).toBe(10) 6 | }) 7 | 8 | test('The Octal representation of 1 is 1', () => { 9 | const res = decimalToOctal(1) 10 | expect(res).toBe(1) 11 | }) 12 | 13 | test('The Octal representation of 0 is 0', () => { 14 | const res = decimalToOctal(0) 15 | expect(res).toBe(0) 16 | }) 17 | 18 | test('The Octal representation of 100 is 144', () => { 19 | const res = decimalToOctal(100) 20 | expect(res).toBe(144) 21 | }) 22 | 23 | test('The Octal representation of 111 is 157', () => { 24 | const res = decimalToOctal(111) 25 | expect(res).toBe(157) 26 | }) 27 | -------------------------------------------------------------------------------- /Conversions/test/DecimalToRoman.test.js: -------------------------------------------------------------------------------- 1 | import { decimalToRoman } from '../DecimalToRoman' 2 | 3 | describe('decimalToRoman', () => { 4 | it('expects to return correct roman numeral of given number', () => { 5 | expect(decimalToRoman(34)).toBe('XXXIV') 6 | }) 7 | it('expects to return correct roman numeral of given number', () => { 8 | expect(decimalToRoman(28)).toBe('XXVIII') 9 | }) 10 | it('expects to return correct roman numeral of given number', () => { 11 | expect(decimalToRoman(2021)).toBe('MMXXI') 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /Conversions/test/HexToDecimal.test.js: -------------------------------------------------------------------------------- 1 | import { hexToDecimal } from '../HexToDecimal' 2 | 3 | describe('Testing HexToDecimal', () => { 4 | it.each([ 5 | ['0', 0], 6 | ['1', 1], 7 | ['A', 10], 8 | ['B', 11], 9 | ['C', 12], 10 | ['D', 13], 11 | ['E', 14], 12 | ['F', 15], 13 | ['10', 16], 14 | ['859', 2137], 15 | ['4D2', 1234], 16 | ['81323ABD92', 554893491602] 17 | ])('check with %s', (hexStr, expected) => { 18 | expect(hexToDecimal(hexStr)).toBe(expected) 19 | }) 20 | 21 | it.each(['a', '-1', 'G', ''])('throws for %s', (hexStr) => { 22 | expect(() => hexToDecimal(hexStr)).toThrowError() 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /Conversions/test/HexToRGB.test.js: -------------------------------------------------------------------------------- 1 | import { hexStringToRGB } from '../HexToRGB' 2 | 3 | test('The RGB form of Hex String E1E1E1 is {r: 225, g: 225, b: 225}', () => { 4 | const res = hexStringToRGB('E1E1E1') 5 | expect(res).toEqual({ r: 225, g: 225, b: 225 }) 6 | }) 7 | 8 | test('The RGB form of Hex String 000000 is {r: 0, g: 0, b: 0}', () => { 9 | const res = hexStringToRGB('000000') 10 | expect(res).toEqual({ r: 0, g: 0, b: 0 }) 11 | }) 12 | 13 | test('The RGB form of Hex String 6CE1CD is {r: 108, g: 225, b: 205}', () => { 14 | const res = hexStringToRGB('6CE1CD') 15 | expect(res).toEqual({ r: 108, g: 225, b: 205 }) 16 | }) 17 | -------------------------------------------------------------------------------- /Conversions/test/LitersToImperialGallons.test.js: -------------------------------------------------------------------------------- 1 | import litersToImperialGallons from '../LitersToImperialGallons' 2 | 3 | test('Convert 25 liters to imperial gallons', () => { 4 | expect(parseFloat(litersToImperialGallons(25).toFixed(2))).toBe(5.5) 5 | }) 6 | -------------------------------------------------------------------------------- /Conversions/test/LitersToUSGallons.test.js: -------------------------------------------------------------------------------- 1 | import litersToUSGallons from '../LitersToUSGallons' 2 | 3 | test('Convert 50 liters to US gallons', () => { 4 | expect(parseFloat(litersToUSGallons(50).toFixed(2))).toBe(13.21) 5 | }) 6 | -------------------------------------------------------------------------------- /Conversions/test/LowerCaseConversion.test.js: -------------------------------------------------------------------------------- 1 | import { LowerCaseConversion } from '../LowerCaseConversion' 2 | 3 | test('The LowerCaseConversion of ApoLO is apolo', () => { 4 | const res = LowerCaseConversion('ApoLO') 5 | expect(res).toBe('apolo') 6 | }) 7 | 8 | test('The LowerCaseConversion of WEB is web', () => { 9 | const res = LowerCaseConversion('WEB') 10 | expect(res).toBe('web') 11 | }) 12 | 13 | test('The LowerCaseConversion of EaRTh is earth', () => { 14 | const res = LowerCaseConversion('EaRTh') 15 | expect(res).toBe('earth') 16 | }) 17 | 18 | test('The LowerCaseConversion of TiGER is tiger', () => { 19 | const res = LowerCaseConversion('TiGER') 20 | expect(res).toBe('tiger') 21 | }) 22 | 23 | test('The LowerCaseConversion of Cricket is cricket', () => { 24 | const res = LowerCaseConversion('Cricket') 25 | expect(res).toBe('cricket') 26 | }) 27 | -------------------------------------------------------------------------------- /Conversions/test/MeterToFeetConversion.test.js: -------------------------------------------------------------------------------- 1 | import { meterToFeet, feetToMeter } from '../MeterToFeetConversion' 2 | 3 | describe('Testing conversion of Meter to Feet', () => { 4 | it('with feet value', () => { 5 | expect(meterToFeet(30.48)).toBe(100) 6 | }) 7 | }) 8 | 9 | describe('Testing conversion of Feet to Meter', () => { 10 | it('with feet value', () => { 11 | expect(feetToMeter(10)).toBe(3.048) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /Conversions/test/OctToDecimal.test.js: -------------------------------------------------------------------------------- 1 | import { octalToDecimal } from '../OctToDecimal' 2 | 3 | test('The Decimal representation of Octal number 56 is 46', () => { 4 | const res = octalToDecimal(56) 5 | expect(res).toBe(46) 6 | }) 7 | 8 | test('The Decimal representation of Octal number 99 is 81', () => { 9 | const res = octalToDecimal(99) 10 | expect(res).toBe(81) 11 | }) 12 | 13 | test('The Decimal representation of Octal number 17 is 15', () => { 14 | const res = octalToDecimal(17) 15 | expect(res).toBe(15) 16 | }) 17 | 18 | test('The Decimal representation of Octal number 100 is 64', () => { 19 | const res = octalToDecimal(100) 20 | expect(res).toBe(64) 21 | }) 22 | 23 | test('The Decimal representation of Octal number 0 is 0', () => { 24 | const res = octalToDecimal(0) 25 | expect(res).toBe(0) 26 | }) 27 | -------------------------------------------------------------------------------- /Conversions/test/OuncesToKilogram.test.js: -------------------------------------------------------------------------------- 1 | import ouncesToKilograms from '../OuncesToKilograms' 2 | 3 | test('Convert 60 ounces to kilograms', () => { 4 | expect(parseFloat(ouncesToKilograms(60).toFixed(3))).toBe(1.701) 5 | }) 6 | -------------------------------------------------------------------------------- /Conversions/test/RGBToHex.test.js: -------------------------------------------------------------------------------- 1 | import { RGBToHex } from '../RGBToHex' 2 | 3 | test('The Hex format of RGB (225, 225, 225) is #ffffff', () => { 4 | const res = RGBToHex(255, 255, 255) 5 | expect(res).toBe('#ffffff') 6 | }) 7 | 8 | test('The Hex format of RGB (190, 108, 217) is #be6cd9', () => { 9 | const res = RGBToHex(190, 108, 217) 10 | expect(res).toBe('#be6cd9') 11 | }) 12 | 13 | test('The Hex format of RGB (255, 99, 71) is #ff6347', () => { 14 | const res = RGBToHex(255, 99, 71) 15 | expect(res).toBe('#ff6347') 16 | }) 17 | 18 | test('The Hex format of RGB (100, 108, 217) is #646cd9', () => { 19 | const res = RGBToHex(100, 108, 217) 20 | expect(res).toBe('#646cd9') 21 | }) 22 | -------------------------------------------------------------------------------- /Conversions/test/RomanToDecimal.test.js: -------------------------------------------------------------------------------- 1 | import { romanToDecimal } from '../RomanToDecimal' 2 | 3 | describe('romanToDecimal', () => { 4 | it('XXIIVV', () => { 5 | expect(romanToDecimal('XXIIVV')).toBe(28) 6 | }) 7 | 8 | it('MDCCCIV', () => { 9 | expect(romanToDecimal('MDCCCIV')).toBe(1804) 10 | }) 11 | 12 | it('XXIVI', () => { 13 | expect(romanToDecimal('XXIVI')).toBe(25) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Data-Structures/Array/Reverse.js: -------------------------------------------------------------------------------- 1 | /** https://www.geeksforgeeks.org/write-a-program-to-Reverse-an-array-or-string/ 2 | * This function will accept an array and 3 | * Reverse its elements and returns the inverted array 4 | * @param {Array} arr array with elements of any data type 5 | * @returns {Array} array with inverted elements 6 | */ 7 | 8 | const Reverse = (arr) => { 9 | // limit specifies the amount of Reverse actions 10 | for (let i = 0, j = arr.length - 1; i < arr.length / 2; i++, j--) 11 | [arr[i], arr[j]] = [arr[j], arr[i]] 12 | 13 | return arr 14 | } 15 | export { Reverse } 16 | -------------------------------------------------------------------------------- /Data-Structures/Array/test/Reverse.test.js: -------------------------------------------------------------------------------- 1 | import { Reverse } from '../Reverse.js' 2 | 3 | describe('reverse elements in an array', () => { 4 | it.each([ 5 | [[], []], 6 | [[1], [1]], 7 | [ 8 | [1, 2, 3, 4], 9 | [4, 3, 2, 1] 10 | ] 11 | ])('returns %j when given %j', (array, expected) => { 12 | expect(Reverse(array)).toEqual(expected) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Data-Structures/Linked-List/CycleDetection.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A LinkedList based solution for Detecting a Cycle in a list. 3 | * https://en.wikipedia.org/wiki/Cycle_detection 4 | */ 5 | 6 | function detectCycle(head) { 7 | /* 8 | Problem Statement: 9 | Given head, the head of a linked list, determine if the linked list has a cycle in it. 10 | Link for the Problem: https://leetcode.com/problems/linked-list-cycle/ 11 | */ 12 | if (!head) { 13 | return false 14 | } 15 | 16 | let slow = head 17 | let fast = head.next 18 | while (fast && fast.next) { 19 | if (fast === slow) { 20 | return true 21 | } 22 | fast = fast.next.next 23 | slow = slow.next 24 | } 25 | return false 26 | } 27 | 28 | export { detectCycle } 29 | -------------------------------------------------------------------------------- /Data-Structures/Linked-List/ReverseSinglyLinkedList.js: -------------------------------------------------------------------------------- 1 | /** A LinkedList based solution to reverse a number 2 | Problem Statement: Given a number such that each of its digit is stored in a singly linked list. Reverse the linked list and return the head of the linked list Link for the Problem: https://leetcode.com/problems/reverse-linked-list/ */ 3 | class ReverseSinglyLinkedList { 4 | solution(head) { 5 | let prev = null 6 | let next = null 7 | while (head) { 8 | next = head.next 9 | head.next = prev 10 | prev = head 11 | head = next 12 | } 13 | return prev 14 | } 15 | } 16 | export { ReverseSinglyLinkedList } 17 | -------------------------------------------------------------------------------- /Data-Structures/Linked-List/test/AddTwoNumbers.test.js: -------------------------------------------------------------------------------- 1 | import { AddTwoNumbers } from '../AddTwoNumbers.js' 2 | import { LinkedList } from '../SinglyLinkedList' 3 | 4 | describe('AddTwoNumbers', () => { 5 | it('Check Sum Of Two Linked List', () => { 6 | const list1 = new LinkedList() 7 | list1.addFirst(2) 8 | list1.addLast(4) 9 | list1.addLast(3) 10 | 11 | const list2 = new LinkedList() 12 | list2.addFirst(5) 13 | list2.addLast(6) 14 | list2.addLast(4) 15 | 16 | const expected = new LinkedList() 17 | expected.addFirst(7) 18 | expected.addLast(0) 19 | expected.addLast(8) 20 | 21 | const addTwoLinkedList = new AddTwoNumbers() 22 | addTwoLinkedList.solution(list1.headNode, list2.headNode) 23 | 24 | expect(addTwoLinkedList.solutionToArray()).toEqual(expected.get()) 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /Data-Structures/Linked-List/test/ReverseSinglyLinkedList.test.js: -------------------------------------------------------------------------------- 1 | import { ReverseSinglyLinkedList } from '../ReverseSinglyLinkedList' 2 | import { Node } from '../SinglyLinkedList' 3 | describe('ReverseSinglyLinkedList', () => { 4 | it('Reverse a Number Represented as Linked List', () => { 5 | const headNode = new Node(3) 6 | headNode.next = new Node(4) 7 | headNode.next.next = new Node(1) 8 | const expected = new Node(1) 9 | expected.next = new Node(4) 10 | expected.next.next = new Node(3) 11 | const reverseSinglyLinkedList = new ReverseSinglyLinkedList() 12 | expect(reverseSinglyLinkedList.solution(headNode)).toEqual(expected) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Data-Structures/Queue/test/QueueUsing2Stacks.test.js: -------------------------------------------------------------------------------- 1 | import { Queue } from '../QueueUsing2Stacks' 2 | 3 | describe('QueueUsing2Stacks', () => { 4 | const queue = new Queue() 5 | 6 | it('Check enqueue/dequeue', () => { 7 | queue.enqueue(1) 8 | queue.enqueue(2) 9 | queue.enqueue(8) 10 | queue.enqueue(9) 11 | 12 | expect(queue.dequeue()).toBe(1) 13 | expect(queue.dequeue()).toBe(2) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Data-Structures/Stack/test/EvaluateExpression.test.js: -------------------------------------------------------------------------------- 1 | import { evaluatePostfixExpression } from '../EvaluateExpression.js' 2 | 3 | describe('evaluatePostfixExpression', () => { 4 | it('should evaluate a valid expression', () => { 5 | const expression = '3 4 * 2 / 5 +' // (3 * 4) / 2 + 5 = 11 6 | const result = evaluatePostfixExpression(expression) 7 | expect(result).toBe(11) 8 | }) 9 | 10 | it('should handle division by zero', () => { 11 | const expression = '3 0 /' // Division by zero 12 | const result = evaluatePostfixExpression(expression) 13 | expect(result).toBe(null) 14 | }) 15 | 16 | it('should handle an invalid expression', () => { 17 | const expression = '3 * 4 2 / +' // Invalid expression 18 | const result = evaluatePostfixExpression(expression) 19 | expect(result).toBe(null) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /Data-Structures/Tree/test/SegmentTree.test.js: -------------------------------------------------------------------------------- 1 | import { SegmentTree } from '../SegmentTree' 2 | 3 | describe('SegmentTree sum test', () => { 4 | const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 5 | 6 | const segment = new SegmentTree(a) 7 | 8 | it('init sum check', () => { 9 | expect(segment.query(0, 2)).toBe(6) 10 | }) 11 | 12 | it('init sum check', () => { 13 | segment.update(2, 1) 14 | expect(segment.query(0, 2)).toBe(4) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Dynamic-Programming/ClimbingStairs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function ClimbStairs 3 | * @description You are climbing a stair case. It takes n steps to reach to the top.Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? 4 | * @param {Integer} n - The input integer 5 | * @return {Integer} distinct ways can you climb to the top. 6 | * @see [Climb_Stairs](https://www.geeksforgeeks.org/count-ways-reach-nth-stair/) 7 | */ 8 | 9 | const climbStairs = (n) => { 10 | let prev = 0 11 | let cur = 1 12 | let temp 13 | 14 | for (let i = 0; i < n; i++) { 15 | temp = prev 16 | prev = cur 17 | cur += temp 18 | } 19 | return cur 20 | } 21 | 22 | export { climbStairs } 23 | -------------------------------------------------------------------------------- /Dynamic-Programming/FibonacciNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function fibonacci 3 | * @description Fibonacci is the sum of previous two fibonacci numbers. 4 | * @param {Integer} N - The input integer 5 | * @return {Integer} fibonacci of N. 6 | * @see [Fibonacci_Numbers](https://en.wikipedia.org/wiki/Fibonacci_number) 7 | */ 8 | const fibonacci = (N) => { 9 | if (!Number.isInteger(N)) { 10 | throw new TypeError('Input should be integer') 11 | } 12 | 13 | // memoize the last two numbers 14 | let firstNumber = 0 15 | let secondNumber = 1 16 | 17 | for (let i = 1; i < N; i++) { 18 | const sumOfNumbers = firstNumber + secondNumber 19 | // update last two numbers 20 | firstNumber = secondNumber 21 | secondNumber = sumOfNumbers 22 | } 23 | 24 | return N ? secondNumber : firstNumber 25 | } 26 | 27 | export { fibonacci } 28 | -------------------------------------------------------------------------------- /Dynamic-Programming/LongestIncreasingSubsequence.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A Dynamic Programming based solution for calculating Longest Increasing Subsequence 3 | * https://en.wikipedia.org/wiki/Longest_increasing_subsequence 4 | */ 5 | 6 | // Return the length of the Longest Increasing Subsequence, given array x 7 | function longestIncreasingSubsequence(x) { 8 | const length = x.length 9 | if (length == 0) { 10 | return 0 11 | } 12 | const dp = Array(length).fill(1) 13 | 14 | let res = 1 15 | 16 | for (let i = 0; i < length; i++) { 17 | for (let j = 0; j < i; j++) { 18 | if (x[i] > x[j]) { 19 | dp[i] = Math.max(dp[i], 1 + dp[j]) 20 | if (dp[i] > res) { 21 | res = dp[i] 22 | } 23 | } 24 | } 25 | } 26 | 27 | return res 28 | } 29 | 30 | export { longestIncreasingSubsequence } 31 | -------------------------------------------------------------------------------- /Dynamic-Programming/RodCutting.js: -------------------------------------------------------------------------------- 1 | /* 2 | * You are given a rod of 'n' length and an array of prices associated with all the lengths less than 'n'. 3 | * Find the maximum profit possible by cutting the rod and selling the pieces. 4 | */ 5 | 6 | export function rodCut(prices, n) { 7 | const memo = new Array(n + 1) 8 | memo[0] = 0 9 | 10 | for (let i = 1; i <= n; i++) { 11 | let maxVal = Number.MIN_VALUE 12 | for (let j = 0; j < i; j++) { 13 | maxVal = Math.max(maxVal, prices[j] + memo[i - j - 1]) 14 | } 15 | memo[i] = maxVal 16 | } 17 | 18 | return memo[n] 19 | } 20 | -------------------------------------------------------------------------------- /Dynamic-Programming/Sliding-Window/MaxConsecutiveOnes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function maxConsecutiveOnes 3 | * @description Given a binary array nums, return the maximum number of consecutive 1's in the array. 4 | * @param {number[]} nums 5 | * @return {number} 6 | * @see [Leetcode link](https://leetcode.com/problems/max-consecutive-ones/) 7 | */ 8 | export const maxConsecutiveOnes = (nums) => { 9 | if (!nums.length) return 0 10 | 11 | let result = 0 12 | let k = 0 13 | 14 | for ( 15 | let slowPointer = 0, fastPointer = 0; 16 | fastPointer < nums.length; 17 | fastPointer++ 18 | ) { 19 | if (nums[fastPointer] === 0) k-- 20 | 21 | while (k < 0) { 22 | if (nums[slowPointer] === 0) { 23 | k++ 24 | } 25 | slowPointer++ 26 | } 27 | result = Math.max(result, fastPointer - slowPointer + 1) 28 | } 29 | return result 30 | } 31 | -------------------------------------------------------------------------------- /Dynamic-Programming/Sliding-Window/test/HouseRobber.test.js: -------------------------------------------------------------------------------- 1 | import { houseRobber } from '../HouseRobber' 2 | 3 | describe('houseRobber', () => { 4 | it('expects to return 0 when argument is empty array', () => { 5 | expect(houseRobber([])).toBe(0) 6 | }) 7 | 8 | it('expects to return element at index 0 when argument is array of length one', () => { 9 | expect(houseRobber([9])).toBe(9) 10 | }) 11 | 12 | it('expects to return greater number when argument is an array of length two', () => { 13 | expect(houseRobber([3, 6])).toBe(6) 14 | }) 15 | 16 | it('expects to return the maximum loot possible', () => { 17 | expect(houseRobber([1, 2, 3, 1])).toBe(4) 18 | expect(houseRobber([2, 7, 9, 3, 1])).toBe(12) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /Dynamic-Programming/Sliding-Window/test/LongestSubstringWithoutRepeatingCharacters.test.js: -------------------------------------------------------------------------------- 1 | import { LongestSubstringWithoutRepeatingCharacters } from '../LongestSubstringWithoutRepeatingCharacters.js' 2 | 3 | describe('LongestSubstringWithoutRepeatingCharacters', () => { 4 | it('should return longest substring without repeating characters', () => { 5 | expect(LongestSubstringWithoutRepeatingCharacters('abcabcbb')).toEqual(3) 6 | expect(LongestSubstringWithoutRepeatingCharacters('bbbbb')).toEqual(1) 7 | expect(LongestSubstringWithoutRepeatingCharacters('pwwkew')).toEqual(3) 8 | expect(LongestSubstringWithoutRepeatingCharacters('a')).toEqual(1) 9 | expect(LongestSubstringWithoutRepeatingCharacters('')).toEqual(0) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Dynamic-Programming/Sliding-Window/test/MaxConsecutiveOnes.test.js: -------------------------------------------------------------------------------- 1 | import { maxConsecutiveOnes } from '../MaxConsecutiveOnes.js' 2 | 3 | describe('maxConsecutiveOnes', () => { 4 | it('expects to return 0 when argument is empty array', () => { 5 | expect(maxConsecutiveOnes([])).toBe(0) 6 | }) 7 | 8 | it('expects to return 3', () => { 9 | expect(maxConsecutiveOnes([1, 1, 0, 1, 1, 1])).toBe(3) 10 | }) 11 | 12 | it('expects to return 2', () => { 13 | expect(maxConsecutiveOnes([1, 0, 1, 1, 0, 1])).toBe(2) 14 | }) 15 | 16 | it('expects to return 5', () => { 17 | expect(maxConsecutiveOnes([0, 1, 1, 1, 1, 1, 0, 0, 1, 0])).toBe(5) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Dynamic-Programming/Sliding-Window/test/MaxConsecutiveOnesIII.test.js: -------------------------------------------------------------------------------- 1 | import { maxConsecutiveOnesIII } from '../MaxConsecutiveOnesIII' 2 | 3 | describe('maxConsecutiveOnesIIIIII', () => { 4 | it('expects to return 0 when argument is empty array', () => { 5 | expect(maxConsecutiveOnesIII([], 3)).toBe(0) 6 | }) 7 | 8 | it('expects to return 6', () => { 9 | expect(maxConsecutiveOnesIII([1, 1, 0, 1, 1, 1], 1)).toBe(6) 10 | }) 11 | 12 | it('expects to return 8', () => { 13 | expect(maxConsecutiveOnesIII([1, 0, 1, 1, 1, 1, 0, 1], 2)).toBe(8) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Dynamic-Programming/Sliding-Window/test/PermutationinString.test.js: -------------------------------------------------------------------------------- 1 | import { PermutationinString } from '../PermutationinString.js' 2 | 3 | describe('PermutationinString', () => { 4 | it("should return true if one of s1's permutations is the substring of s2", () => { 5 | expect(PermutationinString('ab', 'eidbaooo')).toEqual(true) 6 | expect(PermutationinString('abc', 'bcab')).toEqual(true) 7 | expect(PermutationinString('ab', 'eidboaoo')).toEqual(false) 8 | expect(PermutationinString('abc', '')).toEqual(false) 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /Dynamic-Programming/TribonacciNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function Tribonacci 3 | * @description Tribonacci is the sum of previous three tribonacci numbers. 4 | * @param {Integer} n - The input integer 5 | * @return {Integer} tribonacci of n. 6 | * @see [Tribonacci_Numbers](https://www.geeksforgeeks.org/tribonacci-numbers/) 7 | */ 8 | const tribonacci = (n) => { 9 | // creating array to store previous tribonacci numbers 10 | const dp = new Array(n + 1) 11 | dp[0] = 0 12 | dp[1] = 1 13 | dp[2] = 1 14 | for (let i = 3; i <= n; i++) { 15 | dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3] 16 | } 17 | return dp[n] 18 | } 19 | 20 | export { tribonacci } 21 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/CatalanNumbers.test.js: -------------------------------------------------------------------------------- 1 | import { catalanNumbers } from '../CatalanNumbers' 2 | 3 | describe('Testing catalanNumbers function', () => { 4 | test('should return the expected array for inputs from 0 to 20', () => { 5 | const expectedOutput = [ 6 | 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 7 | 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420 8 | ] 9 | 10 | for (let i = 0; i <= 20; i++) { 11 | expect(catalanNumbers(i)).toStrictEqual(expectedOutput.slice(0, i + 1)) 12 | } 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/ClimbingStairs.test.js: -------------------------------------------------------------------------------- 1 | import { climbStairs } from '../ClimbingStairs' 2 | 3 | describe('ClimbingStairs', () => { 4 | it('climbStairs of 0', () => { 5 | expect(climbStairs(0)).toBe(1) 6 | }) 7 | 8 | it('climbStairs of 1', () => { 9 | expect(climbStairs(1)).toBe(1) 10 | }) 11 | 12 | it('climbStairs of 10', () => { 13 | expect(climbStairs(10)).toBe(89) 14 | }) 15 | 16 | it('climbStairs of 15', () => { 17 | expect(climbStairs(15)).toBe(987) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/EditDistance.test.js: -------------------------------------------------------------------------------- 1 | import { minimumEditDistance } from '../EditDistance' 2 | 3 | test('minimumEditDistance(kitten, sitten) => 1', () => { 4 | const str1 = 'kitten' 5 | const str2 = 'sitten' 6 | const res = minimumEditDistance(str1, str2) 7 | expect(res).toEqual(1) 8 | }) 9 | 10 | test('minimumEditDistance(school, skull) => 4', () => { 11 | const str1 = 'school' 12 | const str2 = 'skull' 13 | const res = minimumEditDistance(str1, str2) 14 | expect(res).toEqual(4) 15 | }) 16 | 17 | test('minimumEditDistance(Algorithm, Algorithm) => 0', () => { 18 | const str1 = 'Algorithm' 19 | const str2 = 'Algorithm' 20 | const res = minimumEditDistance(str1, str2) 21 | expect(res).toEqual(0) 22 | }) 23 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/FastFibonacciNumber.test.js: -------------------------------------------------------------------------------- 1 | import { fastFibonacci } from '../FastFibonacciNumber' 2 | 3 | describe('Testing FibonacciNumber', () => { 4 | const errorCases = ['0', '12', true] 5 | 6 | test.each(errorCases)('throws an error if %p is invalid', (input) => { 7 | expect(() => { 8 | fastFibonacci(input) 9 | }).toThrow() 10 | }) 11 | 12 | const testCases = [ 13 | [0, 0], 14 | [1, 1], 15 | [10, 55], 16 | [25, 75025], 17 | [40, 102334155] 18 | ] 19 | 20 | test.each(testCases)('if input is %i it returns %i', (input, expected) => { 21 | expect(fastFibonacci(input)).toBe(expected) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/FibonacciNumber.test.js: -------------------------------------------------------------------------------- 1 | import { fibonacci } from '../FibonacciNumber' 2 | 3 | describe('Testing FibonacciNumber', () => { 4 | it('Testing for invalid type', () => { 5 | expect(() => fibonacci('0')).toThrowError() 6 | expect(() => fibonacci('12')).toThrowError() 7 | expect(() => fibonacci(true)).toThrowError() 8 | }) 9 | 10 | it('fibonacci of 0', () => { 11 | expect(fibonacci(0)).toBe(0) 12 | }) 13 | 14 | it('fibonacci of 1', () => { 15 | expect(fibonacci(1)).toBe(1) 16 | }) 17 | 18 | it('fibonacci of 10', () => { 19 | expect(fibonacci(10)).toBe(55) 20 | }) 21 | 22 | it('fibonacci of 25', () => { 23 | expect(fibonacci(25)).toBe(75025) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/KadaneAlgo.test.js: -------------------------------------------------------------------------------- 1 | import { kadaneAlgo } from '../KadaneAlgo' 2 | test('it is being checked that 15 is the answer to the corresponding array input', () => { 3 | expect(kadaneAlgo([1, 2, 3, 4, 5])).toBe(15) 4 | }) 5 | 6 | test('it is being checked that 5 is the answer to the corresponding array input', () => { 7 | expect(kadaneAlgo([-1, -2, -3, -4, 5])).toBe(5) 8 | }) 9 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/LevenshteinDistance.test.js: -------------------------------------------------------------------------------- 1 | import { calculateLevenshteinDp } from '../LevenshteinDistance' 2 | 3 | test('Should return the distance counting additions and removals', () => { 4 | const from = 'kitten' 5 | const to = 'sitting' 6 | expect(calculateLevenshteinDp(from, to)).toBe(3) 7 | }) 8 | 9 | test('Should return the distance based on replacements in the middle of the strings', () => { 10 | const from = 'book' 11 | const to = 'back' 12 | expect(calculateLevenshteinDp(from, to)).toBe(2) 13 | }) 14 | 15 | test('Should return the distance for strings with different length', () => { 16 | const from = 'sunday' 17 | const to = 'saturday' 18 | expect(calculateLevenshteinDp(from, to)).toBe(3) 19 | }) 20 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/LongestPalindromicSubsequence.test.js: -------------------------------------------------------------------------------- 1 | import { longestPalindromeSubsequence } from '../LongestPalindromicSubsequence' 2 | 3 | describe('LongestPalindromicSubsequence', () => { 4 | it('expects to return 1 as longest palindromic subsequence', () => { 5 | expect(longestPalindromeSubsequence('abcdefgh')).toBe(1) 6 | }) 7 | 8 | it('expects to return 4 as longest palindromic subsequence', () => { 9 | expect(longestPalindromeSubsequence('bbbab')).toBe(4) 10 | }) 11 | 12 | it('expects to return 2 as longest palindromic subsequence', () => { 13 | expect(longestPalindromeSubsequence('cbbd')).toBe(2) 14 | }) 15 | 16 | it('expects to return 7 as longest palindromic subsequence', () => { 17 | expect(longestPalindromeSubsequence('racexyzcxar')).toBe(7) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/LongestValidParentheses.test.js: -------------------------------------------------------------------------------- 1 | import { longestValidParentheses } from '../LongestValidParentheses' 2 | 3 | describe('longestValidParentheses', () => { 4 | it('expects to return 0 as longest valid parentheses substring', () => { 5 | expect(longestValidParentheses('')).toBe(0) 6 | }) 7 | 8 | it('expects to return 2 as longest valid parentheses substring', () => { 9 | expect(longestValidParentheses('(()')).toBe(2) 10 | }) 11 | 12 | it('expects to return 2 as longest valid parentheses substring', () => { 13 | expect(longestValidParentheses(')()())')).toBe(4) 14 | }) 15 | 16 | it('expects to return 2 as longest valid parentheses substring', () => { 17 | expect(longestValidParentheses('(((')).toBe(0) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/NumberOfSubsetEqualToGivenSum.test.js: -------------------------------------------------------------------------------- 1 | import { NumberOfSubsetSum } from '../NumberOfSubsetEqualToGivenSum' 2 | 3 | describe('Testing NumberOfSubsetSum', () => { 4 | it.each([ 5 | [[], 0, 1], 6 | [[], 1, 0], 7 | [[1], 2, 0], 8 | [[1, 2, 3, 4, 5], 0, 1], 9 | [[1, 1, 1, 1, 1], 5, 1], 10 | [[1, 1, 1, 1, 1], 4, 5], 11 | [[1, 2, 3, 3], 6, 3], 12 | [[10, 20, 30, 1], 31, 2], 13 | [[1, 1, 2, 2, 3, 1, 1], 4, 18] 14 | ])('check with %j and %i', (arr, sum, expected) => { 15 | expect(NumberOfSubsetSum(arr, sum)).toBe(expected) 16 | }) 17 | 18 | it.each([ 19 | [[1, 2], -1], 20 | [[0, 2], 2], 21 | [[1, -1], 0] 22 | ])('throws for %j and %i', (arr, sum) => { 23 | expect(() => NumberOfSubsetSum(arr, sum)).toThrowError() 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/RodCutting.test.js: -------------------------------------------------------------------------------- 1 | import { rodCut } from '../RodCutting' 2 | 3 | test('Test Case 1', () => { 4 | expect(rodCut([1, 5, 8, 9, 10, 17, 17, 20], 8)).toBe(22) 5 | }) 6 | 7 | test('Test Case 2', () => { 8 | expect(rodCut([1, 5, 4, 2, 1, 11, 19, 12], 8)).toBe(20) 9 | }) 10 | 11 | test('Test Case 3', () => { 12 | expect(rodCut([1, 2, 1], 3)).toBe(3) 13 | }) 14 | 15 | test('Test Case 4', () => { 16 | expect(rodCut([5, 4, 3, 2, 1], 5)).toBe(25) 17 | }) 18 | 19 | test('Test Case 5', () => { 20 | expect(rodCut([3, 5, 8, 8, 10, 16, 14, 19], 8)).toBe(24) 21 | }) 22 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/SieveOfEratosthenes.test.js: -------------------------------------------------------------------------------- 1 | import { sieveOfEratosthenes } from '../SieveOfEratosthenes' 2 | 3 | describe('SieveOfEratosthenes', () => { 4 | it('Primes till 0', () => { 5 | expect(sieveOfEratosthenes(0)).toEqual([]) 6 | }) 7 | 8 | it('Primes till 1', () => { 9 | expect(sieveOfEratosthenes(1)).toEqual([]) 10 | }) 11 | 12 | it('Primes till 10', () => { 13 | expect(sieveOfEratosthenes(10)).toEqual([2, 3, 5, 7]) 14 | }) 15 | 16 | it('Primes till 23', () => { 17 | expect(sieveOfEratosthenes(23)).toEqual([2, 3, 5, 7, 11, 13, 17, 19, 23]) 18 | }) 19 | 20 | it('Primes till 70', () => { 21 | expect(sieveOfEratosthenes(70)).toEqual([ 22 | 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67 23 | ]) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/TrappingRainWater.test.js: -------------------------------------------------------------------------------- 1 | import { trap } from '../TrappingRainWater' 2 | 3 | describe('TrappingRainWater', () => { 4 | it('expects 6 units of rain water are being trapped', () => { 5 | expect(trap([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1])).toBe(6) 6 | }) 7 | 8 | it('expects 9 units of rain water are being trapped', () => { 9 | expect(trap([4, 2, 0, 3, 2, 5])).toBe(9) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/TribonacciNumber.test.js: -------------------------------------------------------------------------------- 1 | import { tribonacci } from '../TribonacciNumber' 2 | 3 | describe('TribonacciNumber', () => { 4 | it('tribonacci of 0', () => { 5 | expect(tribonacci(0)).toBe(0) 6 | }) 7 | 8 | it('tribonacci of 1', () => { 9 | expect(tribonacci(1)).toBe(1) 10 | }) 11 | 12 | it('tribonacci of 2', () => { 13 | expect(tribonacci(2)).toBe(1) 14 | }) 15 | 16 | it('tribonacci of 10', () => { 17 | expect(tribonacci(10)).toBe(149) 18 | }) 19 | 20 | it('tribonacci of 25', () => { 21 | expect(tribonacci(25)).toBe(1389537) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/UniquePaths.test.js: -------------------------------------------------------------------------------- 1 | import { uniquePaths } from '../UniquePaths' 2 | 3 | describe('Unique Paths', () => { 4 | it('should return 28 when m is 3 and n is 7', () => { 5 | expect(uniquePaths(3, 7)).toBe(28) 6 | }) 7 | 8 | it('should return 48620 when m is 10 and n is 10', () => { 9 | expect(uniquePaths(10, 10)).toBe(48620) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Geometry/Circle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This class represents a circle and can calculate it's perimeter and area 3 | * https://en.wikipedia.org/wiki/Circle 4 | * @constructor 5 | * @param {number} radius - The radius of the circle. 6 | */ 7 | export default class Circle { 8 | constructor(radius) { 9 | this.radius = radius 10 | } 11 | 12 | perimeter = () => { 13 | return this.radius * 2 * Math.PI 14 | } 15 | 16 | area = () => { 17 | return Math.pow(this.radius, 2) * Math.PI 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Geometry/Cone.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This class represents a circular cone and can calculate its volume and surface area 3 | * https://en.wikipedia.org/wiki/Cone 4 | * @constructor 5 | * @param {number} baseRadius - The radius of the base of the cone. 6 | * @param {number} height - The height of the cone 7 | */ 8 | export default class Cone { 9 | constructor(baseRadius, height) { 10 | this.baseRadius = baseRadius 11 | this.height = height 12 | } 13 | 14 | baseArea = () => { 15 | return Math.pow(this.baseRadius, 2) * Math.PI 16 | } 17 | 18 | volume = () => { 19 | return (this.baseArea() * this.height * 1) / 3 20 | } 21 | 22 | surfaceArea = () => { 23 | return ( 24 | this.baseArea() + 25 | Math.PI * 26 | this.baseRadius * 27 | Math.sqrt(Math.pow(this.baseRadius, 2) + Math.pow(this.height, 2)) 28 | ) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Geometry/Pyramid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This class represents a regular pyramid and can calculate its volume and surface area 3 | * https://en.wikipedia.org/wiki/Pyramid_(geometry) 4 | * @constructor 5 | * @param {number} bsl - The side length of the base of the pyramid. 6 | * @param {number} height - The height of the pyramid 7 | */ 8 | export default class Pyramid { 9 | constructor(bsl, height) { 10 | this.bsl = bsl 11 | this.height = height 12 | } 13 | 14 | baseArea = () => { 15 | return Math.pow(this.bsl, 2) 16 | } 17 | 18 | volume = () => { 19 | return (this.baseArea() * this.height) / 3 20 | } 21 | 22 | surfaceArea = () => { 23 | return ( 24 | this.baseArea() + 25 | ((this.bsl * 4) / 2) * 26 | Math.sqrt(Math.pow(this.bsl / 2, 2) + Math.pow(this.height, 2)) 27 | ) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Geometry/Sphere.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This class represents a sphere and can calculate its volume and surface area 3 | * @constructor 4 | * @param {number} radius - The radius of the sphere 5 | * @see https://en.wikipedia.org/wiki/Sphere 6 | */ 7 | export default class Sphere { 8 | constructor(radius) { 9 | this.radius = radius 10 | } 11 | 12 | volume = () => { 13 | return (Math.pow(this.radius, 3) * Math.PI * 4) / 3 14 | } 15 | 16 | surfaceArea = () => { 17 | return Math.pow(this.radius, 2) * Math.PI * 4 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Geometry/Test/Circle.test.js: -------------------------------------------------------------------------------- 1 | import Circle from '../Circle' 2 | 3 | const circle = new Circle(3) 4 | 5 | test('The area of a circle with radius equal to 3', () => { 6 | expect(parseFloat(circle.area().toFixed(2))).toEqual(28.27) 7 | }) 8 | 9 | test('The perimeter of a circle with radius equal to 3', () => { 10 | expect(parseFloat(circle.perimeter().toFixed(2))).toEqual(18.85) 11 | }) 12 | -------------------------------------------------------------------------------- /Geometry/Test/Cone.test.js: -------------------------------------------------------------------------------- 1 | import Cone from '../Cone' 2 | 3 | const cone = new Cone(3, 5) 4 | 5 | test('The Volume of a cone with base radius equal to 3 and height equal to 5', () => { 6 | expect(parseFloat(cone.volume().toFixed(2))).toEqual(47.12) 7 | }) 8 | 9 | test('The Surface Area of a cone with base radius equal to 3 and height equal to 5', () => { 10 | expect(parseFloat(cone.surfaceArea().toFixed(2))).toEqual(83.23) 11 | }) 12 | -------------------------------------------------------------------------------- /Geometry/Test/Pyramid.test.js: -------------------------------------------------------------------------------- 1 | import Pyramid from '../Pyramid' 2 | 3 | const pyramid = new Pyramid(3, 5) 4 | 5 | test('The Volume of a cone with base radius equal to 3 and height equal to 5', () => { 6 | expect(parseFloat(pyramid.volume().toFixed(2))).toEqual(15) 7 | }) 8 | 9 | test('The Surface Area of a cone with base radius equal to 3 and height equal to 5', () => { 10 | expect(parseFloat(pyramid.surfaceArea().toFixed(2))).toEqual(40.32) 11 | }) 12 | -------------------------------------------------------------------------------- /Geometry/Test/Sphere.test.js: -------------------------------------------------------------------------------- 1 | import Sphere from '../Sphere' 2 | 3 | const sphere = new Sphere(3) 4 | 5 | test('The Volume of a sphere with base radius equal to 3 and height equal to 5', () => { 6 | expect(parseFloat(sphere.volume().toFixed(2))).toEqual(113.1) 7 | }) 8 | 9 | test('The Surface Area of a sphere with base radius equal to 3 and height equal to 5', () => { 10 | expect(parseFloat(sphere.surfaceArea().toFixed(2))).toEqual(113.1) 11 | }) 12 | -------------------------------------------------------------------------------- /Graphs/Density.js: -------------------------------------------------------------------------------- 1 | /* 2 | The density of a network is a measure of how many edges exist proportional to 3 | how many edges would exist in a complete network (where all possible edges). 4 | https://networkx.org/documentation/networkx-1.9/reference/generated/networkx.classes.function.density.html 5 | */ 6 | function density(numberOfNodes, numberOfEdges, isDirected = false) { 7 | const multi = isDirected ? 1 : 2 8 | return (multi * numberOfEdges) / (numberOfNodes * (numberOfNodes - 1)) 9 | } 10 | 11 | export { density } 12 | -------------------------------------------------------------------------------- /Graphs/test/Kosaraju.test.js: -------------------------------------------------------------------------------- 1 | import { kosaraju } from '../Kosaraju.js' 2 | 3 | test('Test Case 1', () => { 4 | const graph = [ 5 | [1, 2], 6 | [2, 3], 7 | [3, 1], 8 | [2, 4], 9 | [4, 5], 10 | [5, 6], 11 | [6, 4] 12 | ] 13 | const stronglyConnectedComponents = kosaraju(graph) 14 | expect(stronglyConnectedComponents).toStrictEqual([ 15 | [1, 3, 2], 16 | [4, 6, 5] 17 | ]) 18 | }) 19 | 20 | test('Test Case 2', () => { 21 | const graph = [ 22 | [1, 2], 23 | [2, 3], 24 | [3, 1], 25 | [2, 4], 26 | [4, 5] 27 | ] 28 | const stronglyConnectedComponents = kosaraju(graph) 29 | expect(stronglyConnectedComponents).toStrictEqual([[1, 3, 2], [4], [5]]) 30 | }) 31 | -------------------------------------------------------------------------------- /Graphs/test/NumberOfIslands.test.js: -------------------------------------------------------------------------------- 1 | import { islands } from '../NumberOfIslands' 2 | 3 | describe('Number of Islands', () => { 4 | test('Graph with three islands', () => { 5 | const graph = [ 6 | ['1', '1', '0', '0', '0'], 7 | ['1', '1', '0', '0', '0'], 8 | ['0', '0', '1', '0', '0'], 9 | ['0', '0', '0', '1', '1'] 10 | ] 11 | expect(islands(graph)).toBe(3) 12 | }) 13 | 14 | test('Graph with only one island', () => { 15 | const graph = [ 16 | ['1', '1'], 17 | ['1', '1'], 18 | ['0', '0'], 19 | ['0', '0'] 20 | ] 21 | expect(islands(graph)).toBe(1) 22 | }) 23 | 24 | test('No islands', () => { 25 | const graph = [ 26 | ['0', '0'], 27 | ['0', '0'] 28 | ] 29 | expect(islands(graph)).toBe(0) 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /Graphs/test/PrimMST.test.js: -------------------------------------------------------------------------------- 1 | import { GraphWeightedUndirectedAdjacencyList } from '../PrimMST.js' 2 | 3 | test('Test Case PrimMST 1', () => { 4 | // create graph to compute MST on 5 | const graph = new GraphWeightedUndirectedAdjacencyList() 6 | graph.addEdge(1, 2, 1) 7 | graph.addEdge(2, 3, 2) 8 | graph.addEdge(3, 4, 1) 9 | graph.addEdge(3, 5, 100) // Removed in MST 10 | graph.addEdge(4, 5, 5) 11 | // create expected graph 12 | const expectedGraph = new GraphWeightedUndirectedAdjacencyList() 13 | expectedGraph.addEdge(1, 2, 1) 14 | expectedGraph.addEdge(2, 3, 2) 15 | expectedGraph.addEdge(3, 4, 1) 16 | expectedGraph.addEdge(4, 5, 5) 17 | // result from MST 18 | const res = graph.PrimMST(1) 19 | expect(res).toEqual(expectedGraph) 20 | }) 21 | -------------------------------------------------------------------------------- /Maths/Abs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function abs 3 | * @description This script will find the absolute value of a number. 4 | * @param {number} num - The input integer 5 | * @return {number} - Absolute number of num. 6 | * @see https://en.wikipedia.org/wiki/Absolute_value 7 | * @example abs(-10) = 10 8 | * @example abs(50) = 50 9 | * @example abs(0) = 0 10 | */ 11 | 12 | const abs = (num) => { 13 | const validNumber = +num // converted to number, also can use - Number(num) 14 | 15 | if (Number.isNaN(validNumber) || typeof num === 'object') { 16 | throw new TypeError('Argument is NaN - Not a Number') 17 | } 18 | 19 | return validNumber < 0 ? -validNumber : validNumber // if number is less than zero mean negative then it converted to positive. i.e -> n = -2 = -(-2) = 2 20 | } 21 | 22 | export { abs } 23 | -------------------------------------------------------------------------------- /Maths/ArmstrongNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: dephraiim 3 | * License: GPL-3.0 or later 4 | * 5 | * An Armstrong number is equal to the sum of its own digits each raised to the power of the number of digits. 6 | * For example, 370 is an Armstrong number because 3*3*3 + 7*7*7 + 0*0*0 = 370. 7 | * An Armstrong number is often called Narcissistic number. 8 | * 9 | */ 10 | 11 | const armstrongNumber = (num) => { 12 | if (typeof num !== 'number' || num < 0) return false 13 | const numStr = num.toString() 14 | const sum = [...numStr].reduce( 15 | (acc, digit) => acc + parseInt(digit) ** numStr.length, 16 | 0 17 | ) 18 | return sum === num 19 | } 20 | 21 | export { armstrongNumber } 22 | -------------------------------------------------------------------------------- /Maths/AverageMean.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function mean 3 | * @description This script will find the mean value of a array of numbers. 4 | * @param {Integer[]} nums - Array of integer 5 | * @return {Integer} - mean of nums. 6 | * @see [Mean](https://en.wikipedia.org/wiki/Mean) 7 | * @example mean([1, 2, 4, 5]) = 3 8 | * @example mean([10, 40, 100, 20]) = 42.5 9 | */ 10 | 11 | const mean = (nums) => { 12 | if (!Array.isArray(nums)) { 13 | throw new TypeError('Invalid Input') 14 | } 15 | 16 | return nums.reduce((sum, cur) => sum + cur, 0) / nums.length 17 | } 18 | 19 | export { mean } 20 | -------------------------------------------------------------------------------- /Maths/BinaryConvert.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function BinaryConvert 3 | * @description Convert the decimal to binary. 4 | * @param {Integer} num - The input integer 5 | * @return {Integer} - Binary of num. 6 | * @see [BinaryConvert](https://www.programiz.com/javascript/examples/decimal-binary) 7 | * @example BinaryConvert(12) = 1100 8 | * @example BinaryConvert(12 + 2) = 1110 9 | */ 10 | 11 | const BinaryConvert = (num) => { 12 | let power = 1 13 | let binary = 0 14 | 15 | while (num) { 16 | const rem = num % 2 17 | num = Math.floor(num / 2) 18 | binary = rem * power + binary 19 | power *= 10 20 | } 21 | 22 | return binary 23 | } 24 | 25 | export { BinaryConvert } 26 | -------------------------------------------------------------------------------- /Maths/BinaryExponentiationIterative.js: -------------------------------------------------------------------------------- 1 | // To calculate x^n i.e. exponent(x, n) in O(log n) time in iterative way 2 | // n is an integer and n >= 0 3 | 4 | // Explanation: https://en.wikipedia.org/wiki/Exponentiation_by_squaring 5 | 6 | // Examples: 7 | // 2^3 = 8 8 | // 5^0 = 1 9 | 10 | // Uses the fact that 11 | // exponent(x, n) 12 | // = exponent(x*x, floor(n/2)) ; if n is odd 13 | // = x*exponent(x*x, floor(n/2)) ; if n is even 14 | const exponent = (x, n) => { 15 | let answer = 1 16 | while (n > 0) { 17 | if (n % 2 !== 0) answer *= x 18 | n = Math.floor(n / 2) 19 | if (n > 0) x *= x 20 | } 21 | return answer 22 | } 23 | 24 | export { exponent } 25 | -------------------------------------------------------------------------------- /Maths/BinaryExponentiationRecursive.js: -------------------------------------------------------------------------------- 1 | /* 2 | Modified from: 3 | https://github.com/TheAlgorithms/Python/blob/master/maths/binary_exponentiation.py 4 | 5 | Explanation: 6 | https://en.wikipedia.org/wiki/Exponentiation_by_squaring 7 | */ 8 | 9 | export const binaryExponentiation = (a, n) => { 10 | // input: a: int, n: int 11 | // returns: a^n: int 12 | if (n === 0) { 13 | return 1 14 | } else if (n % 2 === 1) { 15 | return binaryExponentiation(a, n - 1) * a 16 | } else { 17 | const b = binaryExponentiation(a, n / 2) 18 | return b * b 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Maths/Coordinate.js: -------------------------------------------------------------------------------- 1 | /* 2 | Calculate the mathematical properties involving coordinates 3 | Calculate the Distance Between 2 Points on a 2 Dimensional Plane 4 | Example: coorDistance(2,2,14,11) will return 15 5 | Wikipedia reference: https://en.wikipedia.org/wiki/Geographical_distance#Flat-surface_formulae 6 | */ 7 | const euclideanDistance = (longitude1, latitude1, longitude2, latitude2) => { 8 | const width = longitude2 - longitude1 9 | const height = latitude2 - latitude1 10 | return Math.sqrt(width * width + height * height) 11 | } 12 | 13 | const manhattanDistance = (longitude1, latitude1, longitude2, latitude2) => { 14 | const width = Math.abs(longitude2 - longitude1) 15 | const height = Math.abs(latitude2 - latitude1) 16 | return width + height 17 | } 18 | 19 | export { euclideanDistance, manhattanDistance } 20 | -------------------------------------------------------------------------------- /Maths/DecimalIsolate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * function isolates the decimal part of a number. 3 | * Take the number and subtract it from the floored number. 4 | * Return the result. 5 | */ 6 | 7 | export const decimalIsolate = (number) => { 8 | const answer = parseFloat((number + '').replace(/^[-\d]+./, '.')) 9 | return isNaN(answer) === true ? 0 : answer 10 | } 11 | -------------------------------------------------------------------------------- /Maths/DegreeToRadian.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Radian : https://en.wikipedia.org/wiki/Radian 3 | * Degree : https://en.wikipedia.org/wiki/Degree_(angle) 4 | * 5 | * Angle in Radian = ( Angle in Degree ) x ( pi / 180 ) 6 | * 7 | * Example : 8 | * Question : Convert 90 degree to radian 9 | * So, Angle in Degree = 90 10 | * 11 | * Solution : 12 | * Angle in Radian = ( 90 ) x ( pi / 180 ) = pi / 2 13 | * 14 | * So, 90 degree is equal to pi / 2 radian 15 | */ 16 | 17 | /** 18 | * @param {number} degree 19 | * @return {number} 20 | */ 21 | export const degreeToRadian = (degree) => { 22 | return degree * (Math.PI / 180) 23 | } 24 | -------------------------------------------------------------------------------- /Maths/EuclideanDistance.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @see [Wikipedia](https://en.wikipedia.org/wiki/Euclidean_distance) 3 | * Calculate the Euclidean distance between two vectors. 4 | * @param {number[]} vector1 - The first vector. 5 | * @param {number[]} vector2 - The second vector. 6 | * @returns {number} The Euclidean distance between the two vectors. 7 | */ 8 | 9 | const EuclideanDistance = (vector1, vector2) => { 10 | let sumOfSquares = 0 11 | 12 | for (let i = 0; i < vector1.length; i++) { 13 | sumOfSquares += Math.pow(vector1[i] - vector2[i], 2) 14 | } 15 | 16 | return Math.sqrt(sumOfSquares) 17 | } 18 | 19 | export { EuclideanDistance } 20 | -------------------------------------------------------------------------------- /Maths/EulersTotient.js: -------------------------------------------------------------------------------- 1 | /* 2 | Source: 3 | https://en.wikipedia.org/wiki/Euler%27s_totient_function 4 | 5 | EulersTotient(n) = n * product(1 - 1/p for all prime p dividing n) 6 | 7 | Complexity: 8 | O(sqrt(n)) 9 | */ 10 | 11 | export const EulersTotient = (n) => { 12 | // input: n: int 13 | // output: phi(n): count of numbers b/w 1 and n that are coprime to n 14 | let res = n 15 | for (let i = 2; i * i <= n; i++) { 16 | if (n % i === 0) { 17 | while (n % i === 0) { 18 | n = Math.floor(n / i) 19 | } 20 | // i is a prime diving n, multiply res by 1 - 1/i 21 | // res = res * (1 - 1/i) = res - (res / i) 22 | res = res - Math.floor(res / i) 23 | } 24 | } 25 | if (n > 1) { 26 | res = res - Math.floor(res / n) 27 | } 28 | return res 29 | } 30 | -------------------------------------------------------------------------------- /Maths/ExponentialFunction.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function exponentialFunction 3 | * @description Calculates the n+1 th order Taylor series approximation of exponential function e^x given n 4 | * @param {Integer} power 5 | * @param {Integer} order - 1 6 | * @returns exponentialFunction(2,20) = 7.3890560989301735 7 | * @url https://en.wikipedia.org/wiki/Exponential_function 8 | */ 9 | function exponentialFunction(power, n) { 10 | let output = 0 11 | let fac = 1 12 | if (isNaN(power) || isNaN(n) || n < 0) { 13 | throw new TypeError('Invalid Input') 14 | } 15 | if (n === 0) { 16 | return 1 17 | } 18 | for (let i = 0; i < n; i++) { 19 | output += power ** i / fac 20 | fac *= i + 1 21 | } 22 | return output 23 | } 24 | 25 | export { exponentialFunction } 26 | -------------------------------------------------------------------------------- /Maths/Factors.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: dephraiim 3 | * License: GPL-3.0 or later 4 | * 5 | * More on Factors: 6 | * https://www.mathsisfun.com/definitions/factor.html 7 | * 8 | */ 9 | 10 | const factorsOfANumber = (number = 0) => { 11 | return Array.from(Array(number + 1).keys()).filter( 12 | (num) => number % num === 0 13 | ) 14 | } 15 | 16 | export { factorsOfANumber } 17 | -------------------------------------------------------------------------------- /Maths/FindMin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function FindMin 3 | * @description Function to find the minimum number given in an array of integers. 4 | * @param {Integer[]} nums - Array of Integers 5 | * @return {Integer} - The minimum number of the array. 6 | */ 7 | 8 | const findMin = (...nums) => { 9 | if (nums.length === 0) { 10 | throw new TypeError('Array is empty') 11 | } 12 | 13 | let min = nums[0] 14 | for (let i = 1; i < nums.length; i++) { 15 | if (nums[i] < min) { 16 | min = nums[i] 17 | } 18 | } 19 | 20 | return min 21 | } 22 | 23 | export { findMin } 24 | -------------------------------------------------------------------------------- /Maths/HexagonalNumber.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Akshay Dubey (https://github.com/itsAkshayDubey) 3 | * Hexagonal Number: https://en.wikipedia.org/wiki/Hexagonal_number 4 | * The nth hexagonal number hn is the number of distinct dots in a pattern of dots 5 | * consisting of the outlines of regular hexagons with sides up to n dots, when the 6 | * hexagons are overlaid so that they share one vertex. 7 | */ 8 | 9 | /** 10 | * @function hexagonalNumber 11 | * @description -> returns nth hexagonal number 12 | * @param {Integer} number 13 | * @returns {Integer} nth hexagonal number 14 | */ 15 | 16 | export const hexagonalNumber = (number) => { 17 | if (number <= 0) { 18 | throw new Error('Number must be greater than zero.') 19 | } 20 | return number * (2 * number - 1) 21 | } 22 | -------------------------------------------------------------------------------- /Maths/IsDivisible.js: -------------------------------------------------------------------------------- 1 | // Checks if a number is divisible by another number. 2 | 3 | export const isDivisible = (num1, num2) => { 4 | if (!Number.isFinite(num1) || !Number.isFinite(num2)) { 5 | throw new TypeError('Expected a valid real number') 6 | } 7 | if (num2 === 0) { 8 | return false 9 | } 10 | return num1 % num2 === 0 11 | } 12 | 13 | // isDivisible(10, 5) // returns true 14 | // isDivisible(123498175, 5) // returns true 15 | // isDivisible(99, 5) // returns false 16 | -------------------------------------------------------------------------------- /Maths/LeapYear.js: -------------------------------------------------------------------------------- 1 | /** 2 | * isLeapYear :: Number -> Boolean 3 | * 4 | * Check if a year is a leap year or not. A leap year is a year which has 366 days. 5 | * For the extra +1 day the February month contains 29 days instead of 28 days. 6 | * 7 | * The logic behind the leap year is- 8 | * 1. If the year is divisible by 400 then it is a leap year. 9 | * 2. If it is not divisible by 400 but divisible by 100 then it is not a leap year. 10 | * 3. If the year is not divisible by both 400 and 100 but divisible by 4 then a leap year. 11 | * 4. Other cases except the describing ones are not a leap year. 12 | * 13 | * @param {number} year 14 | * @returns {boolean} true if this is a leap year, false otherwise. 15 | */ 16 | export const isLeapYear = (year) => { 17 | return year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0) 18 | } 19 | -------------------------------------------------------------------------------- /Maths/LinearSieve.js: -------------------------------------------------------------------------------- 1 | const LinearSieve = (n) => { 2 | /* 3 | * Calculates prime numbers till a number n 4 | * Time Complexity: O(n) 5 | * Explanation: https://cp-algorithms.com/algebra/prime-sieve-linear.html 6 | * :param n: Number up to which to calculate primes 7 | * :return: A list containing only primes 8 | */ 9 | const isnPrime = new Array(n + 1) 10 | isnPrime[0] = isnPrime[1] = true 11 | const primes = [] 12 | for (let i = 2; i <= n; i++) { 13 | if (!isnPrime[i]) primes.push(i) 14 | for (const p of primes) { 15 | const k = i * p 16 | if (k > n) break 17 | isnPrime[k] = true 18 | if (i % p === 0) break 19 | } 20 | } 21 | return primes 22 | } 23 | 24 | export { LinearSieve } 25 | -------------------------------------------------------------------------------- /Maths/LucasSeries.js: -------------------------------------------------------------------------------- 1 | /* 2 | Program to get the Nth Lucas Number 3 | Article on Lucas Number: https://en.wikipedia.org/wiki/Lucas_number 4 | Examples: 5 | > loopLucas(1) 6 | 1 7 | > loopLucas(20) 8 | 15127 9 | > loopLucas(100) 10 | 792070839848372100000 11 | */ 12 | 13 | /** 14 | * @param {Number} index The position of the number you want to get from the Lucas Series 15 | */ 16 | function lucas(index) { 17 | // index can't be negative 18 | if (index < 0) throw new TypeError('Index cannot be Negative') 19 | 20 | // index can't be a decimal 21 | if (Math.floor(index) !== index) 22 | throw new TypeError('Index cannot be a Decimal') 23 | 24 | let a = 2 25 | let b = 1 26 | for (let i = 0; i < index; i++) { 27 | const temp = a + b 28 | a = b 29 | b = temp 30 | } 31 | return a 32 | } 33 | 34 | export { lucas } 35 | -------------------------------------------------------------------------------- /Maths/MeanAbsoluteDeviation.js: -------------------------------------------------------------------------------- 1 | import { mean } from './AverageMean.js' 2 | /** 3 | *@function meanAbsoluteDeviation 4 | *@description Calculates the mean absolute deviation of list of numbers 5 | * @param {Integer} data 6 | * @returns meanAbsoluteDeviation([2,34,5,0,-2]) = 10.480 7 | * @url https://en.wikipedia.org/wiki/Average_absolute_deviation 8 | */ 9 | function meanAbsoluteDeviation(data) { 10 | if (!Array.isArray(data)) { 11 | throw new TypeError('Invalid Input') 12 | } 13 | let absoluteSum = 0 14 | const meanValue = mean(data) 15 | for (const dataPoint of data) { 16 | absoluteSum += Math.abs(dataPoint - meanValue) 17 | } 18 | return absoluteSum / data.length 19 | } 20 | 21 | export { meanAbsoluteDeviation } 22 | -------------------------------------------------------------------------------- /Maths/MeanSquareError.js: -------------------------------------------------------------------------------- 1 | // Wikipedia: https://en.wikipedia.org/wiki/Mean_squared_error 2 | 3 | const meanSquaredError = (predicted, expected) => { 4 | if (!Array.isArray(predicted) || !Array.isArray(expected)) { 5 | throw new TypeError('Argument must be an Array') 6 | } 7 | 8 | if (predicted.length !== expected.length) { 9 | throw new TypeError('The two lists must be of equal length') 10 | } 11 | 12 | let err = 0 13 | 14 | for (let i = 0; i < expected.length; i++) { 15 | err += (expected[i] - predicted[i]) ** 2 16 | } 17 | 18 | return err / expected.length 19 | } 20 | 21 | export { meanSquaredError } 22 | -------------------------------------------------------------------------------- /Maths/ModularBinaryExponentiationRecursive.js: -------------------------------------------------------------------------------- 1 | /* 2 | Modified from: 3 | https://github.com/TheAlgorithms/Python/blob/master/maths/binary_exp_mod.py 4 | 5 | Explanation: 6 | https://en.wikipedia.org/wiki/Exponentiation_by_squaring 7 | */ 8 | 9 | const modularBinaryExponentiation = (a, n, m) => { 10 | // input: a: int, n: int, m: int 11 | // returns: (a^n) % m: int 12 | if (n === 0) { 13 | return 1 14 | } else if (n % 2 === 1) { 15 | return (modularBinaryExponentiation(a, n - 1, m) * a) % m 16 | } else { 17 | const b = modularBinaryExponentiation(a, n / 2, m) 18 | return (b * b) % m 19 | } 20 | } 21 | 22 | export { modularBinaryExponentiation } 23 | -------------------------------------------------------------------------------- /Maths/NumberOfDigits.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: dephraiim 4 | * License: GPL-3.0 or later 5 | * 6 | * Returns the number of digits of a given integer 7 | * 8 | */ 9 | 10 | const numberOfDigit = (n) => Math.abs(n).toString().length 11 | 12 | /** 13 | * Returns the number of digits of a given integer. 14 | * 15 | * @param {number} n - The integer for which to count digits. 16 | * @returns {number} The number of digits in the integer. 17 | * @see https://math.stackexchange.com/questions/2145480/how-does-the-logarithm-returns-the-number-of-digits-of-a-number 18 | * @author dev-madhurendra 19 | */ 20 | const numberOfDigitsUsingLog = (n) => 21 | n === 0 ? 1 : Math.floor(Math.log10(Math.abs(n))) + 1 22 | 23 | export { numberOfDigit, numberOfDigitsUsingLog } 24 | -------------------------------------------------------------------------------- /Maths/PascalTriangle.js: -------------------------------------------------------------------------------- 1 | const addRow = (triangle) => { 2 | const previous = triangle[triangle.length - 1] 3 | const newRow = [1] 4 | for (let i = 0; i < previous.length - 1; i++) { 5 | const current = previous[i] 6 | const next = previous[i + 1] 7 | newRow.push(current + next) 8 | } 9 | newRow.push(1) 10 | return triangle.push(newRow) 11 | } 12 | 13 | const generate = (numRows) => { 14 | const triangle = [[1], [1, 1]] 15 | 16 | if (numRows === 0) { 17 | return [] 18 | } else if (numRows === 1) { 19 | return [[1]] 20 | } else { 21 | for (let i = 2; i < numRows; i++) { 22 | addRow(triangle) 23 | } 24 | } 25 | return triangle 26 | } 27 | 28 | export { generate } 29 | -------------------------------------------------------------------------------- /Maths/PerfectCube.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: dephraiim 3 | * License: GPL-3.0 or later 4 | * 5 | * This uses `round` instead of `floor` or `trunc`, to guard against potential `cbrt` accuracy errors 6 | */ 7 | 8 | const perfectCube = (num) => 9 | Number.isFinite(num) && Math.round(Math.cbrt(num)) ** 3 === num 10 | 11 | export { perfectCube } 12 | -------------------------------------------------------------------------------- /Maths/PerfectSquare.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: dephraiim 3 | * License: GPL-3.0 or later 4 | * 5 | * This uses `round` instead of `floor` or `trunc`, to guard against potential `sqrt` accuracy errors 6 | */ 7 | 8 | const perfectSquare = (num) => 9 | Number.isFinite(num) && Math.round(Math.sqrt(num)) ** 2 === num 10 | 11 | export { perfectSquare } 12 | -------------------------------------------------------------------------------- /Maths/PiApproximationMonteCarlo.js: -------------------------------------------------------------------------------- 1 | // Wikipedia: https://en.wikipedia.org/wiki/Monte_Carlo_method 2 | // Video Explanation: https://www.youtube.com/watch?v=ELetCV_wX_c 3 | 4 | const piEstimation = (iterations = 100000) => { 5 | let circleCounter = 0 6 | 7 | for (let i = 0; i < iterations; i++) { 8 | // generating random points and checking if it lies within a circle of radius 1 9 | const x = Math.random() 10 | const y = Math.random() 11 | const radius = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) 12 | 13 | if (radius < 1) circleCounter += 1 14 | } 15 | 16 | // formula for pi = (ratio of number inside circle and total iteration) x 4 17 | const pi = (circleCounter / iterations) * 4 18 | return pi 19 | } 20 | 21 | export { piEstimation } 22 | -------------------------------------------------------------------------------- /Maths/PrimeCheck.js: -------------------------------------------------------------------------------- 1 | /* 2 | Modified from: 3 | https://github.com/TheAlgorithms/Python/blob/master/maths/prime_check.py 4 | 5 | Complexity: 6 | O(sqrt(n)) 7 | */ 8 | 9 | const PrimeCheck = (n) => { 10 | // input: n: int 11 | // output: boolean 12 | if (n === 1) return false 13 | if (n === 0) return false 14 | if (n === 2) return true 15 | if (n % 2 === 0) return false 16 | 17 | for (let i = 3; i * i <= n; i += 2) { 18 | if (n % i === 0) { 19 | return false 20 | } 21 | } 22 | return true 23 | } 24 | 25 | export { PrimeCheck } 26 | -------------------------------------------------------------------------------- /Maths/PrimeFactors.js: -------------------------------------------------------------------------------- 1 | /* 2 | Modified from: 3 | https://github.com/TheAlgorithms/Python/blob/master/maths/prime_factors.py 4 | */ 5 | 6 | export const PrimeFactors = (n) => { 7 | // input: n: int 8 | // output: primeFactors: Array of all prime factors of n 9 | const primeFactors = [] 10 | for (let i = 2; i * i <= n; i++) { 11 | while (n % i === 0) { 12 | primeFactors.push(i) 13 | n = Math.floor(n / i) 14 | } 15 | } 16 | if (n > 1) { 17 | primeFactors.push(n) 18 | } 19 | return primeFactors 20 | } 21 | -------------------------------------------------------------------------------- /Maths/RadianToDegree.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Radian : https://en.wikipedia.org/wiki/Radian 3 | * Degree : https://en.wikipedia.org/wiki/Degree_(angle) 4 | * 5 | * Angle in Degree = ( Angle in Radian ) x ( 180 / pi ) 6 | * 7 | * Example : 8 | * Question : Convert pi / 2 degree to radian 9 | * So, Angle in Radian = pi / 2 10 | * 11 | * Solution : 12 | * Angle in Degree = ( pi / 2 ) x ( 180 / pi ) = 90 13 | * 14 | * So, pi / 2 radian is equal to 90 degree 15 | */ 16 | 17 | /** 18 | * @param {number} radian 19 | * @return {number} 20 | */ 21 | export const radianToDegree = (radian) => { 22 | return radian * (180 / Math.PI) 23 | } 24 | -------------------------------------------------------------------------------- /Maths/ReversePolishNotation.js: -------------------------------------------------------------------------------- 1 | // Wikipedia: https://en.wikipedia.org/wiki/Reverse_Polish_notation 2 | 3 | const calcRPN = (expression) => { 4 | const operators = { 5 | '+': (a, b) => a + b, 6 | '-': (a, b) => a - b, 7 | '*': (a, b) => a * b, 8 | '/': (a, b) => b / a 9 | } 10 | 11 | const tokens = expression.split(' ') 12 | 13 | const stack = [] 14 | 15 | tokens.forEach((token) => { 16 | const operator = operators[token] 17 | 18 | if (typeof operator === 'function') { 19 | const a = stack.pop() 20 | const b = stack.pop() 21 | 22 | const result = operator(a, b) 23 | 24 | stack.push(result) 25 | } else { 26 | stack.push(parseFloat(token)) 27 | } 28 | }) 29 | 30 | return stack.pop() 31 | } 32 | 33 | export { calcRPN } 34 | -------------------------------------------------------------------------------- /Maths/Signum.js: -------------------------------------------------------------------------------- 1 | /* 2 | A program to demonstrate the implementation of the signum function, 3 | also known as the sign function, in JavaScript. 4 | 5 | The signum function is an odd mathematical function, which returns the 6 | sign of the provided real number. 7 | It can return 3 values: 1 for values greater than zero, 0 for zero itself, 8 | and -1 for values less than zero 9 | 10 | Wikipedia: https://en.wikipedia.org/wiki/Sign_function 11 | */ 12 | 13 | /** 14 | * @param {Number} input 15 | * @returns {-1 | 0 | 1 | NaN} sign of input (and NaN if the input is not a number) 16 | */ 17 | function signum(input) { 18 | if (input === 0) return 0 19 | if (input > 0) return 1 20 | if (input < 0) return -1 21 | 22 | return NaN 23 | } 24 | 25 | export { signum } 26 | -------------------------------------------------------------------------------- /Maths/Softmax.js: -------------------------------------------------------------------------------- 1 | // Wikipedia: https://en.wikipedia.org/wiki/Softmax_function 2 | 3 | const Softmax = (inputs) => { 4 | const eulerExpOfAllInputs = inputs.map((input) => Math.exp(input)) 5 | const sumOfEulerExpOfAllInputs = eulerExpOfAllInputs.reduce((a, b) => a + b) 6 | 7 | return inputs.map((input) => { 8 | const eulerExpInputs = Math.exp(input) 9 | return eulerExpInputs / sumOfEulerExpOfAllInputs 10 | }) 11 | } 12 | 13 | export { Softmax } 14 | -------------------------------------------------------------------------------- /Maths/SquareRoot.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Rak Laptudirm 3 | * 4 | * https://en.wikipedia.org/wiki/Newton%27s_method 5 | * 6 | * Finding the square root of a number using Newton's method. 7 | */ 8 | 9 | function sqrt(num, precision = 4) { 10 | if (!Number.isFinite(num)) { 11 | throw new TypeError(`Expected a number, received ${typeof num}`) 12 | } 13 | if (!Number.isFinite(precision)) { 14 | throw new TypeError(`Expected a number, received ${typeof precision}`) 15 | } 16 | let sqrt = 1 17 | for (let i = 0; i < precision; i++) { 18 | sqrt -= (sqrt * sqrt - num) / (2 * sqrt) 19 | } 20 | return sqrt 21 | } 22 | 23 | export { sqrt } 24 | -------------------------------------------------------------------------------- /Maths/TwoSum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given an array of integers, find two numbers that add up to a specific target. 3 | * 4 | * @param {number[]} nums - The array of integers. 5 | * @param {number} target - The target sum. 6 | * @returns {number[]} - An array containing the indices of the two numbers. 7 | * 8 | * @example 9 | * const nums = [2, 7, 11, 15]; 10 | * const target = 9; 11 | * const result = twoSum(nums, target); 12 | * // The function should return [0, 1] because nums[0] + nums[1] = 2 + 7 = 9. 13 | */ 14 | 15 | const TwoSum = (nums, target) => { 16 | const numIndicesMap = new Map() 17 | for (let i = 0; i < nums.length; i++) { 18 | const complement = target - nums[i] 19 | if (numIndicesMap.has(complement)) return [numIndicesMap.get(complement), i] 20 | numIndicesMap.set(nums[i], i) 21 | } 22 | return [] 23 | } 24 | export { TwoSum } 25 | -------------------------------------------------------------------------------- /Maths/WhileLoopFactorial.js: -------------------------------------------------------------------------------- 1 | /* 2 | author: Theepag, optimised by merelymyself 3 | */ 4 | export const factorialize = (num) => { 5 | // Step 1. Handles cases where num is 0 or 1, by returning 1. 6 | let result = 1 7 | // Step 2. WHILE loop 8 | while (num > 1) { 9 | result *= num // or result = result * num; 10 | num-- // decrement 1 at each iteration 11 | } 12 | // Step 3. Return the factorial 13 | return result 14 | } 15 | -------------------------------------------------------------------------------- /Maths/test/AliquotSum.test.js: -------------------------------------------------------------------------------- 1 | import { aliquotSum } from '../AliquotSum' 2 | 3 | describe('Aliquot Sum of a Number', () => { 4 | it('Aliquot Sum of 6', () => { 5 | expect(aliquotSum(6)).toBe(6) 6 | }) 7 | 8 | it('Aliquot Sum of 1', () => { 9 | expect(aliquotSum(1)).toBe(0) 10 | }) 11 | 12 | it('Aliquot Sum of 28', () => { 13 | expect(aliquotSum(28)).toBe(28) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Maths/test/ArmstrongNumber.test.js: -------------------------------------------------------------------------------- 1 | import { armstrongNumber } from '../ArmstrongNumber' 2 | 3 | describe('ArmstrongNumber', () => { 4 | it('should return true for an armstrong number', () => { 5 | expect(armstrongNumber(371)).toBeTruthy() 6 | }) 7 | 8 | it('should return false for a non-armstrong number', () => { 9 | expect(armstrongNumber(300)).toBeFalsy() 10 | }) 11 | it('should return false for negative values', () => { 12 | expect(armstrongNumber(-2)).toBeFalsy() 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Maths/test/AverageMean.test.js: -------------------------------------------------------------------------------- 1 | import { mean } from '../AverageMean' 2 | 3 | describe('Tests for average mean', () => { 4 | it('should be a function', () => { 5 | expect(typeof mean).toEqual('function') 6 | }) 7 | 8 | it('should throw error for invalid input', () => { 9 | expect(() => mean(123)).toThrow() 10 | }) 11 | 12 | it('should return the mean of an array of numbers', () => { 13 | const meanFunction = mean([1, 2, 4, 5]) 14 | expect(meanFunction).toBe(3) 15 | }) 16 | 17 | it('should return the mean of an array of numbers', () => { 18 | const meanFunction = mean([10, 40, 100, 20]) 19 | expect(meanFunction).toBe(42.5) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /Maths/test/AverageMedian.test.js: -------------------------------------------------------------------------------- 1 | import { averageMedian } from '../AverageMedian' 2 | 3 | test('should return the median of an array of numbers:', () => { 4 | const medianValue = averageMedian([1, 2, 6, 4, 5]) 5 | expect(medianValue).toBe(4) 6 | }) 7 | 8 | test('should return the median of an array of numbers:', () => { 9 | const medianValue = averageMedian([8, 9, 1, 2, 5, 10, 11]) 10 | expect(medianValue).toBe(8) 11 | }) 12 | 13 | test('should return the median of an array of numbers:', () => { 14 | const medianValue = averageMedian([15, 18, 3, 9, 13, 5]) 15 | expect(medianValue).toBe(11) 16 | }) 17 | 18 | test('should return the median of an array of numbers:', () => { 19 | const medianValue = averageMedian([1, 2, 3, 4, 6, 8]) 20 | expect(medianValue).toBe(3.5) 21 | }) 22 | -------------------------------------------------------------------------------- /Maths/test/BInaryConvert.test.js: -------------------------------------------------------------------------------- 1 | import { BinaryConvert } from '../BinaryConvert' 2 | 3 | describe('BinaryConvert', () => { 4 | it('should return the correct value', () => { 5 | expect(BinaryConvert(4)).toBe(100) 6 | }) 7 | it('should return the correct value', () => { 8 | expect(BinaryConvert(12)).toBe(1100) 9 | }) 10 | it('should return the correct value of the sum from two number', () => { 11 | expect(BinaryConvert(12 + 2)).toBe(1110) 12 | }) 13 | it('should return the correct value of the subtract from two number', () => { 14 | expect(BinaryConvert(245 - 56)).toBe(10111101) 15 | }) 16 | it('should return the correct value', () => { 17 | expect(BinaryConvert(254)).toBe(11111110) 18 | }) 19 | it('should return the correct value', () => { 20 | expect(BinaryConvert(63483)).toBe(1111011111111011) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /Maths/test/BinaryExponentiationIterative.test.js: -------------------------------------------------------------------------------- 1 | import { exponent } from '../BinaryExponentiationIterative' 2 | 3 | describe('exponent', () => { 4 | it('should return 1 when power is 0', () => { 5 | expect(exponent(5, 0)).toBe(1) 6 | }) 7 | 8 | it('should return 0 when base is 0', () => { 9 | expect(exponent(0, 7)).toBe(0) 10 | }) 11 | 12 | it('should return the value of a base raised to a power', () => { 13 | expect(exponent(3, 5)).toBe(243) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Maths/test/BinaryExponentiationRecursive.test.js: -------------------------------------------------------------------------------- 1 | import { binaryExponentiation } from '../BinaryExponentiationRecursive' 2 | 3 | describe('BinaryExponentiationRecursive', () => { 4 | it('should calculate 2 to the power of 10 correctly', () => { 5 | expect(binaryExponentiation(2, 10)).toBe(1024) 6 | }) 7 | 8 | it('should calculate 3 to the power of 9 correctly', () => { 9 | expect(binaryExponentiation(3, 9)).toBe(19683) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/CheckKishnamurthyNumber.test.js: -------------------------------------------------------------------------------- 1 | import { CheckKishnamurthyNumber } from '../CheckKishnamurthyNumber' 2 | 3 | describe('CheckKishnamurthyNumber', () => { 4 | it.each([1, 2, 145, 40585])('returns true for %i', (num) => { 5 | expect(CheckKishnamurthyNumber(num)).toBe(true) 6 | }) 7 | 8 | it.each([0, 3, 4, 5, 100, 146, 1019823, -1])( 9 | 'returns false for %i', 10 | (num) => { 11 | expect(CheckKishnamurthyNumber(num)).toBe(false) 12 | } 13 | ) 14 | 15 | it('should throw when input is not a number', () => { 16 | expect(() => CheckKishnamurthyNumber('2')).toThrowError() 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Maths/test/CircularArc.test.js: -------------------------------------------------------------------------------- 1 | import { circularArcLength, circularArcArea } from '../CircularArc' 2 | 3 | describe('circularArcLength', () => { 4 | it('with natural number', () => { 5 | const arcLengthOfOneThirty = circularArcLength(1, 30) 6 | const arcLengthOfThreeSixty = circularArcLength(3, 60) 7 | expect(arcLengthOfOneThirty).toBe(0.5235987755982988) 8 | expect(arcLengthOfThreeSixty).toBe(3.141592653589793) 9 | }) 10 | }) 11 | 12 | describe('circularArcArea', () => { 13 | it('with natural number', () => { 14 | const arcAreaOfOneThirty = circularArcArea(1, 30) 15 | const arcAreaOfThreeSixty = circularArcArea(3, 60) 16 | expect(arcAreaOfOneThirty).toBe(0.2617993877991494) 17 | expect(arcAreaOfThreeSixty).toBe(4.71238898038469) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Maths/test/CollatzSequence.test.js: -------------------------------------------------------------------------------- 1 | import { collatz } from '../CollatzSequence' 2 | 3 | describe('The Collatz Sequence', () => { 4 | it('Should be 1', () => { 5 | expect(collatz(1)).toStrictEqual({ result: 1, steps: [] }) 6 | expect(collatz(5)).toStrictEqual({ result: 1, steps: [16, 8, 4, 2, 1] }) 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /Maths/test/DegreeToRadian.test.js: -------------------------------------------------------------------------------- 1 | import { degreeToRadian } from '../DegreeToRadian' 2 | 3 | test('should convert degree to radian:', () => { 4 | const radianEqual = degreeToRadian(0) 5 | expect(radianEqual).toBe(0) 6 | }) 7 | 8 | test('should convert degree to radian:', () => { 9 | const radianEqual = degreeToRadian(45) 10 | expect(radianEqual).toBe(Math.PI / 4) 11 | }) 12 | 13 | test('should convert degree to radian:', () => { 14 | const radianEqual = degreeToRadian(90) 15 | expect(radianEqual).toBe(Math.PI / 2) 16 | }) 17 | 18 | test('should convert degree to radian:', () => { 19 | const radianEqual = degreeToRadian(180) 20 | expect(radianEqual).toBe(Math.PI) 21 | }) 22 | -------------------------------------------------------------------------------- /Maths/test/EulersTotient.test.js: -------------------------------------------------------------------------------- 1 | import { EulersTotient } from '../EulersTotient' 2 | 3 | describe('EulersTotient', () => { 4 | it('should return 6 as 1, 2, 4, 5, 7, and 8 are coprime to 9', () => { 5 | expect(EulersTotient(9)).toBe(6) 6 | }) 7 | 8 | it('should return 4 as 1, 3, 7, and 9 are coprime to 10', () => { 9 | expect(EulersTotient(10)).toBe(4) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/EulersTotientFunction.test.js: -------------------------------------------------------------------------------- 1 | import { eulersTotientFunction } from '../EulersTotientFunction' 2 | 3 | describe('eulersTotientFunction', () => { 4 | it('is a function', () => { 5 | expect(typeof eulersTotientFunction).toEqual('function') 6 | }) 7 | it('should return the phi of a given number', () => { 8 | const phiOfNumber = eulersTotientFunction(10) 9 | expect(phiOfNumber).toBe(4) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/ExponentialFunction.test.js: -------------------------------------------------------------------------------- 1 | import { exponentialFunction } from '../ExponentialFunction' 2 | 3 | describe('Tests for exponential function', () => { 4 | it('should be a function', () => { 5 | expect(typeof exponentialFunction).toEqual('function') 6 | }) 7 | 8 | it('should throw error for invalid input', () => { 9 | expect(() => exponentialFunction(2, -34)).toThrow() 10 | }) 11 | 12 | it('should return the exponential function of power of 5 and order of 21', () => { 13 | const ex = exponentialFunction(5, 20) 14 | expect(ex).toBe(148.4131078683383) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Maths/test/Factorial.test.js: -------------------------------------------------------------------------------- 1 | import { calcFactorial } from '../Factorial' 2 | 3 | describe('calcFactorial', () => { 4 | it('should return a statement for value "0"', () => { 5 | expect(calcFactorial(0)).toBe(1) 6 | }) 7 | 8 | it('should throw error for "null" and "undefined"', () => { 9 | expect(() => { 10 | calcFactorial(null) 11 | }).toThrow(Error) 12 | expect(() => { 13 | calcFactorial(undefined) 14 | }).toThrow(Error) 15 | }) 16 | 17 | it('should throw error for negative numbers', () => { 18 | expect(() => { 19 | calcFactorial(-1) 20 | }).toThrow(Error) 21 | }) 22 | 23 | it('should return the factorial of a positive number', () => { 24 | const positiveFactorial = calcFactorial(3) 25 | expect(positiveFactorial).toBe(6) 26 | }) 27 | }) 28 | -------------------------------------------------------------------------------- /Maths/test/Factors.test.js: -------------------------------------------------------------------------------- 1 | import { factorsOfANumber } from '../Factors' 2 | 3 | describe('Factors', () => { 4 | factorsOfANumber(50).forEach((num) => { 5 | it(`${num} is a factor of 50`, () => { 6 | const isFactor = 50 % num === 0 7 | expect(isFactor).toBeTruthy() 8 | }) 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /Maths/test/FareyApproximation.test.js: -------------------------------------------------------------------------------- 1 | import { fareyApproximation } from '../FareyApproximation' 2 | 3 | describe('fareyApproximation', () => { 4 | it('Return Farey Approximation of 0.7538385', () => { 5 | const approx = fareyApproximation(0.7538385) 6 | expect(approx).toStrictEqual({ numerator: 52, denominator: 69 }) 7 | }) 8 | 9 | it('Return Farey Approximation of 0.23584936', () => { 10 | const approx = fareyApproximation(0.23584936) 11 | expect(approx).toStrictEqual({ numerator: 196, denominator: 831 }) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /Maths/test/FermatPrimalityTest.test.js: -------------------------------------------------------------------------------- 1 | import { fermatPrimeCheck, modularExponentiation } from '../FermatPrimalityTest' 2 | 3 | describe('modularExponentiation', () => { 4 | it('should give the correct output for all exponentiations', () => { 5 | expect(modularExponentiation(38, 220, 221)).toBe(1) 6 | expect(modularExponentiation(24, 220, 221)).toBe(81) 7 | }) 8 | }) 9 | 10 | describe('fermatPrimeCheck', () => { 11 | it('should give the correct output for prime and composite numbers', () => { 12 | expect(fermatPrimeCheck(2, 35)).toBe(true) 13 | expect(fermatPrimeCheck(10, 30)).toBe(false) 14 | expect(fermatPrimeCheck(94286167)).toBe(true) 15 | expect(fermatPrimeCheck(83165867)).toBe(true) 16 | expect(fermatPrimeCheck(13268774)).toBe(false) 17 | expect(fermatPrimeCheck(13233852)).toBe(false) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Maths/test/FindHcf.test.js: -------------------------------------------------------------------------------- 1 | import { findHCF } from '../FindHcf' 2 | 3 | describe('findHCF', () => { 4 | it('should throw a statement for values less than 1', () => { 5 | expect(findHCF(0, 0)).toBe('Please enter values greater than zero.') 6 | }) 7 | 8 | it('should throw a statement for one value less than 1', () => { 9 | expect(findHCF(0, 1)).toBe('Please enter values greater than zero.') 10 | expect(findHCF(1, 0)).toBe('Please enter values greater than zero.') 11 | }) 12 | 13 | it('should return an error for values non-integer values', () => { 14 | expect(findHCF(2.24, 4.35)).toBe('Please enter whole numbers.') 15 | }) 16 | 17 | it('should return the HCF of two given integers', () => { 18 | expect(findHCF(27, 36)).toBe(9) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /Maths/test/FindMin.test.js: -------------------------------------------------------------------------------- 1 | import { findMin } from '../FindMin' 2 | 3 | describe('FindMin', () => { 4 | test('Should return the minimum number in the array', () => { 5 | const min = findMin(2, 5, 1, 12, 43, 1, 9) 6 | expect(min).toBe(1) 7 | }) 8 | 9 | test('Should return the minimum number in the array', () => { 10 | const min = findMin(21, 513, 6) 11 | expect(min).toBe(6) 12 | }) 13 | 14 | test('Should throw error', () => { 15 | const min = () => findMin() 16 | expect(min).toThrow('Array is empty') 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Maths/test/GetEuclidGCD.test.js: -------------------------------------------------------------------------------- 1 | import { GetEuclidGCD, GetEuclidGCDRecursive } from '../GetEuclidGCD' 2 | 3 | describe.each([GetEuclidGCD, GetEuclidGCDRecursive])('%o', (gcdFunction) => { 4 | it.each([ 5 | [5, 20, 5], 6 | [109, 902, 1], 7 | [290, 780, 10], 8 | [104, 156, 52], 9 | [0, 100, 100], 10 | [-5, 50, 5], 11 | [0, 0, 0], 12 | [1, 1234567, 1] 13 | ])('returns correct result for %i and %j', (inputA, inputB, expected) => { 14 | expect(gcdFunction(inputA, inputB)).toBe(expected) 15 | expect(gcdFunction(inputB, inputA)).toBe(expected) 16 | }) 17 | 18 | it('should throw when any of the inputs is not a number', () => { 19 | expect(() => gcdFunction('1', 2)).toThrowError() 20 | expect(() => gcdFunction(1, '2')).toThrowError() 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /Maths/test/GridGet.test.js: -------------------------------------------------------------------------------- 1 | import { gridGetX, gridGetY } from '../GridGet' 2 | 3 | describe('GridGet', () => { 4 | it('should have a value of x for the 27th element if the square array has 400 elements', () => { 5 | expect(gridGetX(Math.sqrt(400), 27)).toEqual(8) 6 | }) 7 | it('should have a value of x for the 11th element if the square array has 7 columns and 3 rows', () => { 8 | expect(gridGetX(7, 11)).toEqual(5) 9 | }) 10 | it('should have a value of y for the 27th element if the square array has 400 elements', () => { 11 | expect(gridGetY(Math.sqrt(400), 27)).toEqual(2) 12 | }) 13 | it('should have a value of y for the 11th element if the square array has 7 columns and 3 rows ', () => { 14 | expect(gridGetX(7, 11)).toEqual(5) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Maths/test/HexagonalNumber.test.js: -------------------------------------------------------------------------------- 1 | import { hexagonalNumber } from '../HexagonalNumber' 2 | 3 | const expectedValuesArray = [ 4 | 1, 6, 15, 28, 45, 66, 91, 120, 153, 190, 231, 276, 325, 378, 435, 496, 561, 5 | 630, 703, 780, 861, 946 6 | ] 7 | 8 | describe('Testing hexagonalNumber', () => { 9 | for (let i = 1; i <= 22; i++) { 10 | it( 11 | 'Testing for number = ' + i + ', should return ' + expectedValuesArray[i], 12 | () => { 13 | expect(hexagonalNumber(i)).toBe(expectedValuesArray[i - 1]) 14 | } 15 | ) 16 | } 17 | 18 | it('should throw error when supplied negative numbers', () => { 19 | expect(() => { 20 | hexagonalNumber(-1) 21 | }).toThrow(Error) 22 | }) 23 | 24 | it('should throw error when supplied zero', () => { 25 | expect(() => { 26 | hexagonalNumber(0) 27 | }).toThrow(Error) 28 | }) 29 | }) 30 | -------------------------------------------------------------------------------- /Maths/test/IsEven.test.js: -------------------------------------------------------------------------------- 1 | import { isEven, isEvenBitwise } from '../IsEven' 2 | 3 | describe('Testing isEven function', () => { 4 | it('should return if the number is even or not', () => { 5 | const isEvenNumber = isEven(4) 6 | expect(isEvenNumber).toBe(true) 7 | }) 8 | 9 | it('should return if the number is even or not', () => { 10 | const isEvenNumber = isEven(7) 11 | expect(isEvenNumber).toBe(false) 12 | }) 13 | }) 14 | 15 | describe('Testing isEvenBitwise function', () => { 16 | it('should return if the number is even or not', () => { 17 | const isEvenNumber = isEvenBitwise(6) 18 | expect(isEvenNumber).toBe(true) 19 | }) 20 | 21 | it('should return if the number is even or not', () => { 22 | const isEvenNumber = isEvenBitwise(3) 23 | expect(isEvenNumber).toBe(false) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /Maths/test/IsOdd.test.js: -------------------------------------------------------------------------------- 1 | import { isOdd, isOddBitwise } from '../IsOdd' 2 | 3 | describe('Testing the isOdd function', () => { 4 | it('should return true, if the number is odd', () => { 5 | const isOddNumber = isOdd(4) 6 | expect(isOddNumber).toBe(false) 7 | }) 8 | 9 | it('should return true, if the number is odd', () => { 10 | const isOddNumber = isOdd(7) 11 | expect(isOddNumber).toBe(true) 12 | }) 13 | }) 14 | 15 | describe('Testing the isOddBitwise function', () => { 16 | it('should return true, if the number is odd', () => { 17 | const isOddNumber = isOddBitwise(6) 18 | expect(isOddNumber).toBe(false) 19 | }) 20 | 21 | it('should return true, if the number is odd', () => { 22 | const isOddNumber = isOddBitwise(3) 23 | expect(isOddNumber).toBe(true) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /Maths/test/IsPronic.test.js: -------------------------------------------------------------------------------- 1 | import { isPronic } from '../IsPronic' 2 | 3 | const pronicNumbers = [ 4 | 0, 2, 6, 12, 20, 30, 42, 56, 72, 90, 110, 132, 156, 182, 210, 240, 272, 306, 5 | 342, 380, 420, 462, 506, 552, 600, 650, 702, 756, 812, 870, 930, 992, 1056, 6 | 1122, 1190, 1260, 1332, 1406, 1482, 1560, 1640, 1722, 1806, 1892, 1980, 2070, 7 | 2162, 2256, 2352, 2450, 2550 8 | ] 9 | 10 | describe('Testing isPronic function', () => { 11 | for (let i = 0; i <= 2500; i++) { 12 | it('should return true', () => { 13 | const isPronicNumber = isPronic(i) 14 | expect(isPronicNumber).toBe(pronicNumbers.includes(i)) 15 | }) 16 | } 17 | }) 18 | -------------------------------------------------------------------------------- /Maths/test/JugglerSequence.test.js: -------------------------------------------------------------------------------- 1 | import { jugglerSequence } from '../JugglerSequence' 2 | 3 | describe('Testing jugglerSequence function', () => { 4 | it('should return [3, 5, 11, 36, 6, 2, 1 ] if the number is 3', () => { 5 | expect(jugglerSequence(3)).toEqual( 6 | expect.arrayContaining([3, 5, 11, 36, 6, 2, 1]) 7 | ) 8 | }) 9 | 10 | it('should return [9, 27, 140, 11, 36, 6, 2, 1] if the number is 9', () => { 11 | expect(jugglerSequence(9)).toEqual( 12 | expect.arrayContaining([9, 27, 140, 11, 36, 6, 2, 1]) 13 | ) 14 | }) 15 | 16 | it('should return [15, 58, 7, 18, 4, 2, 1] if the number is 15', () => { 17 | expect(jugglerSequence(15)).toEqual( 18 | expect.arrayContaining([15, 58, 7, 18, 4, 2, 1]) 19 | ) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /Maths/test/LeapYear.test.js: -------------------------------------------------------------------------------- 1 | import { isLeapYear } from '../LeapYear' 2 | 3 | describe('Leap Year', () => { 4 | it('Should return true on the year 2000', () => { 5 | expect(isLeapYear(2000)).toBe(true) 6 | }) 7 | it('Should return false on the year 2001', () => { 8 | expect(isLeapYear(2001)).toBe(false) 9 | }) 10 | it('Should return false on the year 2002', () => { 11 | expect(isLeapYear(2002)).toBe(false) 12 | }) 13 | it('Should return false on the year 2003', () => { 14 | expect(isLeapYear(2003)).toBe(false) 15 | }) 16 | it('Should return false on the year 2004', () => { 17 | expect(isLeapYear(2004)).toBe(true) 18 | }) 19 | it('Should return false on the year 1900', () => { 20 | expect(isLeapYear(1900)).toBe(false) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /Maths/test/LinearSieve.test.js: -------------------------------------------------------------------------------- 1 | import { LinearSieve } from '../LinearSieve' 2 | import { PrimeCheck } from '../PrimeCheck' 3 | 4 | describe('LinearSieve', () => { 5 | it('should return primes below 100', () => { 6 | expect(LinearSieve(100)).toEqual([ 7 | 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 8 | 71, 73, 79, 83, 89, 97 9 | ]) 10 | }) 11 | 12 | it('should return primes only', () => { 13 | const n = 100000 14 | const primes = LinearSieve(n) 15 | for (const p of primes) { 16 | expect(PrimeCheck(p)).toBeTruthy() 17 | } 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Maths/test/LucasSeries.test.js: -------------------------------------------------------------------------------- 1 | import { lucas } from '../LucasSeries' 2 | 3 | describe('Nth Lucas Number', () => { 4 | it('should return the 20th Lucas Number', () => { 5 | expect(lucas(20)).toBe(15127) 6 | }) 7 | 8 | it('should return the 20th Lucas Number', () => { 9 | expect(lucas(0)).toBe(2) 10 | }) 11 | 12 | it('should return the 20th Lucas Number', () => { 13 | expect(lucas(100)).toBe(792070839848372100000) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Maths/test/Mandelbrot.manual-test.js: -------------------------------------------------------------------------------- 1 | import { getRGBData } from '../Mandelbrot' 2 | 3 | // plot the results if the script is executed in a browser with a window-object 4 | if (typeof window !== 'undefined') { 5 | const rgbData = getRGBData() 6 | const width = rgbData.length 7 | const height = rgbData[0].length 8 | const canvas = document.createElement('canvas') 9 | canvas.width = width 10 | canvas.height = height 11 | const ctx = canvas.getContext('2d') 12 | for (let x = 0; x < width; x++) { 13 | for (let y = 0; y < height; y++) { 14 | const rgb = rgbData[x][y] 15 | ctx.fillStyle = 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')' 16 | ctx.fillRect(x, y, 1, 1) 17 | } 18 | } 19 | document.body.append(canvas) 20 | } 21 | -------------------------------------------------------------------------------- /Maths/test/MeanAbsoluteDeviation.test.js: -------------------------------------------------------------------------------- 1 | import { meanAbsoluteDeviation } from '../MeanAbsoluteDeviation.js' 2 | 3 | describe('tests for mean absolute deviation', () => { 4 | it('should be a function', () => { 5 | expect(typeof meanAbsoluteDeviation).toEqual('function') 6 | }) 7 | 8 | it('should throw an invalid input error', () => { 9 | expect(() => meanAbsoluteDeviation('fgh')).toThrow() 10 | }) 11 | 12 | it('should return the mean absolute deviation of an array of numbers', () => { 13 | const meanAbDev = meanAbsoluteDeviation([2, 34, 5, 0, -2]) 14 | expect(meanAbDev).toBe(10.479999999999999) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Maths/test/MeanSquareError.test.js: -------------------------------------------------------------------------------- 1 | import { meanSquaredError } from '../MeanSquareError' 2 | 3 | describe('meanSquareError', () => { 4 | it('should throw an error on non-array arguments', () => { 5 | expect(() => meanSquaredError(1, 4)).toThrow('Argument must be an Array') 6 | }) 7 | 8 | it('should throw an error on non equal length ', () => { 9 | const firstArr = [1, 2, 3, 4, 5] 10 | const secondArr = [1, 2, 3] 11 | expect(() => meanSquaredError(firstArr, secondArr)).toThrow( 12 | 'The two lists must be of equal length' 13 | ) 14 | }) 15 | 16 | it('should return the mean square error of two equal length arrays', () => { 17 | const firstArr = [1, 2, 3, 4, 5] 18 | const secondArr = [1, 3, 5, 6, 7] 19 | expect(meanSquaredError(firstArr, secondArr)).toBe(2.6) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /Maths/test/ModularBinaryExponentiationRecursive.test.js: -------------------------------------------------------------------------------- 1 | import { modularBinaryExponentiation } from '../ModularBinaryExponentiationRecursive' 2 | 3 | describe('modularBinaryExponentiation', () => { 4 | it('should return the binary exponentiation', () => { 5 | expect(modularBinaryExponentiation(2, 10, 17)).toBe(4) 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /Maths/test/NumberOfDigits.test.js: -------------------------------------------------------------------------------- 1 | import { numberOfDigit, numberOfDigitsUsingLog } from '../NumberOfDigits' 2 | 3 | describe('NumberOfDigits', () => { 4 | it('should return the correct number of digits for an integer', () => { 5 | expect(numberOfDigit(1234000)).toBe(7) 6 | }) 7 | 8 | it('should return the correct number of digits for a negative number', () => { 9 | expect(numberOfDigit(-2346243)).toBe(7) 10 | }) 11 | 12 | it.each([ 13 | [0, 1], 14 | [123423232, 9], 15 | [-123423232, 9], 16 | [9999, 4] 17 | ])( 18 | 'should return the correct number of digits in an integer', 19 | (value, expected) => { 20 | expect(numberOfDigitsUsingLog(value)).toBe(expected) 21 | } 22 | ) 23 | }) 24 | -------------------------------------------------------------------------------- /Maths/test/PascalTriangle.test.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'vitest' 2 | import { generate } from '../PascalTriangle' 3 | 4 | describe('Pascals Triangle', () => { 5 | it.each([ 6 | [0, []], 7 | [1, [[1]]], 8 | [2, [[1], [1, 1]]], 9 | [3, [[1], [1, 1], [1, 2, 1]]], 10 | [4, [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]]], 11 | [5, [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]], [1, 4, 6, 4, 1]] 12 | ])('check with %j', (input, expected) => { 13 | const pascalsTriangle = generate(input) 14 | expect(pascalsTriangle.length).toEqual(input) 15 | pascalsTriangle.forEach((arr, index) => { 16 | expect(arr.length).toEqual(index + 1) 17 | }) 18 | expect(pascalsTriangle).toEqual(expect.arrayContaining(expected)) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /Maths/test/PerfectCube.test.js: -------------------------------------------------------------------------------- 1 | import { perfectCube } from '../PerfectCube' 2 | 3 | describe('PerfectCube', () => { 4 | it('should return true for a perfect cube', () => { 5 | expect(perfectCube(125)).toBeTruthy() 6 | expect(perfectCube(-125)).toBeTruthy() 7 | }) 8 | it('should return false for a non perfect cube', () => { 9 | expect(perfectCube(100)).toBeFalsy() 10 | expect(perfectCube(Infinity)).toBeFalsy() 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /Maths/test/PerfectNumber.test.js: -------------------------------------------------------------------------------- 1 | import { perfectNumber } from '../PerfectNumber' 2 | 3 | describe('PerfectNumber', () => { 4 | it('should return true for a perfect cube', () => { 5 | expect(perfectNumber(28)).toBeTruthy() 6 | }) 7 | it('should return false for a non perfect cube', () => { 8 | expect(perfectNumber(10)).toBeFalsy() 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /Maths/test/PerfectSquare.test.js: -------------------------------------------------------------------------------- 1 | import { perfectSquare } from '../PerfectSquare' 2 | 3 | describe('PerfectSquare', () => { 4 | it('should return true for a perfect square', () => { 5 | expect(perfectSquare(16)).toBeTruthy() 6 | }) 7 | it('should return false for a non perfect square', () => { 8 | expect(perfectSquare(10)).toBeFalsy() 9 | expect(perfectSquare(Infinity)).toBeFalsy() 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/PermutationAndCombination.test.js: -------------------------------------------------------------------------------- 1 | import { 2 | factorial, 3 | permutation, 4 | combination 5 | } from '../PermutationAndCombination' 6 | 7 | describe('Factorial', () => { 8 | it('factorial(5)', () => { 9 | expect(factorial(5)).toBe(120) 10 | }) 11 | }) 12 | 13 | describe('Permutation', () => { 14 | it('permutation(5, 2)', () => { 15 | expect(permutation(5, 2)).toBe(20) 16 | }) 17 | }) 18 | 19 | describe('Combination', () => { 20 | it('combination(5, 2)', () => { 21 | expect(combination(5, 2)).toBe(10) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /Maths/test/PiApproximationMonteCarlo.test.js: -------------------------------------------------------------------------------- 1 | import { piEstimation } from '../PiApproximationMonteCarlo' 2 | 3 | describe('PiApproximationMonteCarlo', () => { 4 | it('should be between the range of 2 to 4', () => { 5 | const pi = piEstimation() 6 | const piRange = pi >= 2 && pi <= 4 7 | expect(piRange).toBeTruthy() 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /Maths/test/PowLogarithmic.test.js: -------------------------------------------------------------------------------- 1 | import { powLogarithmic } from '../PowLogarithmic' 2 | 3 | describe('PowLogarithmic', () => { 4 | it('should return 1 for numbers with exponent 0', () => { 5 | expect(powLogarithmic(2, 0)).toBe(1) 6 | }) 7 | 8 | it('should return 0 for numbers with base 0', () => { 9 | expect(powLogarithmic(0, 23)).toBe(0) 10 | }) 11 | 12 | it('should return the base to the exponent power', () => { 13 | expect(powLogarithmic(24, 4)).toBe(331776) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Maths/test/PrimeCheck.test.js: -------------------------------------------------------------------------------- 1 | import { PrimeCheck } from '../PrimeCheck' 2 | 3 | describe('PrimeCheck', () => { 4 | it('should return true for Prime Numbers', () => { 5 | expect(PrimeCheck(1000003)).toBeTruthy() 6 | }) 7 | it('should return false for Non Prime Numbers', () => { 8 | expect(PrimeCheck(1000001)).toBeFalsy() 9 | }) 10 | it('should return false for 1 and 0', () => { 11 | expect(PrimeCheck(1)).toBeFalsy() 12 | expect(PrimeCheck(0)).toBeFalsy() 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Maths/test/PrimeFactors.test.js: -------------------------------------------------------------------------------- 1 | import { PrimeFactors } from '../PrimeFactors' 2 | 3 | describe('EulersTotient', () => { 4 | it('should return the prime factors for 100', () => { 5 | expect(PrimeFactors(100)).toEqual([2, 2, 5, 5]) 6 | }) 7 | 8 | it('should return the prime factors for 2560', () => { 9 | expect(PrimeFactors(2560)).toEqual([2, 2, 2, 2, 2, 2, 2, 2, 2, 5]) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/QuadraticRoots.test.js: -------------------------------------------------------------------------------- 1 | import { quadraticRoots } from '../QuadraticRoots.js' 2 | 3 | describe('quadratic roots', () => { 4 | it('returns an array with two real roots when the discriminant is positive', () => { 5 | expect(quadraticRoots(1, -3, 2)).toEqual([2, 1]) 6 | }) 7 | it('returns an array with one real root when the discriminant is zero', () => { 8 | expect(quadraticRoots(1, -2, 1)).toEqual([1]) 9 | }) 10 | it('returns an empty array indicating no real roots when the discriminant is negative', () => { 11 | expect(quadraticRoots(1, 2, 5)).toEqual([]) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /Maths/test/RadianToDegree.test.js: -------------------------------------------------------------------------------- 1 | import { radianToDegree } from '../RadianToDegree' 2 | 3 | test('should convert radian to degree:', () => { 4 | const degreeEqual = radianToDegree(0) 5 | expect(degreeEqual).toBe(0) 6 | }) 7 | 8 | test('should convert radian to degree:', () => { 9 | const degreeEqual = radianToDegree(Math.PI / 4) 10 | expect(degreeEqual).toBe(45) 11 | }) 12 | 13 | test('should convert radian to degree:', () => { 14 | const degreeEqual = radianToDegree(Math.PI / 2) 15 | expect(degreeEqual).toBe(90) 16 | }) 17 | 18 | test('should convert radian to degree:', () => { 19 | const degreeEqual = radianToDegree(Math.PI) 20 | expect(degreeEqual).toBe(180) 21 | }) 22 | -------------------------------------------------------------------------------- /Maths/test/ReverseNumber.test.js: -------------------------------------------------------------------------------- 1 | import { ReverseNumber } from '../ReverseNumber' 2 | 3 | describe('ReverseNumber', () => { 4 | it.each([ 5 | [0, 0], 6 | [10, 1], 7 | [123, 321], 8 | [100001, 100001] 9 | ])('check with %j', (input, expected) => { 10 | expect(expected).toEqual(ReverseNumber(input)) 11 | }) 12 | 13 | it('should throw when input is not a number', () => { 14 | expect(() => ReverseNumber('100')).toThrowError() 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Maths/test/ReversePolishNotation.test.js: -------------------------------------------------------------------------------- 1 | import { calcRPN } from '../ReversePolishNotation' 2 | 3 | describe('ReversePolishNotation', () => { 4 | it('should evaluate correctly for two values', () => { 5 | expect(calcRPN('2 3 +')).toEqual(5) 6 | }) 7 | it("should evaluate' for multiple values", () => { 8 | expect(calcRPN('2 2 2 * +')).toEqual(6) 9 | expect(calcRPN('6 9 7 + 2 / + 3 *')).toEqual(42) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/Signum.test.js: -------------------------------------------------------------------------------- 1 | import { signum } from '../Signum' 2 | 3 | describe('The sign of a number', () => { 4 | it('Sign of 10', () => { 5 | expect(signum(10)).toBe(1) 6 | }) 7 | 8 | it('Sign of 0', () => { 9 | expect(signum(0)).toBe(0) 10 | }) 11 | 12 | it('Sign of -420', () => { 13 | expect(signum(-420)).toBe(-1) 14 | }) 15 | 16 | it('Sign of NaN', () => { 17 | expect(signum(NaN)).toBe(NaN) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Maths/test/Softmax.test.js: -------------------------------------------------------------------------------- 1 | import { Softmax } from '../Softmax' 2 | 3 | describe('Softmax', () => { 4 | it('should return equal distribution of 1 for equal input values', () => { 5 | expect(Softmax([1, 1])).toEqual([0.5, 0.5]) 6 | expect(Softmax([1, 1, 1, 1])).toEqual([0.25, 0.25, 0.25, 0.25]) 7 | }) 8 | 9 | it('should return values which sum to the value of 1', () => { 10 | expect(Softmax([1, 2, 3, 4]).reduce((a, b) => a + b, 0)).toEqual(1) 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /Maths/test/SquareRootLogarithmic.test.js: -------------------------------------------------------------------------------- 1 | import { squareRootLogarithmic } from '../SquareRootLogarithmic' 2 | 3 | describe('SquareRootLogarithmic', () => { 4 | test('Finding the square root of a positive integer', () => { 5 | expect(squareRootLogarithmic(4)).toEqual(2) 6 | expect(squareRootLogarithmic(16)).toEqual(4) 7 | expect(squareRootLogarithmic(8)).toEqual(2) 8 | }) 9 | test('Throwing an exception', () => { 10 | expect(() => squareRootLogarithmic('not a number')).toThrow() 11 | expect(() => squareRootLogarithmic(true)).toThrow() 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /Maths/test/SumOfDigits.test.js: -------------------------------------------------------------------------------- 1 | import { 2 | sumOfDigitsUsingLoop, 3 | sumOfDigitsUsingRecursion, 4 | sumOfDigitsUsingString 5 | } from '../SumOfDigits' 6 | 7 | test('Testing on sumOfDigitsUsingLoop', () => { 8 | const sum = sumOfDigitsUsingLoop(123) 9 | expect(sum).toBe(6) 10 | }) 11 | 12 | test('Testing on sumOfDigitsUsingRecursion', () => { 13 | const sum = sumOfDigitsUsingRecursion(123) 14 | expect(sum).toBe(6) 15 | }) 16 | 17 | test('Testing on sumOfDigitsUsingString', () => { 18 | const sum = sumOfDigitsUsingString(123) 19 | expect(sum).toBe(6) 20 | }) 21 | -------------------------------------------------------------------------------- /Maths/test/SumOfGeometricProgression.test.js: -------------------------------------------------------------------------------- 1 | import { sumOfGeometricProgression } from '../SumOfGeometricProgression' 2 | 3 | describe('Sum Of Geometric Progression', () => { 4 | it('should return the sum of a finite GP', () => { 5 | expect(sumOfGeometricProgression(100, 1.5, 4)).toBe(812.5) 6 | }) 7 | 8 | it('should return the sum of an infinite GP', () => { 9 | expect(sumOfGeometricProgression(2, 0.5, Infinity)).toBe(4) 10 | }) 11 | 12 | it('should throw when series diverges', () => { 13 | expect(() => sumOfGeometricProgression(1, 1, Infinity)).toThrowError() 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Maths/test/TwoSum.test.js: -------------------------------------------------------------------------------- 1 | import { TwoSum } from '../TwoSum.js' 2 | describe('Two Sum', () => { 3 | const testCasesWithoutSolution = [ 4 | [[8], 8], 5 | [[3, 3, 3, 3], 19] 6 | ] 7 | const testCasesWithSolution = [ 8 | [[2, 7, 11, 15], 9, [0, 1]], 9 | [[15, 2, 11, 7], 13, [1, 2]], 10 | [[2, 7, 11, 15], 17, [0, 3]], 11 | [[7, 15, 11, 2], 18, [0, 2]], 12 | [[2, 7, 11, 15], 26, [2, 3]] 13 | ] 14 | 15 | test.each(testCasesWithoutSolution)( 16 | 'Should return an empty array if there is no solution', 17 | (nums, target) => { 18 | expect(TwoSum(nums, target)).toEqual([]) 19 | } 20 | ) 21 | 22 | test.each(testCasesWithSolution)( 23 | 'Should return the indices of two numbers that add up to the target', 24 | (nums, target, expected) => { 25 | expect(TwoSum(nums, target)).toEqual(expected) 26 | } 27 | ) 28 | }) 29 | -------------------------------------------------------------------------------- /Maths/test/WhileLoopFactorial.test.js: -------------------------------------------------------------------------------- 1 | import { factorialize } from '../WhileLoopFactorial' 2 | 3 | function testFactorial(n, expected) { 4 | test('Testing on ' + n + '!', () => { 5 | expect(factorialize(n)).toBe(expected) 6 | }) 7 | } 8 | 9 | testFactorial(3, 6) 10 | testFactorial(7, 5040) 11 | testFactorial(0, 1) 12 | testFactorial(12, 479001600) 13 | -------------------------------------------------------------------------------- /Maths/test/ZellersCongruenceAlgorithm.test.js: -------------------------------------------------------------------------------- 1 | import { zellersCongruenceAlgorithm } from '../ZellersCongruenceAlgorithm' 2 | 3 | function testZeller(day, month, year, expected) { 4 | test('Testing on ' + day + '/' + month + '/' + year, () => { 5 | expect(zellersCongruenceAlgorithm(day, month, year)).toBe(expected) 6 | }) 7 | } 8 | 9 | test('Testing on this/should/throw', () => { 10 | expect(() => { 11 | zellersCongruenceAlgorithm('this', 'should', 'error') 12 | }).toThrowError(new TypeError('Arguments are not all numbers.')) 13 | }) 14 | testZeller(25, 1, 2013, 'Friday') 15 | testZeller(26, 1, 2013, 'Saturday') 16 | testZeller(16, 4, 2022, 'Saturday') 17 | testZeller(25, 4, 2022, 'Monday') 18 | -------------------------------------------------------------------------------- /Navigation/test/Haversine.test.js: -------------------------------------------------------------------------------- 1 | import { haversineDistance } from '../Haversine' 2 | 3 | describe('Testing the haversine distance calculator', () => { 4 | it('Calculate distance', () => { 5 | const distance = haversineDistance(64.1265, -21.8174, 40.7128, -74.006) 6 | expect(distance).toBe(4208198.758424171) 7 | }) 8 | it('Test validation, expect throw', () => { 9 | expect(() => 10 | haversineDistance(64.1265, -21.8174, 40.7128, '74.0060') 11 | ).toThrow() 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /Project-Euler/Problem002.js: -------------------------------------------------------------------------------- 1 | // https://projecteuler.net/problem=2 2 | const SQ5 = 5 ** 0.5 // Square root of 5 3 | const PHI = (1 + SQ5) / 2 // definition of PHI 4 | 5 | // theoretically it should take O(1) constant amount of time as long 6 | // arithmetic calculations are considered to be in constant amount of time 7 | export const EvenFibonacci = (limit) => { 8 | if (limit < 1) 9 | throw new Error("Fibonacci sequence limit can't be less than 1") 10 | 11 | const highestIndex = Math.floor(Math.log(limit * SQ5) / Math.log(PHI)) 12 | const n = Math.floor(highestIndex / 3) 13 | return Math.floor( 14 | ((PHI ** (3 * n + 3) - 1) / (PHI ** 3 - 1) - 15 | ((1 - PHI) ** (3 * n + 3) - 1) / ((1 - PHI) ** 3 - 1)) / 16 | SQ5 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /Project-Euler/Problem003.js: -------------------------------------------------------------------------------- 1 | // https://projecteuler.net/problem=3 2 | 3 | export const largestPrime = (num = 600851475143) => { 4 | let newnum = num 5 | let largestFact = 0 6 | let counter = 2 7 | while (counter * counter <= newnum) { 8 | if (newnum % counter === 0) { 9 | newnum = newnum / counter 10 | } else { 11 | counter++ 12 | } 13 | } 14 | if (newnum > largestFact) { 15 | largestFact = newnum 16 | } 17 | return largestFact 18 | } 19 | -------------------------------------------------------------------------------- /Project-Euler/Problem005.js: -------------------------------------------------------------------------------- 1 | /* 2 | Smallest multiple 3 | 4 | 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. 5 | What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? 6 | */ 7 | 8 | export const findSmallestMultiple = (maxDivisor) => { 9 | const divisors = Array.from({ length: maxDivisor }, (_, i) => i + 1) 10 | let num = maxDivisor + 1 11 | let result 12 | 13 | while (!result) { 14 | const isDivisibleByAll = divisors.every((divisor) => num % divisor === 0) 15 | if (isDivisibleByAll) result = num 16 | else num++ 17 | } 18 | 19 | return result 20 | } 21 | -------------------------------------------------------------------------------- /Project-Euler/Problem006.js: -------------------------------------------------------------------------------- 1 | // https://projecteuler.net/problem=6 2 | 3 | export const squareDifference = (num = 100) => { 4 | let sumOfSquares = (num * (num + 1) * (2 * num + 1)) / 6 5 | let sums = (num * (num + 1)) / 2 6 | 7 | return sums ** 2 - sumOfSquares // difference of square of the total sum and sum of squares 8 | } 9 | -------------------------------------------------------------------------------- /Project-Euler/Problem007.js: -------------------------------------------------------------------------------- 1 | import { PrimeCheck } from '../Maths/PrimeCheck.js' 2 | 3 | /** 4 | * Find nth Prime Number 5 | * 6 | * P.S.(Project Euler - 007): 7 | * By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. 8 | * What is the 10001st prime number? 9 | * 10 | * @param {Number} n 11 | * @returns {Number} returns the nth prime number 12 | */ 13 | export const nthPrime = (n) => { 14 | if (n < 1) { 15 | throw new Error('Invalid Input') 16 | } 17 | 18 | let count = 0 19 | let candidateValue = 1 20 | while (count < n) { 21 | candidateValue++ 22 | if (PrimeCheck(candidateValue)) { 23 | count++ 24 | } 25 | } 26 | return candidateValue 27 | } 28 | -------------------------------------------------------------------------------- /Project-Euler/Problem008.js: -------------------------------------------------------------------------------- 1 | // Problem: https://projecteuler.net/problem=8 2 | 3 | const largestAdjacentNumber = (grid, consecutive) => { 4 | grid = grid.split('\n').join('') 5 | const splitGrid = grid.split('\n') 6 | let largestProd = 0 7 | 8 | for (const row in splitGrid) { 9 | const currentRow = splitGrid[row].split('').map((x) => Number(x)) 10 | 11 | for (let i = 0; i < currentRow.length - consecutive; i++) { 12 | const combine = currentRow.slice(i, i + consecutive) 13 | 14 | if (!combine.includes(0)) { 15 | const product = combine.reduce(function (a, b) { 16 | return a * b 17 | }) 18 | 19 | if (largestProd < product) largestProd = product 20 | } 21 | } 22 | } 23 | return largestProd 24 | } 25 | 26 | export { largestAdjacentNumber } 27 | -------------------------------------------------------------------------------- /Project-Euler/Problem009.js: -------------------------------------------------------------------------------- 1 | /* 2 | Special Pythagorean triplet 3 | 4 | A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, 5 | 6 | a^2 + b^2 = c^2 7 | For example, 32 + 42 = 9 + 16 = 25 = 52. 8 | 9 | There exists exactly one Pythagorean triplet for which a + b + c = 1000. 10 | Find the product abc. 11 | */ 12 | 13 | const isPythagoreanTriplet = (a, b, c) => 14 | Math.pow(a, 2) + Math.pow(b, 2) === Math.pow(c, 2) 15 | 16 | export const findSpecialPythagoreanTriplet = () => { 17 | for (let a = 0; a < 1000; a++) { 18 | for (let b = a + 1; b < 1000; b++) { 19 | for (let c = b + 1; c < 1000; c++) { 20 | if (isPythagoreanTriplet(a, b, c) && a + b + c === 1000) { 21 | return a * b * c 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Project-Euler/Problem010.js: -------------------------------------------------------------------------------- 1 | // https://projecteuler.net/problem=10 2 | 3 | const isPrime = (number) => { 4 | if (number === 2) return true 5 | if (number % 2 === 0) return false 6 | 7 | for (let j = 3; j * j <= number; j += 2) { 8 | if (number % j === 0) { 9 | return false 10 | } 11 | } 12 | return true 13 | } 14 | 15 | const calculateSumOfPrimeNumbers = (maxNumber) => { 16 | let sum = 0 17 | for (let i = maxNumber - 1; i >= 2; i--) { 18 | if (isPrime(parseInt(i)) === true) { 19 | sum += i 20 | } 21 | } 22 | return sum 23 | } 24 | export { calculateSumOfPrimeNumbers } 25 | -------------------------------------------------------------------------------- /Project-Euler/Problem013.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Work out the first ten digits of the sum of the following one-hundred 50-digit numbers. 3 | */ 4 | 5 | export function largeSum(bignum) { 6 | const nums = [] 7 | for (let i = 0; i < bignum.length; i += 50) { 8 | nums.push(bignum.slice(i, i + 50)) 9 | } 10 | 11 | let pos = nums[0].length 12 | let ret = '' 13 | let num = 0 14 | 15 | while (pos--) { 16 | for (let i = nums.length; i--; ) { 17 | num += +nums[i].charAt(pos) 18 | } 19 | ret = (num % 10) + ret 20 | num = (num / 10) | 0 21 | } 22 | 23 | if (num > 0) { 24 | ret = num + ret 25 | } 26 | return ret.slice(0, 10) 27 | } 28 | -------------------------------------------------------------------------------- /Project-Euler/Problem015.js: -------------------------------------------------------------------------------- 1 | // https://projecteuler.net/problem=15 2 | /* Starting in the top left corner of a 2×2 grid, and only being able to move to 3 | the right and down, there are exactly 6 routes to the bottom right corner. 4 | How many such routes are there through a 20×20 grid? 5 | */ 6 | 7 | // A lattice path is composed of horizontal and vertical lines that pass through lattice points. 8 | 9 | export const latticePath = (gridSize) => { 10 | let paths 11 | for (let i = 1, paths = 1; i <= gridSize; i++) { 12 | paths = (paths * (gridSize + i)) / i 13 | } 14 | // The total number of paths can be found using the binomial coefficient (b+a)/a. 15 | return paths 16 | } 17 | 18 | // > latticePath(20)) 19 | // 137846528820 20 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem001.test.js: -------------------------------------------------------------------------------- 1 | import { multiplesThreeAndFive } from '../Problem001.js' 2 | 3 | describe('Sum of multiples of 3 or 5', () => { 4 | it('should throw error when number is negative number', () => { 5 | expect(() => multiplesThreeAndFive(-24)).toThrowError( 6 | 'No natural numbers exist below 1' 7 | ) 8 | }) 9 | it('should throw error when number is 0', () => { 10 | expect(() => multiplesThreeAndFive(0)).toThrowError( 11 | 'No natural numbers exist below 1' 12 | ) 13 | }) 14 | test('if the number is greater than 0', () => { 15 | expect(multiplesThreeAndFive(10)).toBe(23) 16 | }) 17 | // Project Euler Condition Check 18 | test('if the number is 1000', () => { 19 | expect(multiplesThreeAndFive(1000)).toBe(233168) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem002.test.js: -------------------------------------------------------------------------------- 1 | import { EvenFibonacci } from '../Problem002' 2 | 3 | describe('Even Fibonacci numbers', () => { 4 | it('should throw error when limit is less than 1', () => { 5 | expect(() => EvenFibonacci(-1)).toThrowError( 6 | "Fibonacci sequence limit can't be less than 1" 7 | ) 8 | }) 9 | test('when limit is greater than 0', () => { 10 | expect(EvenFibonacci(40)).toBe(44) 11 | }) 12 | // Project Euler Condition Check 13 | test('when limit is 4 million', () => { 14 | expect(EvenFibonacci(4e6)).toBe(4613732) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem003.test.js: -------------------------------------------------------------------------------- 1 | import { largestPrime } from '../Problem003.js' 2 | 3 | describe('Largest prime factor', () => { 4 | test('if the number is 13195', () => { 5 | expect(largestPrime(13195)).toBe(29) 6 | }) 7 | // Project Euler Condition Check 8 | test('if the number is 600851475143', () => { 9 | // Default value is same as the tested value 10 | expect(largestPrime()).toBe(6857) 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem004.test.js: -------------------------------------------------------------------------------- 1 | import { largestPalindromic } from '../Problem004.js' 2 | 3 | describe('Largest Palindromic Number', () => { 4 | test('if digit is 2', () => { 5 | expect(largestPalindromic(2)).toBe(9009) 6 | }) 7 | // Project Euler Condition Check 8 | test('if digit is 3', () => { 9 | expect(largestPalindromic(3)).toBe(906609) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem005.test.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'vitest' 2 | import { findSmallestMultiple } from '../Problem005.js' 3 | 4 | describe.concurrent('Find smallest multiple', () => { 5 | test.each([ 6 | [10, 2520], 7 | [15, 360360], 8 | [20, 232792560] 9 | ])('max divisor -> %i, smallest multiple -> %i', (a, expected) => { 10 | expect(findSmallestMultiple(a)).toBe(expected) 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem006.test.js: -------------------------------------------------------------------------------- 1 | import { squareDifference } from '../Problem006.js' 2 | 3 | describe('Square Difference', () => { 4 | test('difference between the sum of the squares of the first ten natural numbers and the square of the sum', () => { 5 | expect(squareDifference(10)).toBe(2640) 6 | }) 7 | // Project Euler Condition Check 8 | test('difference between the sum of the squares of the first one hundred natural numbers and the square of the sum', () => { 9 | expect(squareDifference()).toBe(25164150) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem007.test.js: -------------------------------------------------------------------------------- 1 | import { nthPrime } from '../Problem007.js' 2 | 3 | describe('checking nth prime number', () => { 4 | it('should be invalid input if number is negative', () => { 5 | expect(() => nthPrime(-3)).toThrowError('Invalid Input') 6 | }) 7 | it('should be invalid input if number is 0', () => { 8 | expect(() => nthPrime(0)).toThrowError('Invalid Input') 9 | }) 10 | test('if the number is greater than 0', () => { 11 | expect(nthPrime(10)).toBe(29) 12 | }) 13 | // Project Euler Condition Check 14 | test('if the number is 10001', () => { 15 | expect(nthPrime(10001)).toBe(104743) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem009.test.js: -------------------------------------------------------------------------------- 1 | import { findSpecialPythagoreanTriplet } from '../Problem009.js' 2 | 3 | describe('Pythagorean Triplet', () => { 4 | // Project Euler Condition Check 5 | test('the multiplication of the pythagorean triplet where a + b + c = 1000', () => { 6 | expect(findSpecialPythagoreanTriplet()).toBe(31875000) 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem010.test.js: -------------------------------------------------------------------------------- 1 | import { calculateSumOfPrimeNumbers } from '../Problem010' 2 | 3 | describe('checkAnagram', () => { 4 | it('Return the sum of prime numbers up to but less than 14', () => { 5 | const SUT = calculateSumOfPrimeNumbers(14) 6 | expect(SUT).toBe(41) 7 | }) 8 | it('Return the sum of prime numbers up to but less than 10', () => { 9 | const SUT = calculateSumOfPrimeNumbers(10) 10 | expect(SUT).toBe(17) 11 | }) 12 | it('Return the sum of prime numbers up to but less than 100', () => { 13 | const SUT = calculateSumOfPrimeNumbers(100) 14 | expect(SUT).toBe(1060) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem012.test.js: -------------------------------------------------------------------------------- 1 | import { firstTriangularWith500Divisors } from '../Problem012' 2 | 3 | describe('checkFirstTriangularWith500Divisors()', () => { 4 | it('Problem Statement Answer', () => { 5 | const firstTriangular = firstTriangularWith500Divisors() 6 | expect(firstTriangular).toBe(76576500) 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem014.test.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'vitest' 2 | import { findLongestCollatzSequence } from '../Problem014.js' 3 | 4 | describe('Longest Collatz Sequence', () => { 5 | test.each([ 6 | [2, 1], 7 | [13, 9], 8 | [1000000, 837799] 9 | ])( 10 | 'if limit is %i, then the Longest Collatz Sequence will be %i', 11 | (a, expected) => { 12 | expect(findLongestCollatzSequence(a)).toBe(expected) 13 | } 14 | ) 15 | }) 16 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem016.test.js: -------------------------------------------------------------------------------- 1 | import { powerDigitSum } from '../Problem016' 2 | 3 | describe('Check Problem 16 - Power digit sum', () => { 4 | it('Power digit sum of 2^15', () => { 5 | expect(powerDigitSum(2, 15)).toBe(26) 6 | }) 7 | 8 | it('Power digit sum of 2^1000', () => { 9 | expect(powerDigitSum()).toBe(1366) 10 | expect(powerDigitSum(2, 1000)).toBe(1366) 11 | }) 12 | 13 | it('Power digit sum of 3^5000', () => { 14 | expect(powerDigitSum(3, 5000)).toBe(11097) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem017.test.js: -------------------------------------------------------------------------------- 1 | import { countNumberWordLength } from '../Problem017.js' 2 | 3 | describe('Number letter count', () => { 4 | test.each([ 5 | [5, 19], 6 | [100, 864], 7 | [1000, 21124] 8 | ])('Number letter count from 1 to %i', (n, expected) => { 9 | expect(countNumberWordLength(n)).toBe(expected) 10 | }) 11 | 12 | test.each([ 13 | ['test', 'Invalid input, please provide valid number'], 14 | [0, 'Please provide number greater that 1'] 15 | ])('Should throw an error for input %i', (n, expected) => { 16 | expect(() => countNumberWordLength(n)).toThrowError(expected) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem018.test.js: -------------------------------------------------------------------------------- 1 | import { maxPathSum } from '../Problem018' 2 | 3 | const example = ` 4 | 3 5 | 7 4 6 | 2 4 6 7 | 8 5 9 3 8 | ` 9 | 10 | describe('Check Problem 18 - Maximum path sum I', () => { 11 | it('Check example', () => { 12 | expect(maxPathSum(example)).toBe(23) 13 | }) 14 | 15 | it('Check solution', () => { 16 | expect(maxPathSum()).toBe(1074) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem019.test.js: -------------------------------------------------------------------------------- 1 | import { problem19 } from '../Problem019.js' 2 | 3 | describe('checking sundays during the twentieth century', () => { 4 | // Project Euler Challenge Check 5 | test('result should be 171', () => { 6 | expect(problem19()).toBe(171) 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem020.test.js: -------------------------------------------------------------------------------- 1 | import { factorialDigitSum } from '../Problem020' 2 | 3 | describe('Check Problem 20 - Factorial digit sum', () => { 4 | it('Factorial digit sum of 10!', () => { 5 | expect(factorialDigitSum(10)).toBe(27) 6 | }) 7 | 8 | it('Factorial digit sum of 100!', () => { 9 | expect(factorialDigitSum()).toBe(648) 10 | expect(factorialDigitSum(100)).toBe(648) 11 | }) 12 | 13 | it('Factorial digit sum of 1000!', () => { 14 | expect(factorialDigitSum(1000)).toBe(10539) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem021.test.js: -------------------------------------------------------------------------------- 1 | import { problem21 } from '../Problem021.js' 2 | 3 | describe('check sum of amicable numbers under n', () => { 4 | test('should be invalid input if number is negative', () => { 5 | expect(() => problem21(-1)).toThrowError('Invalid Input') 6 | }) 7 | test('should be invalid input if number is 0', () => { 8 | expect(() => problem21(0)).toThrowError('Invalid Input') 9 | }) 10 | // Project Euler Condition Check 11 | test('if the number is greater or equal to 1', () => { 12 | expect(problem21(10000)).toBe(31626) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem028.test.js: -------------------------------------------------------------------------------- 1 | import { problem28 } from '../Problem028.js' 2 | 3 | describe('checking number spiral diagonals', () => { 4 | it('should be invalid input if number is negative', () => { 5 | expect(() => problem28(-3)).toThrowError('Dimension must be positive') 6 | }) 7 | it('should be invalid input if number is not odd', () => { 8 | expect(() => problem28(4)).toThrowError('Dimension must be odd') 9 | }) 10 | test('if the number is equal to 5 result should be 101', () => { 11 | expect(problem28(5)).toBe(101) 12 | }) 13 | // Project Euler Condition Check 14 | test('if the number is equal to 1001 result should be 669171001', () => { 15 | expect(problem28(1001)).toBe(669171001) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem035.test.js: -------------------------------------------------------------------------------- 1 | import { problem35 } from '../Problem035.js' 2 | 3 | describe('checking circular primes', () => { 4 | it('should be invalid input if number is negative', () => { 5 | expect(() => problem35(-3)).toThrowError('Invalid input') 6 | }) 7 | it('should be invalid input if number is 0', () => { 8 | expect(() => problem35(0)).toThrowError('Invalid input') 9 | }) 10 | // Project Euler Condition Check 11 | test('if the number is equal to 100 result should be 13', () => { 12 | expect(problem35(100)).toBe(13) 13 | }) 14 | // Project Euler Challenge Check 15 | test('if the number is equal to one million result should be 55', () => { 16 | expect(problem35(1000000)).toBe(55) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem044.test.js: -------------------------------------------------------------------------------- 1 | import { problem44 } from '../Problem044.js' 2 | 3 | describe('checking nth prime number', () => { 4 | test('should be invalid input if number is negative', () => { 5 | expect(() => problem44(-3)).toThrowError('Invalid Input') 6 | }) 7 | test('should be invalid input if number is 0', () => { 8 | expect(() => problem44(0)).toThrowError('Invalid Input') 9 | }) 10 | // Project Euler Condition Check 11 | test('if the number is greater or equal to 1', () => { 12 | expect(problem44(1)).toBe(5482660) 13 | }) 14 | // Project Euler Second Value for Condition Check 15 | test('if the number is greater or equal to 2167', () => { 16 | expect(problem44(2167)).toBe(8476206790) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Recursive/BinaryEquivalent.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem Statement: Given a positive number `num`, find it's binary equivalent using recursion 3 | * 4 | * What is Binary Equivalent? 5 | * - In binary number system, a number is represented in terms of 0s and 1s, 6 | * for example: 7 | * - Binary Of 2 = 10 8 | * - Binary of 3 = 11 9 | * - Binary of 4 = 100 10 | * 11 | * Reference on how to find Binary Equivalent 12 | * - https://byjus.com/maths/decimal-to-binary/ 13 | * 14 | */ 15 | 16 | export const binaryEquivalent = (num) => { 17 | if (num === 0 || num === 1) { 18 | return String(num) 19 | } 20 | return binaryEquivalent(Math.floor(num / 2)) + String(num % 2) 21 | } 22 | -------------------------------------------------------------------------------- /Recursive/Factorial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function Factorial 3 | * @description function to find factorial using recursion. 4 | * @param {Integer} n - The input integer 5 | * @return {Integer} - Factorial of n. 6 | * @see [Factorial](https://en.wikipedia.org/wiki/Factorial) 7 | * @example 5! = 1*2*3*4*5 = 120 8 | * @example 2! = 1*2 = 2 9 | */ 10 | 11 | const factorial = (n) => { 12 | if (!Number.isInteger(n) || n < 0) { 13 | throw new RangeError('Input should be a non-negative whole number') 14 | } 15 | 16 | if (n === 0) { 17 | return 1 18 | } 19 | 20 | return n * factorial(n - 1) 21 | } 22 | 23 | export { factorial } 24 | -------------------------------------------------------------------------------- /Recursive/FibonacciNumberRecursive.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function Fibonacci 3 | * @description Function to return the N-th Fibonacci number. 4 | * @param {Integer} n - The input integer 5 | * @return {Integer} - Return the N-th Fibonacci number 6 | * @see [Fibonacci](https://en.wikipedia.org/wiki/Fibonacci_number) 7 | */ 8 | 9 | const fibonacci = (n) => { 10 | if (n < 2) { 11 | return n 12 | } 13 | return fibonacci(n - 2) + fibonacci(n - 1) 14 | } 15 | 16 | export { fibonacci } 17 | -------------------------------------------------------------------------------- /Recursive/Palindrome.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function Palindrome 3 | * @description Check whether the given string is Palindrome or not. 4 | * @param {String} str - The input string 5 | * @return {Boolean}. 6 | * @see [Palindrome](https://en.wikipedia.org/wiki/Palindrome) 7 | */ 8 | 9 | const palindrome = (str) => { 10 | if (typeof str !== 'string') { 11 | throw new TypeError('Invalid Input') 12 | } 13 | 14 | if (str.length <= 1) { 15 | return true 16 | } 17 | 18 | if (str[0] !== str[str.length - 1]) { 19 | return false 20 | } else { 21 | return palindrome(str.slice(1, str.length - 1)) 22 | } 23 | } 24 | 25 | export { palindrome } 26 | -------------------------------------------------------------------------------- /Recursive/TowerOfHanoi.js: -------------------------------------------------------------------------------- 1 | // wiki - https://en.wikipedia.org/wiki/Tower_of_Hanoi 2 | // Recursive Javascript function to solve tower of hanoi 3 | 4 | export function TowerOfHanoi(n, from, to, aux, output = []) { 5 | if (n === 1) { 6 | output.push(`Move disk 1 from rod ${from} to rod ${to}`) 7 | return output 8 | } 9 | TowerOfHanoi(n - 1, from, aux, to, output) 10 | output.push(`Move disk ${n} from rod ${from} to rod ${to}`) 11 | TowerOfHanoi(n - 1, aux, to, from, output) 12 | return output 13 | } 14 | 15 | // Driver code (A, C, B are the name of rods) 16 | 17 | // const n = 4 18 | // TowerOfHanoi(n, 'A', 'C', 'B') 19 | -------------------------------------------------------------------------------- /Recursive/test/BinaryEquivalent.test.js: -------------------------------------------------------------------------------- 1 | import { binaryEquivalent } from '../BinaryEquivalent' 2 | 3 | const tests = [ 4 | { 5 | test: 2, 6 | expectedValue: '10' 7 | }, 8 | { 9 | test: 0, 10 | expectedValue: '0' 11 | }, 12 | { 13 | test: 543, 14 | expectedValue: '1000011111' 15 | }, 16 | { 17 | test: 4697621023, 18 | expectedValue: '100011000000000000000001000011111' 19 | } 20 | ] 21 | 22 | describe('Binary Equivalent', () => { 23 | test.each(tests)( 24 | 'of $test should be $expectedValue', 25 | ({ test, expectedValue }) => { 26 | expect(binaryEquivalent(test)).toBe(expectedValue) 27 | } 28 | ) 29 | }) 30 | -------------------------------------------------------------------------------- /Recursive/test/FibonacciNumberRecursive.test.js: -------------------------------------------------------------------------------- 1 | import { fibonacci } from '../FibonacciNumberRecursive' 2 | 3 | describe('FibonacciNumberRecursive', () => { 4 | it('should return 0', () => { 5 | expect(fibonacci(0)).toBe(0) 6 | }) 7 | 8 | it('should return 1', () => { 9 | expect(fibonacci(1)).toBe(1) 10 | }) 11 | 12 | it('should return 5', () => { 13 | expect(fibonacci(5)).toBe(5) 14 | }) 15 | 16 | it('should return 9', () => { 17 | expect(fibonacci(9)).toBe(34) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Recursive/test/Palindrome.test.js: -------------------------------------------------------------------------------- 1 | import { palindrome } from '../Palindrome' 2 | 3 | describe('Palindrome', () => { 4 | it('expects to return true for palindrome string', () => { 5 | const isPalindrome = palindrome('madam') 6 | expect(isPalindrome).toBe(true) 7 | }) 8 | 9 | it('expects to return true for Empty String', () => { 10 | const isPalindrome = palindrome('') 11 | expect(isPalindrome).toBe(true) 12 | }) 13 | 14 | it('expects to return false for non-palindrome string', () => { 15 | const isPalindrome = palindrome('foobar') 16 | expect(isPalindrome).toBe(false) 17 | }) 18 | 19 | it('Throw Error for Invalid Input', () => { 20 | expect(() => palindrome(123)).toThrow('Invalid Input') 21 | expect(() => palindrome(null)).toThrow('Invalid Input') 22 | expect(() => palindrome(undefined)).toThrow('Invalid Input') 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /Recursive/test/PalindromePartitioning.test.js: -------------------------------------------------------------------------------- 1 | import partitionPalindrome from '../PalindromePartitioning' 2 | 3 | describe('Palindrome Partitioning', () => { 4 | it('should return all possible palindrome partitioning of s', () => { 5 | expect(partitionPalindrome('aab')).toEqual([ 6 | ['a', 'a', 'b'], 7 | ['aa', 'b'] 8 | ]) 9 | expect(partitionPalindrome('a')).toEqual([['a']]) 10 | expect(partitionPalindrome('ab')).toEqual([['a', 'b']]) 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /Search/test/ExponentialSearch.test.js: -------------------------------------------------------------------------------- 1 | import { exponentialSearch } from '../ExponentialSearch' 2 | 3 | test('The Exponential Search of the Array [2, 3, 4, 10, 40, 65, 78, 100] is 6 where the value = 78', () => { 4 | const arr = [2, 3, 4, 10, 40, 65, 78, 100] 5 | const value = 78 6 | const result = exponentialSearch(arr, arr.length, value) 7 | expect(result).toEqual(6) 8 | }) 9 | 10 | test('The Exponential Search of the Array [2, 3, 4, 10, 40, 65, 78, 100] is -1 where the value = 178', () => { 11 | const arr = [2, 3, 4, 10, 40, 65, 78, 100] 12 | const value = 178 13 | const result = exponentialSearch(arr, arr.length, value) 14 | expect(result).toEqual(-1) 15 | }) 16 | -------------------------------------------------------------------------------- /Search/test/InterpolationSearch.test.js: -------------------------------------------------------------------------------- 1 | import { interpolationSearch } from '../InterpolationSearch' 2 | 3 | test('interpolationSearch([2, 6, 8, 14, 122, 169], 144) => -1', () => { 4 | const array = [2, 6, 8, 14, 122, 169] 5 | const key = 144 6 | const res = interpolationSearch(array, key) 7 | expect(res).toEqual(-1) 8 | }) 9 | 10 | test('interpolationSearch([2, 6, 8, 14, 122, 169], 122) => 4', () => { 11 | const array = [2, 6, 8, 14, 122, 169] 12 | const key = 122 13 | const res = interpolationSearch(array, key) 14 | expect(res).toEqual(4) 15 | }) 16 | -------------------------------------------------------------------------------- /Search/test/LinearSearch.test.js: -------------------------------------------------------------------------------- 1 | import { Search as linearSearch } from '../LinearSearch' 2 | 3 | const tests = [ 4 | { 5 | test: { 6 | arr: [1, 2, 300, 401, 450, 504, 800, 821, 855, 900, 1002], 7 | target: 900 8 | }, 9 | expectedValue: 9 10 | }, 11 | { 12 | test: { 13 | arr: [1, 104, 110, 4, 44, 55, 56, 78], 14 | target: 104 15 | }, 16 | expectedValue: 1 17 | }, 18 | { 19 | test: { 20 | arr: [-4, 5, 50, 77, 821, 85, 99, 100], 21 | target: 192 22 | }, 23 | expectedValue: -1 24 | } 25 | ] 26 | 27 | describe('Linear Search', () => { 28 | it.each(tests)( 29 | 'linearSearch($test.arr, $test.target) => $expectedValue', 30 | ({ test, expectedValue }) => { 31 | const { arr, target } = test 32 | expect(linearSearch(arr, target)).toBe(expectedValue) 33 | } 34 | ) 35 | }) 36 | -------------------------------------------------------------------------------- /Search/test/SlidingWindow.test.js: -------------------------------------------------------------------------------- 1 | import { slidingWindow } from '../SlidingWindow' 2 | 3 | test('expect to return the largest sum of sequence in the array', () => { 4 | const sum = slidingWindow([1, 2, 5, 2, 8, 1, 5], 2) 5 | expect(sum).toBe(10) 6 | }) 7 | 8 | test('expect to return the largest sum of sequence in the array', () => { 9 | const sum = slidingWindow([5, 2, 6, 9], 3) 10 | expect(sum).toBe(17) 11 | }) 12 | 13 | test('expect to return null when the sequence size is larger then the array length', () => { 14 | const sum = slidingWindow([1, 2, 5, 2, 8, 1, 5], 15) 15 | expect(sum).toBe(null) 16 | }) 17 | -------------------------------------------------------------------------------- /Search/test/jumpSearch.test.js: -------------------------------------------------------------------------------- 1 | import { jumpSearch } from '../JumpSearch' 2 | 3 | test('jumpSearch([0, 0, 4, 7, 10, 23, 34, 40, 55, 68, 77, 90], 77) => 10', () => { 4 | const arr = [0, 0, 4, 7, 10, 23, 34, 40, 55, 68, 77, 90] 5 | const res = jumpSearch(arr, 77) 6 | expect(res).toEqual(10) 7 | }) 8 | 9 | test('jumpSearch([11, 12, 15, 65, 78, 90], 4) => -1', () => { 10 | const arr = [11, 12, 15, 65, 78, 90] 11 | const res = jumpSearch(arr, 4) 12 | expect(res).toEqual(-1) 13 | }) 14 | 15 | test('jumpSearch([11, 12, 15, 65, 78, 90], 11) => 0', () => { 16 | const arr = [11, 12, 15, 65, 78, 90] 17 | const res = jumpSearch(arr, 11) 18 | expect(res).toEqual(0) 19 | }) 20 | -------------------------------------------------------------------------------- /Sorts/FindSecondLargestElement.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Find Second Largest is a real technical interview question. 3 | * Chances are you will be asked to find the second largest value 4 | * inside of an array of numbers. You must also be able to filter 5 | * out duplicate values. It's important to know how to do this with 6 | * clean code that is also easy to explain. 7 | * 8 | * Resources: 9 | * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set 10 | */ 11 | 12 | const secondLargestElement = (array) => { 13 | const largestElement = Math.max(...array) 14 | let element = -Number.MAX_VALUE 15 | 16 | for (let i = 0; i < array.length; i++) { 17 | if (element < array[i] && array[i] !== largestElement) { 18 | element = array[i] 19 | } 20 | } 21 | 22 | return element 23 | } 24 | 25 | export { secondLargestElement } 26 | -------------------------------------------------------------------------------- /Sorts/FisherYatesShuffle.js: -------------------------------------------------------------------------------- 1 | export const shuffle = (array) => { 2 | let maxLength = array.length 3 | let temp 4 | let idx 5 | 6 | // While there remain elements to shuffle... 7 | while (maxLength) { 8 | // Pick a remaining element... 9 | idx = Math.floor(Math.random() * maxLength--) 10 | 11 | // And swap it with the current element 12 | temp = array[maxLength] 13 | array[maxLength] = array[idx] 14 | array[idx] = temp 15 | } 16 | 17 | return array 18 | } 19 | -------------------------------------------------------------------------------- /Sorts/GnomeSort.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Gnome sort is a sort algorithm that moving an element to its proper place is accomplished by a series of swap 3 | * more information: https://en.wikipedia.org/wiki/Gnome_sort 4 | * 5 | */ 6 | export function gnomeSort(items) { 7 | if (items.length <= 1) { 8 | return 9 | } 10 | 11 | let i = 1 12 | 13 | while (i < items.length) { 14 | if (items[i - 1] <= items[i]) { 15 | i++ 16 | } else { 17 | ;[items[i], items[i - 1]] = [items[i - 1], items[i]] 18 | 19 | i = Math.max(1, i - 1) 20 | } 21 | } 22 | return items 23 | } 24 | 25 | // Implementation of gnomeSort 26 | 27 | // const ar = [5, 6, 7, 8, 1, 2, 12, 14] 28 | // gnomeSort(ar) 29 | -------------------------------------------------------------------------------- /Sorts/QuickSort.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function QuickSort 3 | * @description Quick sort is a comparison sorting algorithm that uses a divide and conquer strategy. 4 | * @param {Integer[]} items - Array of integers 5 | * @return {Integer[]} - Sorted array. 6 | * @see [QuickSort](https://en.wikipedia.org/wiki/Quicksort) 7 | */ 8 | function quickSort(items) { 9 | const length = items.length 10 | 11 | if (length <= 1) { 12 | return items 13 | } 14 | const PIVOT = items[0] 15 | const GREATER = [] 16 | const LESSER = [] 17 | 18 | for (let i = 1; i < length; i++) { 19 | if (items[i] > PIVOT) { 20 | GREATER.push(items[i]) 21 | } else { 22 | LESSER.push(items[i]) 23 | } 24 | } 25 | 26 | const sorted = [...quickSort(LESSER), PIVOT, ...quickSort(GREATER)] 27 | return sorted 28 | } 29 | 30 | export { quickSort } 31 | -------------------------------------------------------------------------------- /Sorts/ShellSort.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Shell Sort sorts an array based on insertion sort algorithm 3 | * more information: https://en.wikipedia.org/wiki/Shellsort 4 | * 5 | */ 6 | export function shellSort(items) { 7 | let interval = 1 8 | 9 | while (interval < items.length / 3) { 10 | interval = interval * 3 + 1 11 | } 12 | 13 | while (interval > 0) { 14 | for (let outer = interval; outer < items.length; outer++) { 15 | const value = items[outer] 16 | let inner = outer 17 | 18 | while (inner > interval - 1 && items[inner - interval] >= value) { 19 | items[inner] = items[inner - interval] 20 | inner = inner - interval 21 | } 22 | items[inner] = value 23 | } 24 | interval = (interval - 1) / 3 25 | } 26 | return items 27 | } 28 | -------------------------------------------------------------------------------- /Sorts/StoogeSort.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Stooge Sort sorts an array based on divide and conquer principle 3 | * note the exceptionally bad time complexity 4 | * more information: https://en.wikipedia.org/wiki/Stooge_sort 5 | * 6 | */ 7 | export function stoogeSort(items, leftEnd, rightEnd) { 8 | if (items[rightEnd - 1] < items[leftEnd]) { 9 | const temp = items[leftEnd] 10 | items[leftEnd] = items[rightEnd - 1] 11 | items[rightEnd - 1] = temp 12 | } 13 | const length = rightEnd - leftEnd 14 | if (length > 2) { 15 | const third = Math.floor(length / 3) 16 | stoogeSort(items, leftEnd, rightEnd - third) 17 | stoogeSort(items, leftEnd + third, rightEnd) 18 | stoogeSort(items, leftEnd, rightEnd - third) 19 | } 20 | return items 21 | } 22 | -------------------------------------------------------------------------------- /Sorts/test/BeadSort.test.js: -------------------------------------------------------------------------------- 1 | import { beadSort } from '../BeadSort' 2 | 3 | describe('BeadSort', () => { 4 | it('should sort arrays correctly', () => { 5 | expect(beadSort([5, 4, 3, 2, 1])).toEqual([1, 2, 3, 4, 5]) 6 | expect(beadSort([7, 9, 4, 3, 5])).toEqual([3, 4, 5, 7, 9]) 7 | }) 8 | 9 | it('should throw a RangeError when the array contains negative integers', () => { 10 | expect(() => beadSort([-1, 5, 8, 4, 3, 19])).toThrow(RangeError) 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /Sorts/test/BinaryInsertionSort.test.js: -------------------------------------------------------------------------------- 1 | import { binaryInsertionSort } from '../BinaryInsertionSort' 2 | 3 | describe('BinaryInsertionSort', () => { 4 | it('should sort arrays correctly', () => { 5 | expect(binaryInsertionSort([5, 4, 3, 2, 1])).toEqual([1, 2, 3, 4, 5]) 6 | expect(binaryInsertionSort([7, 9, 4, 3, 5])).toEqual([3, 4, 5, 7, 9]) 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /Sorts/test/BogoSort.test.js: -------------------------------------------------------------------------------- 1 | import { bogoSort, isSorted } from '../BogoSort' 2 | 3 | describe('isSorted', () => { 4 | it('should return true for empty arrays', () => { 5 | expect(isSorted([])).toBe(true) 6 | }) 7 | 8 | it('should return true for single-element arrays', () => { 9 | expect(isSorted([1])).toBe(true) 10 | }) 11 | 12 | it('should return true for arrays that are properly sorted', () => { 13 | expect(isSorted([1, 2, 3])).toBe(true) 14 | }) 15 | 16 | it('should return false for arrays that are not properly sorted', () => { 17 | expect(isSorted([3, 2, 1])).toBe(false) 18 | }) 19 | }) 20 | 21 | describe('bogoSort', () => { 22 | it('should (eventually) sort the array', () => { 23 | expect(bogoSort([5, 6, 7, 8, 1, 2, 12, 14])).toEqual([ 24 | 1, 2, 5, 6, 7, 8, 12, 14 25 | ]) 26 | }) 27 | }) 28 | -------------------------------------------------------------------------------- /Sorts/test/CocktailShakerSort.test.js: -------------------------------------------------------------------------------- 1 | import { cocktailShakerSort } from '../CocktailShakerSort' 2 | 3 | describe('CocktailShakerSort', () => { 4 | it('should sort arrays correctly', () => { 5 | expect(cocktailShakerSort([5, 4, 1, 2, 3])).toEqual([1, 2, 3, 4, 5]) 6 | expect(cocktailShakerSort([1, 2, 3])).toEqual([1, 2, 3]) 7 | expect(cocktailShakerSort([5, 6, 7, 8, 1, 2, 12, 14])).toEqual([ 8 | 1, 2, 5, 6, 7, 8, 12, 14 9 | ]) 10 | }) 11 | 12 | it('should work for empty arrays, too', () => { 13 | expect(cocktailShakerSort([])).toEqual([]) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Sorts/test/DutchNationalFlagSort.test.js: -------------------------------------------------------------------------------- 1 | import { dutchNationalFlagSort } from '../DutchNationalFlagSort' 2 | 3 | describe('DutchNationalFlagSort', () => { 4 | it('should sort arrays correctly', () => { 5 | expect(dutchNationalFlagSort([2, 0, 2, 1, 1, 0])).toEqual([ 6 | 0, 0, 1, 1, 2, 2 7 | ]) 8 | expect(dutchNationalFlagSort([2, 1, 0])).toEqual([0, 1, 2]) 9 | expect(dutchNationalFlagSort([1, 0, 0, 0, 1])).toEqual([0, 0, 0, 1, 1]) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Sorts/test/FindSecondLargestElement.test.js: -------------------------------------------------------------------------------- 1 | import { secondLargestElement } from '../FindSecondLargestElement' 2 | 3 | test('The second largest element of the array [1, 2, 3, 4, 5] is 4', () => { 4 | const array = [1, 2, 3, 4, 5] 5 | const res = secondLargestElement(array) 6 | expect(res).toEqual(4) 7 | }) 8 | 9 | test('The second largest element of the array [-1, -2, -3, -4, -5] is -2', () => { 10 | const array = [-1, -2, -3, -4, -5] 11 | const res = secondLargestElement(array) 12 | expect(res).toEqual(-2) 13 | }) 14 | -------------------------------------------------------------------------------- /Sorts/test/GnomeSort.test.js: -------------------------------------------------------------------------------- 1 | import { gnomeSort } from '../GnomeSort' 2 | 3 | test('The gnomeSort of the array [5, 4, 3, 2, 1] is [1, 2, 3, 4, 5]', () => { 4 | const arr = [5, 4, 3, 2, 1] 5 | const res = gnomeSort(arr) 6 | expect(res).toEqual([1, 2, 3, 4, 5]) 7 | }) 8 | 9 | test('The gnomeSort of the array [-5, 4, -3, 2, -1] is [-5, -3, -1, 2, 4]', () => { 10 | const arr = [-5, 4, -3, 2, -1] 11 | const res = gnomeSort(arr) 12 | expect(res).toEqual([-5, -3, -1, 2, 4]) 13 | }) 14 | 15 | test('The gnomeSort of the array [15, 4, -13, 2, -11] is [-13, -11, 2, 4, 15]', () => { 16 | const arr = [15, 4, -13, 2, -11] 17 | const res = gnomeSort(arr) 18 | expect(res).toEqual([-13, -11, 2, 4, 15]) 19 | }) 20 | -------------------------------------------------------------------------------- /Sorts/test/HeapSort.test.js: -------------------------------------------------------------------------------- 1 | import { heapSort } from '../HeapSort' 2 | 3 | test('The HeapSort of the array [5, 4, 3, 2, 1] is [1, 2, 3, 4, 5]', () => { 4 | const array = [5, 4, 3, 2, 1] 5 | const res = heapSort(array) 6 | expect(res).toEqual([1, 2, 3, 4, 5]) 7 | }) 8 | 9 | test('The HeapSort of the array [-5, -4, -3, -2, -1] is [-5, -4, -3, -2, -1]', () => { 10 | const array = [-5, -4, -3, -2, -1] 11 | const res = heapSort(array) 12 | expect(res).toEqual([-5, -4, -3, -2, -1]) 13 | }) 14 | 15 | test('The HeapSort of the array [50, 43, 31, 52, 91] is [31, 43, 50, 52, 91]', () => { 16 | const array = [50, 43, 31, 52, 91] 17 | const res = heapSort(array) 18 | expect(res).toEqual([31, 43, 50, 52, 91]) 19 | }) 20 | 21 | test('The HeapSort of the array [] is []', () => { 22 | const array = [] 23 | const res = heapSort(array) 24 | expect(res).toEqual([]) 25 | }) 26 | -------------------------------------------------------------------------------- /Sorts/test/HeapSortV2.test.js: -------------------------------------------------------------------------------- 1 | import { heapSort } from '../HeapSortV2' 2 | 3 | test('The heapSort of the array [4, 3, 2, 1] is [1, 2, 3, 4]', () => { 4 | const arr = [4, 3, 2, 1] 5 | const res = heapSort(arr) 6 | expect(res).toEqual([1, 2, 3, 4]) 7 | }) 8 | 9 | test('The heapSort of the array [] is []', () => { 10 | const arr = [] 11 | const res = heapSort(arr) 12 | expect(res).toEqual([]) 13 | }) 14 | 15 | test('The heapSort of the array [41, 31, 32, 31] is [31, 31, 32, 41]', () => { 16 | const arr = [41, 31, 32, 31] 17 | const res = heapSort(arr) 18 | expect(res).toEqual([31, 31, 32, 41]) 19 | }) 20 | -------------------------------------------------------------------------------- /Sorts/test/OddEvenSort.test.js: -------------------------------------------------------------------------------- 1 | import { oddEvenSort } from '../OddEvenSort' 2 | 3 | test('The OddEvenSort of the array [5, 4, 3, 2, 1] is [1, 2, 3, 4, 5]', () => { 4 | const arr = [5, 4, 3, 2, 1] 5 | const res = oddEvenSort(arr) 6 | expect(res).toEqual([1, 2, 3, 4, 5]) 7 | }) 8 | 9 | test('The OddEvenSort of the array [] is []', () => { 10 | const arr = [] 11 | const res = oddEvenSort(arr) 12 | expect(res).toEqual([]) 13 | }) 14 | 15 | test('The OddEvenSort of the array [10, 14, 12, 20] is [10, 12, 14, 20]', () => { 16 | const arr = [10, 14, 12, 20] 17 | const res = oddEvenSort(arr) 18 | expect(res).toEqual([10, 12, 14, 20]) 19 | }) 20 | 21 | test('The OddEvenSort of the array [166, 169, 144] is [144, 166, 169]', () => { 22 | const arr = [166, 169, 144] 23 | const res = oddEvenSort(arr) 24 | expect(res).toEqual([144, 166, 169]) 25 | }) 26 | -------------------------------------------------------------------------------- /Sorts/test/PigeonHoleSort.test.js: -------------------------------------------------------------------------------- 1 | import { pigeonHoleSort } from '../PigeonHoleSort' 2 | 3 | test('The pigeonHoleSort of the array [1, 4, 3, 2] is [1, 2, 3, 4]', () => { 4 | const arr = [1, 4, 3, 2] 5 | const res = pigeonHoleSort(arr) 6 | expect(res).toEqual([1, 2, 3, 4]) 7 | }) 8 | 9 | test('The pigeonHoleSort of the array [5, 4, 1, 2] is [1, 2, 4, 5]', () => { 10 | const arr = [5, 4, 1, 2] 11 | const res = pigeonHoleSort(arr) 12 | expect(res).toEqual([1, 2, 4, 5]) 13 | }) 14 | 15 | test('The pigeonHoleSort of the array [18, 31, 29, 35, 11] is [11, 18, 29, 31, 35]', () => { 16 | const arr = [18, 31, 29, 35, 11] 17 | const res = pigeonHoleSort(arr) 18 | expect(res).toEqual([11, 18, 29, 31, 35]) 19 | }) 20 | -------------------------------------------------------------------------------- /Sorts/test/QuickSort.test.js: -------------------------------------------------------------------------------- 1 | import { quickSort } from '../QuickSort' 2 | 3 | describe('QuickSort', () => { 4 | it('should work for empty arrays', () => { 5 | expect(quickSort([])).toEqual([]) 6 | }) 7 | 8 | it('should sort arrays correctly', () => { 9 | expect(quickSort([5, 4, 3, 10, 2, 1])).toEqual([1, 2, 3, 4, 5, 10]) 10 | expect(quickSort([5, 4])).toEqual([4, 5]) 11 | expect(quickSort([1, 2, 3])).toEqual([1, 2, 3]) 12 | expect(quickSort([0, 5, 3, 2, 2])).toEqual([0, 2, 2, 3, 5]) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Sorts/test/RadixSort.test.js: -------------------------------------------------------------------------------- 1 | import { radixSort } from '../RadixSort' 2 | 3 | test('The RadixSort of the array [4, 3, 2, 1] is [1, 2, 3, 4]', () => { 4 | const arr = [4, 3, 2, 1] 5 | const res = radixSort(arr, 10) 6 | expect(res).toEqual([1, 2, 3, 4]) 7 | }) 8 | 9 | test('The RadixSort of the array [] is []', () => { 10 | const arr = [] 11 | const res = radixSort(arr, 10) 12 | expect(res).toEqual([]) 13 | }) 14 | 15 | test('The RadixSort of the array [14, 16, 10, 12] is [10, 12, 14, 16]', () => { 16 | const arr = [14, 16, 10, 12] 17 | const res = radixSort(arr, 10) 18 | expect(res).toEqual([10, 12, 14, 16]) 19 | }) 20 | -------------------------------------------------------------------------------- /Sorts/test/ShellSort.test.js: -------------------------------------------------------------------------------- 1 | import { shellSort } from '../ShellSort' 2 | 3 | test('The ShellSort of the array [5, 4, 3, 2, 1] is [1, 2, 3, 4, 5]', () => { 4 | const arr = [5, 4, 3, 2, 1] 5 | const res = shellSort(arr) 6 | expect(res).toEqual([1, 2, 3, 4, 5]) 7 | }) 8 | 9 | test('The ShellSort of the array [] is []', () => { 10 | const arr = [] 11 | const res = shellSort(arr) 12 | expect(res).toEqual([]) 13 | }) 14 | 15 | test('The ShellSort of the array [15, 24, 31, 42, 11] is [11, 15, 24, 31, 42]', () => { 16 | const arr = [15, 24, 31, 42, 11] 17 | const res = shellSort(arr) 18 | expect(res).toEqual([11, 15, 24, 31, 42]) 19 | }) 20 | 21 | test('The ShellSort of the array [121, 190, 169] is [121, 169, 190]', () => { 22 | const arr = [121, 190, 169] 23 | const res = shellSort(arr) 24 | expect(res).toEqual([121, 169, 190]) 25 | }) 26 | -------------------------------------------------------------------------------- /Sorts/test/SwapSort.test.js: -------------------------------------------------------------------------------- 1 | import { minSwapsToSort } from '../SwapSort' 2 | 3 | describe('SwapSort', () => { 4 | it('should work for empty arrays', () => { 5 | expect(minSwapsToSort([])).toEqual(0) 6 | }) 7 | 8 | it('should work for sorted arrays', () => { 9 | expect(minSwapsToSort([1, 2, 3, 4, 5, 6])).toEqual(0) 10 | }) 11 | 12 | it('should return correct results', () => { 13 | expect(minSwapsToSort([7, 6, 2, 5, 11, 0])).toEqual(2) 14 | expect(minSwapsToSort([3, 3, 2, 1, 0])).toEqual(2) 15 | expect(minSwapsToSort([3, 0, 2, 1, 9, 8, 7, 6])).toEqual(4) 16 | expect(minSwapsToSort([1, 0, 14, 0, 8, 6, 8])).toEqual(3) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Sorts/test/TimSort.test.js: -------------------------------------------------------------------------------- 1 | import { Timsort } from '../TimSort' 2 | 3 | test('The Timsort of the array [5, 4, 3, 2, 1] is [1, 2, 3, 4, 5]', () => { 4 | const arr = [5, 4, 3, 2, 1] 5 | const res = Timsort(arr) 6 | expect(res).toEqual([1, 2, 3, 4, 5]) 7 | }) 8 | 9 | test('The Timsort of the array [] is []', () => { 10 | const arr = [] 11 | const res = Timsort(arr) 12 | expect(res).toEqual([]) 13 | }) 14 | 15 | test('The Timsort of the array [-5, -4, -3, -2, -1] is [-5, -4, -3, -2, -1]', () => { 16 | const arr = [-5, -4, -3, -2, -1] 17 | const res = Timsort(arr) 18 | expect(res).toEqual([-5, -4, -3, -2, -1]) 19 | }) 20 | 21 | test('The Timsort of the array [9, 0, -5, -11, 3] is [-11, -5, 0, 3, 9]', () => { 22 | const arr = [9, 0, -5, -11, 3] 23 | const res = Timsort(arr) 24 | expect(res).toEqual([-11, -5, 0, 3, 9]) 25 | }) 26 | -------------------------------------------------------------------------------- /String/CheckCamelCase.js: -------------------------------------------------------------------------------- 1 | // CheckCamelCase method checks the given string is in camelCase or not. 2 | 3 | // Problem Source & Explanation: https://en.wikipedia.org/wiki/Camel_case 4 | 5 | /** 6 | * checkCamelCase method returns true if the string in camelCase, else return the false. 7 | * @param {String} varName the name of the variable to check. 8 | * @returns `Boolean` return true if the string is in camelCase, else return false. 9 | */ 10 | const checkCamelCase = (varName) => { 11 | // firstly, check that input is a string or not. 12 | if (typeof varName !== 'string') { 13 | throw new TypeError('Argument is not a string.') 14 | } 15 | 16 | const pat = /^[a-z][A-Za-z]*$/ 17 | return pat.test(varName) 18 | } 19 | 20 | export { checkCamelCase } 21 | -------------------------------------------------------------------------------- /String/CheckKebabCase.js: -------------------------------------------------------------------------------- 1 | // CheckKebabCase method checks the given string is in kebab-case or not. 2 | 3 | // Problem Source & Explanation: https://en.wikipedia.org/wiki/Naming_convention_(programming) 4 | 5 | /** 6 | * CheckKebabCase method returns true if the string in kebab-case, else return the false. 7 | * @param {String} varName the name of the variable to check. 8 | * @returns `Boolean` return true if the string is in kebab-case, else return false. 9 | */ 10 | const CheckKebabCase = (varName) => { 11 | // firstly, check that input is a string or not. 12 | if (typeof varName !== 'string') { 13 | throw new TypeError('Argument is not a string.') 14 | } 15 | 16 | const pat = /(\w+)-(\w)([\w-]*)/ 17 | return pat.test(varName) && !varName.includes('_') 18 | } 19 | 20 | export { CheckKebabCase } 21 | -------------------------------------------------------------------------------- /String/CheckPalindrome.js: -------------------------------------------------------------------------------- 1 | // Palindrome check is case sensitive; i.e. Aba is not a palindrome 2 | // input is a string 3 | const checkPalindrome = (str) => { 4 | // check that input is a string 5 | if (typeof str !== 'string') { 6 | return 'Not a string' 7 | } 8 | if (str.length === 0) { 9 | return 'Empty string' 10 | } 11 | // Reverse only works with array, thus convert the string to array, reverse it and convert back to string 12 | // return as palindrome if the reversed string is equal to the input string 13 | const reversed = [...str].reverse().join('') 14 | return str === reversed ? 'Palindrome' : 'Not a Palindrome' 15 | } 16 | 17 | export { checkPalindrome } 18 | -------------------------------------------------------------------------------- /String/CheckPascalCase.js: -------------------------------------------------------------------------------- 1 | // CheckPascalCase method checks the given string is in PascalCase or not. 2 | 3 | // Problem Source & Explanation: https://www.theserverside.com/definition/Pascal-case 4 | 5 | /** 6 | * CheckPascalCase method returns true if the string in PascalCase, else return the false. 7 | * @param {String} VarName the name of the variable to check. 8 | * @returns `Boolean` return true if the string is in PascalCase, else return false. 9 | */ 10 | const CheckPascalCase = (VarName) => { 11 | // firstly, check that input is a string or not. 12 | if (typeof VarName !== 'string') { 13 | throw new TypeError('Argument is not a string.') 14 | } 15 | 16 | const pat = /^[A-Z][A-Za-z]*$/ 17 | return pat.test(VarName) 18 | } 19 | 20 | export { CheckPascalCase } 21 | -------------------------------------------------------------------------------- /String/CheckSnakeCase.js: -------------------------------------------------------------------------------- 1 | // CheckSnakeCase method checks the given string is in snake_case or not. 2 | 3 | // Problem Source & Explanation: https://en.wikipedia.org/wiki/Naming_convention_(programming) 4 | 5 | /** 6 | * checkSnakeCase method returns true if the string in snake_case, else return the false. 7 | * @param {String} varName the name of the variable to check. 8 | * @returns `Boolean` return true if the string is in snake_case, else return false. 9 | */ 10 | const checkSnakeCase = (varName) => { 11 | // firstly, check that input is a string or not. 12 | if (typeof varName !== 'string') { 13 | throw new TypeError('Argument is not a string.') 14 | } 15 | 16 | const pat = /(.*?)_([a-zA-Z])*/ 17 | return pat.test(varName) 18 | } 19 | 20 | export { checkSnakeCase } 21 | -------------------------------------------------------------------------------- /String/CountVowels.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function countVowels 3 | * @description Given a string of words or phrases, count the number of vowels. 4 | * @param {String} str - The input string 5 | * @return {Number} - The number of vowels 6 | * @example countVowels("ABCDE") => 2 7 | * @example countVowels("Hello") => 2 8 | */ 9 | 10 | const countVowels = (str) => { 11 | if (typeof str !== 'string') { 12 | throw new TypeError('Input should be a string') 13 | } 14 | 15 | const vowelRegex = /[aeiou]/gi 16 | const vowelsArray = str.match(vowelRegex) || [] 17 | 18 | return vowelsArray.length 19 | } 20 | 21 | export { countVowels } 22 | -------------------------------------------------------------------------------- /String/FormatPhoneNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description - function that takes 10 digits and returns a string of the formatted phone number e.g.: 1234567890 -> (123) 456-7890 3 | * @param {string} phoneNumber 4 | * @returns {string} - Format to (XXX) XXX-XXXX pattern 5 | */ 6 | const formatPhoneNumber = (phoneNumber) => { 7 | if (phoneNumber.length !== 10 || isNaN(phoneNumber)) { 8 | // return "Invalid phone number." 9 | throw new TypeError('Invalid phone number!') 10 | } 11 | 12 | let index = 0 13 | return '(XXX) XXX-XXXX'.replace(/X/g, () => phoneNumber[index++]) 14 | } 15 | 16 | export default formatPhoneNumber 17 | -------------------------------------------------------------------------------- /String/GenerateGUID.js: -------------------------------------------------------------------------------- 1 | /* 2 | Generates a UUID/GUID in Node.Js. 3 | The script uses `Math.random` in combination with the timestamp for better randomness. 4 | The function generate an RFC4122 (https://www.ietf.org/rfc/rfc4122.txt) version 4 UUID/GUID 5 | */ 6 | 7 | export const Guid = () => { 8 | const pattern = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' 9 | let currentDateMilliseconds = new Date().getTime() 10 | return pattern.replace(/[xy]/g, (currentChar) => { 11 | const randomChar = (currentDateMilliseconds + Math.random() * 16) % 16 | 0 12 | currentDateMilliseconds = Math.floor(currentDateMilliseconds / 16) 13 | return ( 14 | currentChar === 'x' ? randomChar : (randomChar & 0x7) | 0x8 15 | ).toString(16) 16 | }) 17 | } 18 | 19 | // > Guid() 20 | // 'edc848db-3478-1760-8b55-7986003d895f' 21 | -------------------------------------------------------------------------------- /String/HammingDistance.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Hamming Distance: https://en.wikipedia.org/wiki/Hamming_distance 3 | * 4 | * 5 | * Hamming distance is a metric for comparing two binary data strings. 6 | * 7 | * While comparing two binary strings of equal length, Hamming distance 8 | * is the number of bit positions in which the two bits are different. 9 | * The Hamming distance between two strings, a and b is denoted as d(a,b) 10 | */ 11 | 12 | /** 13 | * @param {string} a 14 | * @param {string} b 15 | * @return {number} 16 | */ 17 | 18 | export const hammingDistance = (a, b) => { 19 | if (a.length !== b.length) { 20 | throw new Error('Strings must be of the same length') 21 | } 22 | 23 | let distance = 0 24 | 25 | for (let i = 0; i < a.length; i += 1) { 26 | if (a[i] !== b[i]) { 27 | distance += 1 28 | } 29 | } 30 | 31 | return distance 32 | } 33 | -------------------------------------------------------------------------------- /String/Lower.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function lower 3 | * @description Will convert the entire string to lowercase letters. 4 | * @param {String} str - The input string 5 | * @returns {String} Lowercase string 6 | * @example lower("HELLO") => hello 7 | * @example lower("He_llo") => he_llo 8 | */ 9 | 10 | const lower = (str) => { 11 | if (typeof str !== 'string') { 12 | throw new TypeError('Invalid Input Type') 13 | } 14 | 15 | return str.replace(/[A-Z]/g, (char) => 16 | String.fromCharCode(char.charCodeAt() + 32) 17 | ) 18 | } 19 | 20 | export default lower 21 | -------------------------------------------------------------------------------- /String/ReverseWords.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function reverseWords 3 | * @param {string} str 4 | * @returns {string} - reverse string 5 | */ 6 | const reverseWords = (str) => { 7 | if (typeof str !== 'string') { 8 | throw new TypeError('The given value is not a string') 9 | } 10 | 11 | return str 12 | .split(/\s+/) // create an array with each word in string 13 | .reduceRight((reverseStr, word) => `${reverseStr} ${word}`, '') // traverse the array from last & create an string 14 | .trim() // remove the first useless space 15 | } 16 | 17 | export default reverseWords 18 | -------------------------------------------------------------------------------- /String/Upper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function upper 3 | * @description Will convert the entire string to uppercase letters. 4 | * @param {String} str - The input string 5 | * @return {String} Uppercase string 6 | * @example upper("hello") => HELLO 7 | * @example upper("He_llo") => HE_LLO 8 | */ 9 | const upper = (str) => { 10 | if (typeof str !== 'string') { 11 | throw new TypeError('Argument should be string') 12 | } 13 | 14 | return str.replace(/[a-z]/g, (char) => 15 | String.fromCharCode(char.charCodeAt() - 32) 16 | ) 17 | } 18 | 19 | export default upper 20 | -------------------------------------------------------------------------------- /String/ValidateEmail.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns whether the given string is a valid email address or not. 3 | */ 4 | const validateEmail = (str) => { 5 | if (str === '' || str === null) { 6 | throw new TypeError('Email Address String Null or Empty.') 7 | } 8 | 9 | return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str) 10 | } 11 | 12 | export { validateEmail } 13 | -------------------------------------------------------------------------------- /String/test/AlternativeStringArrange.test.js: -------------------------------------------------------------------------------- 1 | import { AlternativeStringArrange } from '../AlternativeStringArrange' 2 | 3 | test('AlternativeStringArrange(Agrtm, loih) -> Algorithm', () => { 4 | const str1 = 'Agrtm' 5 | const str2 = 'loih' 6 | const res = AlternativeStringArrange(str1, str2) 7 | expect(res).toEqual('Algorithm') 8 | }) 9 | 10 | test('AlternativeStringArrange(JvSrp, aacit) -> JavaScript', () => { 11 | const str1 = 'JvSrp' 12 | const str2 = 'aacit' 13 | const res = AlternativeStringArrange(str1, str2) 14 | expect(res).toEqual('JavaScript') 15 | }) 16 | 17 | test('AlternativeStringArrange(abc, def) -> adbecf', () => { 18 | const str1 = 'abc' 19 | const str2 = 'def' 20 | const res = AlternativeStringArrange(str1, str2) 21 | expect(res).toEqual('adbecf') 22 | }) 23 | -------------------------------------------------------------------------------- /String/test/BoyerMoore.test.js: -------------------------------------------------------------------------------- 1 | import { boyerMoore } from '../BoyerMoore' 2 | 3 | describe('Testing the boyer moore algorithm', () => { 4 | it('Testing with alphabetical strings', () => { 5 | expect(boyerMoore('THIS IS A TEST TEXT', 'TEST')).toBe(10) 6 | expect(boyerMoore('AAIOOOAADDZXYCAADAABAABA', 'AADA')).toBe(14) 7 | expect(boyerMoore('Hello World! This is a test case.', 'Boyer')).toBe(-1) 8 | }) 9 | 10 | it('Testing with alphabets and symbols', () => { 11 | expect(boyerMoore('AA&&@_OPOODDA##!', '@_')).toBe(4) 12 | expect(boyerMoore('LK_||{{}}[[$($', '||')).toBe(3) 13 | expect(boyerMoore('__||{{__+}}[[$($', '-}}')).toBe(-1) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /String/test/CheckCamelCase.test.js: -------------------------------------------------------------------------------- 1 | import { checkCamelCase } from '../CheckCamelCase' 2 | describe('checkCamelCase', () => { 3 | it('expect to throw an error if input is not a string', () => { 4 | expect(() => checkCamelCase(null)).toThrow() 5 | }) 6 | 7 | it('expects to return true if the input is in camel case format', () => { 8 | const value = 'dockerBuild' 9 | const result = checkCamelCase(value) 10 | expect(result).toBe(true) 11 | }) 12 | 13 | it('expects to return false if the input is not in camel case format', () => { 14 | const value = 'docker_build' 15 | const result = checkCamelCase(value) 16 | expect(result).toBe(false) 17 | }) 18 | 19 | it('should throw when input is not a string', () => { 20 | expect(() => checkCamelCase(100)).toThrowError() 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /String/test/CheckFlatCase.test.js: -------------------------------------------------------------------------------- 1 | import { checkFlatCase } from '../CheckFlatCase' 2 | 3 | describe('checkFlatCase function', () => { 4 | it('should return false when the input string is not in flatcase', () => { 5 | const actual = checkFlatCase('this is not in flatcase') 6 | expect(actual).toBe(false) 7 | }) 8 | 9 | it('should return true when the input string is a single letter character', () => { 10 | const actual = checkFlatCase('a') 11 | expect(actual).toBe(true) 12 | }) 13 | 14 | it('should return true when the input string is a string of lowercase letter characters with no spaces', () => { 15 | const actual = checkFlatCase('abcdefghijklmnopqrstuvwxyz') 16 | expect(actual).toBe(true) 17 | }) 18 | 19 | it('should throw when input is not a string', () => { 20 | expect(() => checkFlatCase(100)).toThrowError() 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /String/test/CheckKebabCase.test.js: -------------------------------------------------------------------------------- 1 | import { CheckKebabCase } from '../CheckKebabCase' 2 | 3 | test('CheckKebabCase(The-Algorithms) -> true', () => { 4 | const word = 'The-Algorithms' 5 | const res = CheckKebabCase(word) 6 | expect(res).toBeTruthy() 7 | }) 8 | 9 | test('CheckKebabCase(The Algorithms) -> false', () => { 10 | const word = 'The Algorithms' 11 | const res = CheckKebabCase(word) 12 | expect(res).toBeFalsy() 13 | }) 14 | 15 | test('CheckKebabCase throws when input is not a string', () => { 16 | expect(() => CheckKebabCase(100)).toThrowError() 17 | }) 18 | -------------------------------------------------------------------------------- /String/test/CheckPalindrome.test.js: -------------------------------------------------------------------------------- 1 | import { checkPalindrome } from '../CheckPalindrome' 2 | 3 | describe('checkPalindrome', () => { 4 | it('expects to return "Palindrome" if the given string is a palindrome', () => { 5 | const SUT = checkPalindrome('madam') 6 | expect(SUT).toBe('Palindrome') 7 | }) 8 | it('expects to return "Empty string" if the given string is empty', () => { 9 | const SUT = checkPalindrome('') 10 | expect(SUT).toBe('Empty string') 11 | }) 12 | it('expects to return "Not a string" if the given string is not a string', () => { 13 | const SUT = checkPalindrome(123) 14 | expect(SUT).toBe('Not a string') 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /String/test/CheckPascalCase.test.js: -------------------------------------------------------------------------------- 1 | import { CheckPascalCase } from '../CheckPascalCase' 2 | 3 | test('CheckPascalCase(TheAlgorithms) -> true', () => { 4 | const word = 'TheAlgorithms' 5 | const res = CheckPascalCase(word) 6 | expect(res).toBeTruthy() 7 | }) 8 | 9 | test('CheckPascalCase(theAlgorithms) -> false', () => { 10 | const word = 'theAlgorithms' 11 | const res = CheckPascalCase(word) 12 | expect(res).toBeFalsy() 13 | }) 14 | 15 | test('CheckPascalCase(The Algorithms) -> false', () => { 16 | const word = 'The Algorithms' 17 | const res = CheckPascalCase(word) 18 | expect(res).toBeFalsy() 19 | }) 20 | 21 | test('CheckPascalCase throws when input is not a string', () => { 22 | expect(() => CheckPascalCase(100)).toThrowError() 23 | }) 24 | -------------------------------------------------------------------------------- /String/test/CheckRearrangePalindrome.test.js: -------------------------------------------------------------------------------- 1 | import { palindromeRearranging } from '../CheckRearrangePalindrome' 2 | 3 | test('palindromeRearranging(apple) -> false', () => { 4 | const word = 'apple' 5 | const res = palindromeRearranging(word) 6 | expect(res).toBeFalsy() 7 | }) 8 | 9 | test('palindromeRearranging(aapplle) -> true', () => { 10 | const word = 'aapplle' 11 | const res = palindromeRearranging(word) 12 | expect(res).toBeTruthy() 13 | }) 14 | 15 | test('palindromeRearranging(value) -> false', () => { 16 | const word = 'value' 17 | const res = palindromeRearranging(word) 18 | expect(res).toBeFalsy() 19 | }) 20 | 21 | test('palindromeRearranging(aaeccrr) -> true', () => { 22 | const word = 'aaeccrr' 23 | const res = palindromeRearranging(word) 24 | expect(res).toBeTruthy() 25 | }) 26 | -------------------------------------------------------------------------------- /String/test/CheckSnakeCase.test.js: -------------------------------------------------------------------------------- 1 | import { checkSnakeCase } from '../CheckSnakeCase' 2 | describe('checkSnakeCase', () => { 3 | it('expect to throw an error if input is not a string', () => { 4 | expect(() => checkSnakeCase(0)).toThrow() 5 | }) 6 | 7 | it('expects to return true if the input is in snake case format', () => { 8 | const value = 'docker_build' 9 | const result = checkSnakeCase(value) 10 | expect(result).toBe(true) 11 | }) 12 | 13 | it('expects to return false if the input is not in snake case format', () => { 14 | const value = 'dockerBuild' 15 | const result = checkSnakeCase(value) 16 | expect(result).toBe(false) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /String/test/CreatePermutations.test.js: -------------------------------------------------------------------------------- 1 | import { createPermutations } from '../CreatePermutations' 2 | 3 | describe('createPermutations', () => { 4 | it('expects to generate 6 different combinations', () => { 5 | const text = 'abc' 6 | const SUT = createPermutations(text) 7 | expect(SUT).toStrictEqual(['abc', 'acb', 'bac', 'bca', 'cab', 'cba']) 8 | }) 9 | it('expects to generate 2 different combinations', () => { 10 | const text = '12' 11 | const SUT = createPermutations(text) 12 | expect(SUT).toStrictEqual(['12', '21']) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /String/test/DiceCoefficient.test.js: -------------------------------------------------------------------------------- 1 | import { diceCoefficient } from '../DiceCoefficient' 2 | 3 | describe('diceCoefficient', () => { 4 | it('should calculate edit distance between two strings', () => { 5 | // equal strings return 1 (max possible value) 6 | expect(diceCoefficient('abc', 'abc')).toBe(1) 7 | expect(diceCoefficient('', '')).toBe(1) 8 | 9 | // string length needs to be at least 2 (unless equal) 10 | expect(diceCoefficient('a', '')).toBe(0) 11 | expect(diceCoefficient('', 'a')).toBe(0) 12 | 13 | expect(diceCoefficient('skate', 'ate')).toBe(0.66) 14 | 15 | expect(diceCoefficient('money', 'honey')).toBe(0.75) 16 | 17 | expect(diceCoefficient('love', 'hate')).toBe(0) 18 | 19 | expect(diceCoefficient('skilled', 'killed')).toBe(0.9) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /String/test/FirstUniqueCharacter.test.js: -------------------------------------------------------------------------------- 1 | import { firstUniqChar } from '../FirstUniqueCharacter' 2 | 3 | describe('firstUniqChar', () => { 4 | it('locates the index of first unique character in the string', () => { 5 | expect(firstUniqChar('javascript')).toEqual(0) 6 | expect(firstUniqChar('sesquipedalian')).toEqual(3) 7 | expect(firstUniqChar('aabb')).toEqual(-1) 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /String/test/FormatPhoneNumber.test.js: -------------------------------------------------------------------------------- 1 | import formatPhoneNumber from '../FormatPhoneNumber' 2 | 3 | describe('Testing the formatPhoneNumber functions', () => { 4 | it('expects to throw a type error', () => { 5 | expect(() => formatPhoneNumber('1234567')).toThrow('Invalid phone number!') 6 | expect(() => formatPhoneNumber('123456text')).toThrow( 7 | 'Invalid phone number!' 8 | ) 9 | expect(() => formatPhoneNumber(12345)).toThrow('Invalid phone number!') 10 | }) 11 | 12 | it('expects to return the formatted phone number', () => { 13 | expect(formatPhoneNumber('1234567890')).toEqual('(123) 456-7890') 14 | expect(formatPhoneNumber('2124323322')).toEqual('(212) 432-3322') 15 | expect(formatPhoneNumber('1721543455')).toEqual('(172) 154-3455') 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /String/test/HammingDistance.test.js: -------------------------------------------------------------------------------- 1 | import { hammingDistance } from '../HammingDistance' 2 | 3 | test('should throw an error when trying to compare the strings of different length', () => { 4 | const compareStringsOfDifferentLength = () => { 5 | hammingDistance('abc', 'abcd') 6 | } 7 | 8 | expect(compareStringsOfDifferentLength).toThrowError() 9 | }) 10 | 11 | test('should calculate difference between two strings', () => { 12 | expect(hammingDistance('a', 'a')).toBe(0) 13 | }) 14 | 15 | test('should calculate difference between two strings', () => { 16 | expect(hammingDistance('abc', 'add')).toBe(2) 17 | }) 18 | 19 | test('should calculate difference between two strings', () => { 20 | expect(hammingDistance('1011101', '1001001')).toBe(2) 21 | }) 22 | -------------------------------------------------------------------------------- /String/test/Lower.test.js: -------------------------------------------------------------------------------- 1 | import lower from '../Lower' 2 | 3 | describe('Testing the Lower function', () => { 4 | it('Test 1: Check by invalid type', () => { 5 | expect(() => lower(345)).toThrowError() 6 | expect(() => lower(true)).toThrowError() 7 | expect(() => lower(null)).toThrowError() 8 | }) 9 | 10 | it('Test 2: Check by uppercase string', () => { 11 | expect(lower('WORLD')).toBe('world') 12 | expect(lower('Hello_WORLD')).toBe('hello_world') 13 | }) 14 | 15 | it('Test 3: Check by lowercase string', () => { 16 | expect(lower('hello')).toBe('hello') 17 | expect(lower('hello_world')).toBe('hello_world') 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /String/test/MaxCharacter.test.js: -------------------------------------------------------------------------------- 1 | import maxCharacter from '../MaxCharacter' 2 | 3 | describe('Testing the maxCharacter function', () => { 4 | it('Expect throw with wrong arg', () => { 5 | expect(() => maxCharacter(123)).toThrow() 6 | expect(() => maxCharacter('')).toThrow() 7 | }) 8 | 9 | it('Check the max character in string', () => { 10 | const theString = "I can't do that" 11 | const maxCharInAllCount = maxCharacter(theString) 12 | const maxChar = maxCharacter(theString, /\s/) 13 | 14 | expect(maxCharInAllCount).toBe(' ') 15 | expect(maxChar).toBe('t') 16 | 17 | expect(maxCharacter('!!!Hello, World!!!', /[a-z]/)).toBe('!') 18 | 19 | expect(maxCharacter('!!!Hello, World!!!', /[^a-z]/i)).toBe('l') 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /String/test/MaxWord.test.js: -------------------------------------------------------------------------------- 1 | import { maxWord } from '../MaxWord' 2 | 3 | describe('Testing the maxWord function', () => { 4 | it('Expect throw with non string argument', () => { 5 | expect(() => maxWord(10)).toThrow() 6 | }) 7 | it('get the max word', () => { 8 | const string = 'be be be be a a banana' 9 | const mostOccurringWord = maxWord(string) 10 | expect(mostOccurringWord).toBe('be') 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /String/test/PercentageOfLetters.test.js: -------------------------------------------------------------------------------- 1 | import { percentageOfLetter } from '../PercentageOfLetters' 2 | 3 | describe('Percentage of Letters in a String', () => { 4 | test('Calculate percent for lower case', () => { 5 | expect(percentageOfLetter('foobar', 'o')).toEqual(33) 6 | expect(percentageOfLetter('aaabcd', 'a')).toEqual(50) 7 | }) 8 | test('Calculate percent for upper case', () => { 9 | expect(percentageOfLetter('foobar', 'o')).toEqual(33) 10 | expect(percentageOfLetter('aAabcd', 'a')).toEqual(50) 11 | }) 12 | test('Throwing an exception', () => { 13 | expect(() => percentageOfLetter(100, 'string')).toThrow() 14 | expect(() => percentageOfLetter('string', true)).toThrow() 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /String/test/ReverseWords.test.js: -------------------------------------------------------------------------------- 1 | import reverseWords from '../ReverseWords' 2 | 3 | describe('Testing the reverseWords function', () => { 4 | it.each` 5 | input 6 | ${123456} 7 | ${[1, 2, 3, 4, 5, 6]} 8 | ${{ test: 'test' }} 9 | ${null} 10 | `( 11 | 'expects to throw a type error given a value that is $input', 12 | ({ input }) => { 13 | expect(() => { 14 | reverseWords(input) 15 | }).toThrow('The given value is not a string') 16 | } 17 | ) 18 | 19 | it('expects to reverse words to return a joined word', () => { 20 | expect(reverseWords('I Love JS')).toBe('JS Love I') 21 | expect(reverseWords('Hello World')).toBe('World Hello') 22 | expect(reverseWords('The Algorithms Javascript')).toBe( 23 | 'Javascript Algorithms The' 24 | ) 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /String/test/ScrambleStrings.test.js: -------------------------------------------------------------------------------- 1 | import { isScramble } from '../ScrambleStrings' 2 | 3 | describe('ScrambleStrings', () => { 4 | it('expects to return true for same string', () => { 5 | expect(isScramble('a', 'a')).toBe(true) 6 | }) 7 | 8 | it('expects to return false for non-scrambled strings', () => { 9 | expect(isScramble('abcde', 'caebd')).toBe(false) 10 | }) 11 | 12 | it('expects to return true for scrambled strings', () => { 13 | expect(isScramble('great', 'rgeat')).toBe(true) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /String/test/Upper.test.js: -------------------------------------------------------------------------------- 1 | import upper from '../Upper' 2 | 3 | describe('Testing the Upper function', () => { 4 | it('return uppercase strings', () => { 5 | expect(upper('hello')).toBe('HELLO') 6 | expect(upper('WORLD')).toBe('WORLD') 7 | expect(upper('hello_WORLD')).toBe('HELLO_WORLD') 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /String/test/ZFunction.test.js: -------------------------------------------------------------------------------- 1 | import zFunction from '../ZFunction' 2 | 3 | test('Testing zFunction', () => { 4 | expect(zFunction('aabxaayaab')).toEqual([10, 1, 0, 0, 2, 1, 0, 3, 1, 0]) 5 | expect(zFunction('aabxaabxcaabxaabxay')).toEqual([ 6 | 19, 1, 0, 0, 4, 1, 0, 0, 0, 8, 1, 0, 0, 5, 1, 0, 0, 1, 0 7 | ]) 8 | }) 9 | -------------------------------------------------------------------------------- /Timing-Functions/ParseDate.js: -------------------------------------------------------------------------------- 1 | import { getMonthDays } from './GetMonthDays' 2 | 3 | function checkDate(date) { 4 | if (date.day < 1 || date.day > getMonthDays(date.month, date.year)) { 5 | throw new Error('Invalid day value.') 6 | } 7 | } 8 | 9 | function parseDate(dateString) { 10 | const regex = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/ 11 | 12 | const match = dateString.match(regex) 13 | 14 | if (!match) { 15 | throw new Error("Invalid date format. Please use 'dd/mm/yyyy'.") 16 | } 17 | 18 | const res = { 19 | day: parseInt(match[1], 10), 20 | month: parseInt(match[2], 10), 21 | year: parseInt(match[3], 10) 22 | } 23 | checkDate(res) 24 | return res 25 | } 26 | 27 | export { parseDate } 28 | -------------------------------------------------------------------------------- /Trees/test/FenwickTree.test.js: -------------------------------------------------------------------------------- 1 | import { FenwickTree } from '../FenwickTree' 2 | 3 | describe('Fenwick Tree Implementation', () => { 4 | const fenwickArray = new Array(1000) 5 | const array = [3, 2, 0, 6, 5, -1, 2] 6 | const length = array.length 7 | 8 | const fenwickTree = new FenwickTree(fenwickArray, array, length) 9 | 10 | it('Fenwick Tree - Prefix sum of array', () => { 11 | const prefixSum = fenwickTree.getPrefixSum(fenwickArray, 6) 12 | expect(prefixSum).toBe(23) 13 | }) 14 | 15 | array[2] += 6 16 | fenwickTree.update(fenwickArray, length, 2, 6) 17 | 18 | it('Fenwick Tree - Prefix sum of Updated array', () => { 19 | const prefixSum = fenwickTree.getPrefixSum(fenwickArray, 6) 20 | expect(prefixSum).toBe(23) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "description": "A repository for All algorithms implemented in Javascript (for educational purposes only)", 6 | "scripts": { 7 | "test": "vitest run", 8 | "test-watch": "vitest", 9 | "style": "npx prettier . --write", 10 | "check-style": "npx prettier . --check", 11 | "prepare": "husky install" 12 | }, 13 | "author": "TheAlgorithms", 14 | "license": "GPL-3.0", 15 | "devDependencies": { 16 | "globby": "^13.2.2", 17 | "husky": "^8.0.3", 18 | "prettier": "^3.0.3", 19 | "vitest": "^1.2.1", 20 | "@vitest/coverage-v8": "^1.2.1" 21 | }, 22 | "engines": { 23 | "node": ">=20.6.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | test: { 5 | globals: true, 6 | restoreMocks: true, 7 | coverage: { 8 | reporter: ['text', 'json', 'html'] 9 | } 10 | } 11 | }) 12 | --------------------------------------------------------------------------------