Showing preview only (1,114K chars total). Download the full file or copy to clipboard to get everything.
Repository: TheAlgorithms/JavaScript
Branch: master
Commit: 5c39e87a9a31
Files: 751
Total size: 962.4 KB
Directory structure:
gitextract_1dh1r31z/
├── .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/
│ │ ├── LocalMaximumPoint.js
│ │ ├── NumberOfLocalMaximumPoints.js
│ │ ├── QuickSelect.js
│ │ ├── Reverse.js
│ │ └── test/
│ │ ├── LocalMaximumPoint.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
├── Sliding-Windows/
│ ├── LongestSubarrayWithSumAtMost.js
│ ├── MaxSumSubarrayFixed.js
│ └── test/
│ ├── LongestSubarrayWithSumAtMost.test.js
│ └── MaxSumSubarrayFixed.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.json
└── vitest.config.ts
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/CODEOWNERS
================================================
* @appgurueu
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug report
description: 'Create a report to help us improve'
title: '[BUG]: '
labels: ['bug']
body:
- type: markdown
attributes:
value: '### Before you open an issue, please verify if a similar one already exists or has been closed before. More details about the process of contributing can be found in [CONTRIBUTING.md](https://github.com/TheAlgorithms/JavaScript/blob/master/CONTRIBUTING.md).'
- type: textarea
id: description
attributes:
label: Description
description: Explain what the problem is.
validations:
required: true
- type: textarea
id: expectedbhv
attributes:
label: Expected Behavior
description: Describe what was the expected behavior.
validations:
required: true
- type: textarea
id: actualbhv
attributes:
label: Actual Behavior
description: Describe what actually happens.
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to reproduce (if applicable)
description: List steps to reproduce the behavior.
placeholder: |
1.
2.
3.
4.
validations:
required: false
- type: textarea
id: extra_information
attributes:
label: Additional information
description: Is there anything else we should know about this bug report?
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: Discord community
url: https://the-algorithms.com/discord/
about: Have any questions or found any bugs? Contact us via our Discord community.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yml
================================================
name: Feature request
description: 'Suggest features, propose improvements, discuss new ideas'
title: '[FEATURE]: '
labels: ['enhancement']
body:
- type: markdown
attributes:
value: |
## This issue template is not for requesting new algorithms. For new algorithms, PRs should be opened directly.
## Make sure your issue isn't a duplicate and you follow our [contributing guidelines](https://github.com/TheAlgorithms/JavaScript/blob/master/CONTRIBUTING.md)
- type: textarea
id: description
attributes:
label: Motivation
description: Describe what is the motivation behind this feature.
validations:
required: true
- type: textarea
id: examples
attributes:
label: Examples
description: If possible, provide examples of how this feature can be used.
validations:
required: false
- type: textarea
id: workarounds
attributes:
label: Possible workarounds
description: If possible, describes possible workarounds to this feature.
validations:
required: false
- type: textarea
id: extra_information
attributes:
label: Additional information
description: Is there anything else we should know about this feature request?
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/other.yml
================================================
name: Other issue
description: Use this for any other issues. Do NOT create blank issues
title: "[OTHER]: "
labels: ["awaiting triage"]
body:
- type: textarea
id: description
attributes:
label: What would you like to share?
description: Provide a clear and concise explanation of your issue.
validations:
required: true
- type: textarea
id: extrainfo
attributes:
label: Additional information
description: Is there anything else we should know about this issue?
validations:
required: false
================================================
FILE: .github/dependabot.yml
================================================
# Keep GitHub Actions up to date with Dependabot...
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
================================================
FILE: .github/pull_request_template.md
================================================
[](https://gitpod.io/from-referrer/) [know more](https://www.gitpod.io/docs/pull-requests/)
### Describe your change:
- [ ] Add an algorithm?
- [ ] Fix a bug or typo in an existing algorithm?
- [ ] Documentation change?
### Checklist:
- [ ] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Javascript/blob/master/CONTRIBUTING.md).
- [ ] This pull request is all my own work -- I have not plagiarized.
- [ ] I know that pull requests will not be merged if they fail the automated tests.
- [ ] This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
- [ ] All new JavaScript files are placed inside an existing directory.
- [ ] All filenames should use the UpperCamelCase (PascalCase) style. There should be no spaces in filenames.
**Example:**`UserProfile.js` is allowed but `userprofile.js`,`Userprofile.js`,`user-Profile.js`,`userProfile.js` are not
- [ ] All new algorithms have a URL in their comments that points to Wikipedia or another similar explanation.
- [ ] If this pull request resolves one or more open issues then the commit message contains `Fixes: #{$ISSUE_NO}`.
================================================
FILE: .github/stale.yml
================================================
# Number of days of inactivity before an issue becomes stale (2 weeks)
daysUntilStale: 14
# Number of days of inactivity before a stale issue is closed (a week)
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- bug
- help wanted
- OK to merge
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: >
Please reopen this issue once you commit the changes requested or
make improvements on the code. Thank you for your contributions.
================================================
FILE: .github/workflows/Ci.yml
================================================
name: Continuous Integration
on:
push:
branches:
- master
pull_request:
jobs:
build:
name: Code style and tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: 📦 Install dependencies
run: npm ci
- name: 🧪 Run all tests
run: npm run test
- name: 💄 Code style
run: npm run check-style
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: codespell-project/actions-codespell@master
with:
# file types to ignore
skip: "*.json,*.yml,DIRECTORY.md"
ignore_words_list: "ba,esy,yse,falsy,abd"
================================================
FILE: .github/workflows/UpdateDirectory.js
================================================
import path from 'path'
import fs from 'fs'
import { globby } from 'globby'
function pathPrefix (i) {
const res = ' '.repeat(i)
return res + '*'
}
function printPath (oldPath, newPath, output) {
const oldParts = oldPath.split(path.sep)
const newParts = newPath.split(path.sep)
for (let i = 0; i < newParts.length; ++i) {
const newPart = newParts[i]
if (i + 1 > oldParts.length || oldParts[i] !== newPart) {
if (newPart) {
output.push(`${pathPrefix(i)} **${newPart.replace('_', ' ')}**`)
}
}
}
return newPath
}
function pathsToMarkdown (filePaths) {
const output = []
let oldPath = ''
filePaths.sort(function (a, b) {
if (a.toLowerCase() < b.toLowerCase()) return -1
if (a.toLowerCase() > b.toLowerCase()) return 1
return 0
})
for (let filepath of filePaths) {
let filename = path.basename(filepath)
filepath = path.dirname(filepath)
if (filepath !== oldPath) {
oldPath = printPath(oldPath, filepath, output)
}
let indent = filepath.split(path.sep).length
// prepare the markdown-esque prefix to the file's line
const prefix = pathPrefix(indent)
// remove extension from filename
const name = path.basename(filename, ".js")
const url = path.join(filepath, filename)
output.push(`${prefix} [${name}](${url})`)
}
return output.join('\n')
}
// get paths of all .js files - excluding node_modules, the .github folder, tests and config stuff
globby([
'**/*.js',
'!(node_modules|.github)/**/*',
"!**/test/**/*",
'!**/*.test.js',
'!**/*.manual-test.js',
'!vitest.config.ts'
])
// create markdown content
.then(pathsToMarkdown)
// write markdown to file
.then(markdown => fs.writeFileSync('DIRECTORY.md', markdown + '\n', { encoding: 'utf8' }))
================================================
FILE: .github/workflows/UpdateDirectory.yml
================================================
# This GitHub Action updates the DIRECTORY.md file (if needed) when doing a git push
name: Update Directory
on:
push:
branches-ignore:
"master"
jobs:
updateDirectory:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: 📦 Install dependencies
run: npm ci
- name: 🗄️ Create Directory from JS files
run: node .github/workflows/UpdateDirectory.js
- name: Configure Github Action
run: |
git config --global user.name "$GITHUB_ACTOR"
git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: 🤓 Commit & push new Directory (if needed)
run: |
if [[ `git status --porcelain` ]]; then
git commit -am "Updated Documentation in README.md"
git push
else
echo "NO CHANGES DETECTED"
fi
================================================
FILE: .github/workflows/UploadCoverageReport.yml
================================================
---
name: UploadCoverageReport
'on':
workflow_dispatch:
push:
branches:
- master
pull_request:
env:
REPORT_PATH: "coverage/coverage-final.json"
jobs:
UploadCoverageReport:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Generate coverage report
run: npm test -- --coverage
- name: Upload coverage to codecov (tokenless)
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
uses: codecov/codecov-action@v4
with:
files: "${{ env.REPORT_PATH }}"
fail_ci_if_error: true
- name: Upload coverage to codecov (with token)
if: "! github.event.pull_request.head.repo.fork "
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: "${{ env.REPORT_PATH }}"
fail_ci_if_error: true
...
================================================
FILE: .gitignore
================================================
# dependencies
/node_modules
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# intelliJ workspace folder
.idea
.vscode
.trae
/coverage
================================================
FILE: .gitpod.yml
================================================
github:
prebuilds:
addBadge: true
addComment: false
addCheck: false
master: true
branches: true
pullRequestsFromForks: true
tasks:
- init: npm install
================================================
FILE: .husky/pre-commit
================================================
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run check-style
npm run test
================================================
FILE: .prettierignore
================================================
.github
DIRECTORY.md
================================================
FILE: .prettierrc
================================================
{
"arrowParens": "always",
"bracketSpacing": true,
"endOfLine": "lf",
"insertPragma": false,
"printWidth": 80,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "none",
"useTabs": false
}
================================================
FILE: Backtracking/AllCombinationsOfSizeK.js
================================================
function generateCombinations(n, k) {
let currentCombination = []
let allCombinations = [] // will be used for storing all combinations
let currentValue = 1
function findCombinations() {
if (currentCombination.length === k) {
// Add the array of size k to the allCombinations array
allCombinations.push([...currentCombination])
return
}
if (currentValue > n) {
// Check for exceeding the range
return
}
currentCombination.push(currentValue++)
findCombinations()
currentCombination.pop()
findCombinations()
currentValue--
}
findCombinations()
return allCombinations
}
export { generateCombinations }
================================================
FILE: Backtracking/GeneratePermutations.js
================================================
/*
* Problem Statement: Generate all distinct permutations of an array (all permutations should be in sorted order);
*
* What is permutations?
* - Permutation means possible arrangements in a set (here it is an array);
*
* Reference to know more about permutations:
* - https://www.britannica.com/science/permutation
*
*/
const swap = (arr, i, j) => {
const newArray = [...arr]
;[newArray[i], newArray[j]] = [newArray[j], newArray[i]] // Swapping elements ES6 way
return newArray
}
const permutations = (arr) => {
const P = []
const permute = (arr, low, high) => {
if (low === high) {
P.push([...arr])
return P
}
for (let i = low; i <= high; i++) {
arr = swap(arr, low, i)
permute(arr, low + 1, high)
}
return P
}
return permute(arr, 0, arr.length - 1)
}
export { permutations }
================================================
FILE: Backtracking/KnightTour.js
================================================
// Wikipedia: https://en.wikipedia.org/wiki/Knight%27s_tour
class OpenKnightTour {
constructor(size) {
// Constructor to initialize the chessboard and size
this.board = new Array(size).fill(0).map(() => new Array(size).fill(0))
this.size = size
}
getMoves([i, j]) {
// Helper function to get the valid moves of the knight from the current position
const moves = [
[i + 2, j - 1],
[i + 2, j + 1],
[i - 2, j - 1],
[i - 2, j + 1],
[i + 1, j - 2],
[i + 1, j + 2],
[i - 1, j - 2],
[i - 1, j + 2]
]
// Filter out moves that are within the board boundaries
return moves.filter(
([y, x]) => y >= 0 && y < this.size && x >= 0 && x < this.size
)
}
isComplete() {
// Helper function to check if the board is complete
return !this.board.map((row) => row.includes(0)).includes(true)
}
solve() {
// Function to find the solution for the given board
for (let i = 0; i < this.size; i++) {
for (let j = 0; j < this.size; j++) {
if (this.solveHelper([i, j], 0)) return true
}
}
return false
}
solveHelper([i, j], curr) {
// Helper function for the main computation
if (this.isComplete()) return true
// Iterate through possible moves and attempt to fill the board
for (const [y, x] of this.getMoves([i, j])) {
if (this.board[y][x] === 0) {
this.board[y][x] = curr + 1
if (this.solveHelper([y, x], curr + 1)) return true
// Backtracking: If the solution is not found, reset the cell to 0
this.board[y][x] = 0
}
}
return false
}
printBoard(output = (value) => console.log(value)) {
// Utility function to display the board
for (const row of this.board) {
let string = ''
for (const elem of row) {
string += elem + '\t'
}
output(string)
}
}
}
export { OpenKnightTour }
================================================
FILE: Backtracking/MColoringProblem.js
================================================
/**
* Colors a graph using up to m colors such that no two adjacent vertices share the same color.
* @param {number[][]} graph - Adjacency matrix of the graph, using 0 for no edge.
* @param {number} m - The number of colors to use.
* @returns {?Array.<number>} A valid M-coloring of the graph using colors 1 to m, or null if none exists.
* @see https://en.wikipedia.org/wiki/Graph_coloring
*/
function mColoring(graph, m) {
const colors = new Array(graph.length).fill(0)
// Check if it's safe to color a vertex with a given color.
function isSafe(vertex, color) {
for (let i = 0; i < graph.length; i++) {
if (graph[vertex][i] && colors[i] === color) {
return false
}
}
return true
}
// Use backtracking to try and color the graph.
function solveColoring(vertex = 0) {
if (vertex === graph.length) {
return true
}
for (let color = 1; color <= m; color++) {
if (isSafe(vertex, color)) {
colors[vertex] = color
if (solveColoring(vertex + 1)) {
return true
}
// If no solution, backtrack.
colors[vertex] = 0
}
}
return false
}
// If coloring is possible, return the colors.
if (solveColoring()) {
return colors
}
return null
}
export { mColoring }
================================================
FILE: Backtracking/NQueens.js
================================================
class NQueens {
constructor(size) {
if (size < 0) {
throw RangeError('Invalid board size')
}
this.board = new Array(size).fill('.').map(() => new Array(size).fill('.'))
this.size = size
this.solutionCount = 0
}
isValid([row, col]) {
// function to check if the placement of the queen in the given location is valid
// checking the left of the current row
for (let i = 0; i < col; i++) {
if (this.board[row][i] === 'Q') return false
}
// checking the upper left diagonal
for (let i = row, j = col; i >= 0 && j >= 0; i--, j--) {
if (this.board[i][j] === 'Q') return false
}
// checking the lower left diagonal
for (let i = row, j = col; j >= 0 && i < this.size; i++, j--) {
if (this.board[i][j] === 'Q') return false
}
return true
}
placeQueen(row, col) {
this.board[row][col] = 'Q'
}
removeQueen(row, col) {
this.board[row][col] = '.'
}
solve(col = 0) {
if (col >= this.size) {
this.solutionCount++
return true
}
for (let i = 0; i < this.size; i++) {
if (this.isValid([i, col])) {
this.placeQueen(i, col)
this.solve(col + 1)
this.removeQueen(i, col)
}
}
return false
}
printBoard(output = (value) => console.log(value)) {
if (!output._isMockFunction) {
output('\n')
}
for (const row of this.board) {
output(row)
}
}
}
export { NQueens }
================================================
FILE: Backtracking/RatInAMaze.js
================================================
/*
* Problem Statement:
* - Given a NxN grid, find whether rat in cell [0, 0] can reach the target in cell [N-1, N-1]
* - The grid is represented as an array of rows. Each row is represented as an array of 0 or 1 values.
* - A cell with value 0 can not be moved through. Value 1 means the rat can move here.
* - The rat can not move diagonally.
*
* Reference for this problem: https://www.geeksforgeeks.org/rat-in-a-maze-backtracking-2/
*
* Based on the original implementation contributed by Chiranjeev Thapliyal (https://github.com/chiranjeev-thapliyal).
*/
/**
* Checks if the given grid is valid.
*
* A grid needs to satisfy these conditions:
* - must not be empty
* - must be a square
* - must not contain values other than {@code 0} and {@code 1}
*
* @param grid The grid to check.
* @throws TypeError When the given grid is invalid.
*/
function validateGrid(grid) {
if (!Array.isArray(grid) || grid.length === 0)
throw new TypeError('Grid must be a non-empty array')
const allRowsHaveCorrectLength = grid.every(
(row) => row.length === grid.length
)
if (!allRowsHaveCorrectLength) throw new TypeError('Grid must be a square')
const allCellsHaveValidValues = grid.every((row) => {
return row.every((cell) => cell === 0 || cell === 1)
})
if (!allCellsHaveValidValues)
throw new TypeError('Grid must only contain 0s and 1s')
}
function isSafe(grid, x, y) {
const n = grid.length
return x >= 0 && x < n && y >= 0 && y < n && grid[y][x] === 1
}
/**
* Attempts to calculate the remaining path to the target.
*
* @param grid The full grid.
* @param x The current X coordinate.
* @param y The current Y coordinate.
* @param solution The current solution matrix.
* @param path The path we took to get from the source cell to the current location.
* @returns {string|boolean} Either the path to the target cell or false.
*/
function getPathPart(grid, x, y, solution, path) {
const n = grid.length
// are we there yet?
if (x === n - 1 && y === n - 1 && grid[y][x] === 1) {
solution[y][x] = 1
return path
}
// did we step on a 0 cell or outside the grid?
if (!isSafe(grid, x, y)) return false
// are we walking onto an already-marked solution coordinate?
if (solution[y][x] === 1) return false
// none of the above? let's dig deeper!
// mark the current coordinates on the solution matrix
solution[y][x] = 1
// attempt to move right
const right = getPathPart(grid, x + 1, y, solution, path + 'R')
if (right) return right
// right didn't work: attempt to move down
const down = getPathPart(grid, x, y + 1, solution, path + 'D')
if (down) return down
// down didn't work: attempt to move up
const up = getPathPart(grid, x, y - 1, solution, path + 'U')
if (up) return up
// up didn't work: attempt to move left
const left = getPathPart(grid, x - 1, y, solution, path + 'L')
if (left) return left
// no direction was successful: remove this cell from the solution matrix and backtrack
solution[y][x] = 0
return false
}
function getPath(grid) {
// grid dimensions
const n = grid.length
// prepare solution matrix
const solution = []
for (let i = 0; i < n; i++) {
const row = Array(n)
row.fill(0)
solution[i] = row
}
return getPathPart(grid, 0, 0, solution, '')
}
/**
* Creates an instance of the "rat in a maze" based on a given grid (maze).
*/
export class RatInAMaze {
constructor(grid) {
// first, let's do some error checking on the input
validateGrid(grid)
// attempt to solve the maze now - all public methods only query the result state later
const solution = getPath(grid)
if (solution !== false) {
this.path = solution
this.solved = true
} else {
this.path = ''
this.solved = false
}
}
}
================================================
FILE: Backtracking/Sudoku.js
================================================
class Sudoku {
// Sudoku Class to hold the board and related functions
constructor(board) {
this.board = board
}
findEmptyCell() {
// Find a empty cell in the board (returns [-1, -1] if all cells are filled)
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
if (this.board[i][j] === 0) return [i, j]
}
}
return [-1, -1]
}
check([y, x], value) {
// checks if the value to be added in the board is an acceptable value for the cell
// checking through the row
for (let i = 0; i < 9; i++) {
if (this.board[i][x] === value) return false
}
// checking through the column
for (let i = 0; i < 9; i++) {
if (this.board[y][i] === value) return false
}
// checking through the 3x3 block of the cell
const secRow = Math.floor(y / 3)
const secCol = Math.floor(x / 3)
for (let i = secRow * 3; i < secRow * 3 + 3; i++) {
for (let j = secCol * 3; j < secCol * 3 + 3; j++) {
if (y !== i && x !== j && this.board[i][j] === value) return false
}
}
return true
}
solve() {
const [y, x] = this.findEmptyCell()
// checking if the board is complete
if (y === -1 && x === -1) return true
for (let val = 1; val < 10; val++) {
if (this.check([y, x], val)) {
this.board[y][x] = val
if (this.solve()) return true
// backtracking if the board cannot be solved using current configuration
this.board[y][x] = 0
}
}
// returning false the board cannot be solved using current configuration
return false
}
getSection(row, [start, end]) {
return this.board[row].slice(start, end)
}
printBoard(output = (...v) => console.log(...v)) {
// helper function to display board
for (let i = 0; i < 9; i++) {
if (i % 3 === 0 && i !== 0) {
output('- - - - - - - - - - - -')
}
output(
...this.getSection(i, [0, 3]),
' | ',
...this.getSection(i, [3, 6]),
' | ',
...this.getSection(i, [6, 9])
)
}
}
}
export { Sudoku }
================================================
FILE: Backtracking/SumOfSubset.js
================================================
/*
*
* Sum of Subset problem
*
* Given an ordered set W of non-negative integers and a value K,
* determine all possible subsets from the given set W whose sum
* of its elements equals to the given value K.
*
* More info: https://www.geeksforgeeks.org/subset-sum-backtracking-4/
*/
/*
* @param {number[]} set Original set of numbers
* @param {number[]} subset Subset being evaluated
* @param {number} setIndex Index from set of last element in subset
* @param {number} Sum of elements from subset
* @param {targetSum} The target sum on which the subset sum is compared to
* @returns {number[][]} Subsets whose elements add up to targetSum
*/
const sumOfSubset = (set, subset, setindex, sum, targetSum) => {
// Base case where the subset sum is equal to target sum
// Evaluation of following subsets on this path will always add up to
// greater than targetSum, so no need to continue
if (sum === targetSum) return [subset]
// This and following subsets on this path will always add up to
// greater than targetSum, so no need to continue
if (sum > targetSum) return []
// Initialize results array. Will contain only valid subsets
let results = []
// Slice gets from the set all the elements at the right of the last element
// to be evaluated (last element of subset)
// forEach iterated on the resulting array
set.slice(setindex).forEach((num, index) => {
// The next subset to be evaluated, current subset plus next element
const nextSubset = [...subset, num]
// Next index from the set. Current set index plus iteration index
// index starts at 0, so a + 1 is required
const nextSetIndex = setindex + index + 1
// Sum of elements from the next subset to be evaluated
const nextSum = sum + num
// Call recursively the sumOfSubset for the nextSubset
const subsetResult = sumOfSubset(
set,
nextSubset,
nextSetIndex,
nextSum,
targetSum
)
// Concat the recursive result with current result array
results = [...results, ...subsetResult]
})
// Return results
return results
}
export { sumOfSubset }
================================================
FILE: Backtracking/generateParentheses.js
================================================
/**
* Problem Statement: Given a number n pairs of parentheses, try to Generate all combinations of valid parentheses;
* @param {number} n - number of given parentheses
* @return {string[]} res - array that contains all valid parentheses
* @see https://leetcode.com/problems/generate-parentheses/
*/
const generateParentheses = (n) => {
const res = []
const solve = (chres, openParenthese, closedParenthese) => {
if (openParenthese === n && closedParenthese === n) {
res.push(chres)
return
}
if (openParenthese <= n) {
solve(chres + '(', openParenthese + 1, closedParenthese)
}
if (closedParenthese < openParenthese) {
solve(chres + ')', openParenthese, closedParenthese + 1)
}
}
solve('', 0, 0)
return res
}
export { generateParentheses }
================================================
FILE: Backtracking/tests/AllCombinationsOfSizeK.test.js
================================================
import { generateCombinations } from '../AllCombinationsOfSizeK'
describe('AllCombinationsOfSizeK', () => {
it('should return 3x2 matrix solution for n = 3 and k = 2', () => {
const res = generateCombinations(3, 2)
expect(res).toEqual([
[1, 2],
[1, 3],
[2, 3]
])
})
it('should return 6x2 matrix solution for n = 4 and k = 2', () => {
const res = generateCombinations(4, 2)
expect(res).toEqual([
[1, 2],
[1, 3],
[1, 4],
[2, 3],
[2, 4],
[3, 4]
])
})
})
================================================
FILE: Backtracking/tests/GenerateParentheses.test.js
================================================
import { generateParentheses } from '../generateParentheses'
test('generate all valid parentheses of input 3', () => {
expect(generateParentheses(3)).toStrictEqual([
'((()))',
'(()())',
'(())()',
'()(())',
'()()()'
])
})
================================================
FILE: Backtracking/tests/GeneratePermutations.test.js
================================================
import { factorial } from '../../Recursive/Factorial'
import { permutations } from '../GeneratePermutations'
describe('Permutations', () => {
it('Permutations of [a]', () => {
const perms = permutations(['a'])
expect(perms).toHaveLength(factorial(1))
expect(perms).toContainEqual(['a'])
})
it('Permutations of [true, false]', () => {
const perms = permutations([true, false])
expect(perms).toHaveLength(factorial(2))
expect(perms).toContainEqual([true, false])
expect(perms).toContainEqual([false, true])
})
it('Permutations of [1, 2, 3]', () => {
const perms = permutations([1, 2, 3])
expect(perms).toHaveLength(factorial(3))
expect(perms).toContainEqual([1, 2, 3])
expect(perms).toContainEqual([1, 3, 2])
expect(perms).toContainEqual([2, 1, 3])
expect(perms).toContainEqual([2, 3, 1])
expect(perms).toContainEqual([3, 1, 2])
expect(perms).toContainEqual([3, 2, 1])
})
it('Permutation counts across larger input arrays', () => {
expect(permutations([1, 2, 3, 4, 5, 6, 7, 8])).toHaveLength(factorial(8))
expect(permutations([1, 2, 3, 4, 5, 6, 7, 8, 9])).toHaveLength(factorial(9))
})
})
================================================
FILE: Backtracking/tests/KnightTour.test.js
================================================
import { OpenKnightTour } from '../KnightTour'
describe('OpenKnightTour', () => {
it('OpenKnightTour(5)', () => {
const KT = new OpenKnightTour(5)
expect(KT.board).toEqual([
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
])
expect(KT.solve()).toBe(true)
expect(KT.board).toEqual([
[19, 4, 15, 10, 25],
[14, 9, 18, 5, 16],
[1, 20, 3, 24, 11],
[8, 13, 22, 17, 6],
[21, 2, 7, 12, 23]
])
})
it('OpenKnightTour(2)', () => {
const KT = new OpenKnightTour(2)
expect(KT.board).toEqual([
[0, 0],
[0, 0]
])
expect(KT.solve()).toBe(false)
expect(KT.board).toEqual([
[0, 0],
[0, 0]
])
})
})
================================================
FILE: Backtracking/tests/MColoringProblem.test.js
================================================
import { mColoring } from '../MColoringProblem'
describe('MColoringProblem', () => {
it('should color a triangle with 3 colors', () => {
const graph = [
[0, 1, 1],
[1, 0, 1],
[1, 1, 0]
]
const solution = mColoring(graph, 3)
expect(solution).not.toBeNull()
})
it('should not color a triangle with 2 colors', () => {
const graph = [
[0, 1, 1],
[1, 0, 1],
[1, 1, 0]
]
const solution = mColoring(graph, 2)
expect(solution).toBeNull()
})
})
================================================
FILE: Backtracking/tests/NQueens.test.js
================================================
import { NQueens } from '../NQueens'
describe('NQueens', () => {
it('should return 2 solutions for 4x4 size board', () => {
const _4Queens = new NQueens(4)
_4Queens.solve()
expect(_4Queens.solutionCount).toEqual(2)
})
it('should return 92 solutions for 8x8 size board', () => {
const _8Queens = new NQueens(8)
_8Queens.solve()
expect(_8Queens.solutionCount).toEqual(92)
})
it('should throw RangeError for negative size board', () => {
expect(() => {
return new NQueens(-1)
}).toThrow(RangeError)
})
})
================================================
FILE: Backtracking/tests/RatInAMaze.test.js
================================================
import { RatInAMaze } from '../RatInAMaze'
describe('RatInAMaze', () => {
it('should fail for non-arrays', () => {
const values = [undefined, null, {}, 42, 'hello, world']
for (const value of values) {
// we deliberately want to check whether this constructor call fails or not
expect(() => {
new RatInAMaze(value)
}).toThrow()
}
})
it('should fail for an empty array', () => {
// we deliberately want to check whether this constructor call fails or not
expect(() => {
new RatInAMaze([])
}).toThrow()
})
it('should fail for a non-square array', () => {
const array = [
[0, 0, 0],
[0, 0]
]
// we deliberately want to check whether this constructor call fails or not
expect(() => {
new RatInAMaze(array)
}).toThrow()
})
it('should fail for arrays containing invalid values', () => {
const values = [[[2]], [['a']]]
for (const value of values) {
// we deliberately want to check whether this constructor call fails or not
expect(() => {
new RatInAMaze(value)
}).toThrow()
}
})
it('should work for a single-cell maze', () => {
const maze = new RatInAMaze([[1]])
expect(maze.solved).toBe(true)
expect(maze.path).toBe('')
})
it('should work for a single-cell maze that can not be solved', () => {
const maze = new RatInAMaze([[0]])
expect(maze.solved).toBe(false)
expect(maze.path).toBe('')
})
it('should work for a simple 3x3 maze', () => {
const maze = new RatInAMaze([
[1, 1, 0],
[0, 1, 0],
[0, 1, 1]
])
expect(maze.solved).toBe(true)
expect(maze.path).toBe('RDDR')
})
it('should work for a simple 2x2 that can not be solved', () => {
const maze = new RatInAMaze([
[1, 0],
[0, 1]
])
expect(maze.solved).toBe(false)
expect(maze.path).toBe('')
})
it('should work for a more complex maze', () => {
const maze = new RatInAMaze([
[1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 1, 0, 0],
[1, 1, 1, 0, 1, 0, 0],
[1, 0, 1, 0, 1, 0, 0],
[1, 0, 1, 1, 1, 0, 0],
[1, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1]
])
expect(maze.solved).toBe(true)
expect(maze.path).toBe('RRRRDDDDLLUULLDDDDRRRRRR')
})
it('should work for a more complex maze that can not be solved', () => {
const maze = new RatInAMaze([
[1, 1, 1, 1, 1, 0, 1],
[0, 0, 0, 0, 1, 0, 1],
[1, 1, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1]
])
expect(maze.solved).toBe(false)
expect(maze.path).toBe('')
})
})
================================================
FILE: Backtracking/tests/Sudoku.test.js
================================================
import { Sudoku } from '../Sudoku'
const data = [
[3, 0, 6, 5, 0, 8, 4, 0, 0],
[5, 2, 0, 0, 0, 0, 0, 0, 0],
[0, 8, 7, 0, 0, 0, 0, 3, 1],
[0, 0, 3, 0, 1, 0, 0, 8, 0],
[9, 0, 0, 8, 6, 3, 0, 0, 5],
[0, 5, 0, 0, 9, 0, 6, 0, 0],
[1, 3, 0, 0, 0, 0, 2, 5, 0],
[0, 0, 0, 0, 0, 0, 0, 7, 4],
[0, 0, 5, 2, 0, 6, 3, 0, 0]
]
const solved = [
[3, 1, 6, 5, 7, 8, 4, 9, 2],
[5, 2, 9, 1, 3, 4, 7, 6, 8],
[4, 8, 7, 6, 2, 9, 5, 3, 1],
[2, 6, 3, 4, 1, 5, 9, 8, 7],
[9, 7, 4, 8, 6, 3, 1, 2, 5],
[8, 5, 1, 7, 9, 2, 6, 4, 3],
[1, 3, 8, 9, 4, 7, 2, 5, 6],
[6, 9, 2, 3, 5, 1, 8, 7, 4],
[7, 4, 5, 2, 8, 6, 3, 1, 9]
]
describe('Sudoku', () => {
it('should create a valid board successfully', () => {
// we deliberately want to check whether this constructor call fails or not
expect(() => {
new Sudoku(data)
}).not.toThrow()
})
it('should find an empty cell', () => {
const board = new Sudoku(data)
const emptyCell = board.findEmptyCell()
expect(emptyCell).not.toEqual([-1, -1])
})
it('should solve the board successfully', () => {
const board = new Sudoku(data)
board.solve()
// should not have empty cells anymore
const emptyCell = board.findEmptyCell()
expect(emptyCell).toEqual([-1, -1])
// solved board should match our expectation
for (let i = 0; i < 9; i++) {
const section = board.getSection(i, [0, 9])
expect(section).toEqual(solved[i])
}
})
})
================================================
FILE: Backtracking/tests/SumOfSubset.test.js
================================================
import { sumOfSubset } from '../SumOfSubset'
describe('SumOfSubset', () => {
it('should return the subsets that add up to the given number', () => {
// W = [2, 5, 7, 8, 12, 16, 23, 40]
// K = 25
const nums = [2, 5, 7, 8, 12, 16, 23, 40]
const subsets = sumOfSubset(nums, [], 0, 0, 25)
expect(subsets).toEqual([
[2, 7, 16],
[2, 23],
[5, 8, 12]
])
})
})
================================================
FILE: Bit-Manipulation/BinaryCountSetBits.js
================================================
/*
author: vivek9patel
license: GPL-3.0 or later
This script will find number of 1's
in binary representation of given number
*/
function BinaryCountSetBits(a) {
'use strict'
// 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
if (!Number.isInteger(a)) throw new TypeError('Argument not an Integer')
let count = 0
while (a) {
a &= a - 1
count++
}
return count
}
export { BinaryCountSetBits }
================================================
FILE: Bit-Manipulation/GenerateSubSets.js
================================================
/**
* @function generateSubSets
* @param {Array} inputArray
* @returns {Array}
* @example [1,2] -> [[],[1],[2],[1,2]]
*/
// The time complexity of this algorithm is BigO(2^n) where n is the length of array
function generateSubSets(inputArray) {
if (!Array.isArray(inputArray)) {
throw new Error('Provided input is not an array')
}
if (inputArray.length > 32) {
throw new RangeError('Error size should be less than equal to 32')
}
let arrayLength = inputArray.length
let subSets = []
// loop till (2^n) - 1
for (let i = 0; i < 1 << arrayLength; i++) {
let subSet = []
for (let j = 0; j < arrayLength; j++) {
// 1 << j it shifts binary digit 1 by j positions and then we perform
// and by AND operation we are checking whetheer jth bit
// in i is set to 1 if result is non zero just add into set
if (i & (1 << j)) {
subSet.push(inputArray[j])
}
}
subSets.push(subSet)
}
return subSets
}
export { generateSubSets }
================================================
FILE: Bit-Manipulation/GrayCodes.js
================================================
/**
* Generates a Gray code sequence for the given number of bits.
* @param {number} n - The number of bits in the Gray code sequence.
* @returns {number[]} - An array of Gray codes in binary format.
* @description
* Gray codes are binary sequences in which two successive values differ in only one bit.
* This function generates a Gray code sequence of length 2^n for the given number of bits.
*
* The algorithm follows these steps:
*
* 1. Initialize an array `grayCodes` to store the Gray codes. Start with [0, 1] for n = 1.
* 2. Iterate from 1 to n:
* a. Calculate `highestBit` as 2^i, where `i` is the current iteration index.
* b. Iterate in reverse order through the existing Gray codes:
* - For each Gray code `code`, add `highestBit | code` to `grayCodes`.
* - This operation flips a single bit in each existing code, creating new codes.
* 3. Return the `grayCodes` array containing the Gray codes in decimal representation.
*
*resources: [GFG](https://www.geeksforgeeks.org/generate-n-bit-gray-codes/)
* @example
* const n = 3;
* const grayCodes = generateGrayCodes(n);
* // grayCodes will be [0, 1, 3, 2, 6, 7, 5, 4] for n=3.
*/
function generateGrayCodes(n) {
if (n <= 0) {
return [0]
}
const grayCodes = [0, 1]
for (let i = 1; i < n; i++) {
const highestBit = 1 << i
for (let j = grayCodes.length - 1; j >= 0; j--) {
grayCodes.push(highestBit | grayCodes[j])
}
}
return grayCodes
}
export { generateGrayCodes }
================================================
FILE: Bit-Manipulation/IsPowerOfTwo.js
================================================
/*
author: @Aayushi-Mittal
This script will check whether the given
number is a power of two or not.
A number will be a power of two if only one bit is set and rest are unset.
This is true for all the cases except 01 because (2^0 = 1) which is not a power of 2.
For eg: 10 (2^1 = 2), 100 (2^2 = 4), 10000 (2^4 = 16)
Reference Link: https://www.hackerearth.com/practice/notes/round-a-number-to-the-next-power-of-2/
If we will subtract 1 from a number that is a power of 2 we will get it's 1's complement.
And we know that 1's complement is just opp. of that number.
So, (n & (n-1)) will be 0.
For eg: (1000 & (1000-1))
1 0 0 0 // Original Number (8)
0 1 1 1 // After Subtracting 1 (8-1 = 7)
_______
0 0 0 0 // will become 0
*/
export const IsPowerOfTwo = (n) => {
return n > 0 && (n & (n - 1)) === 0
}
================================================
FILE: Bit-Manipulation/IsPowerofFour.js
================================================
/**
* @author : dev-madhurendra
* Checks whether the given number is a power of four or not.
*
* A number is considered a power of four if and only if there is a single '1' bit in its binary representation,
* and that '1' bit is at the first position, followed by an even number of '0' bits.
*
* @param {number} n - The input number to check.
* @returns {boolean} True if the number is a power of four, false otherwise.
*
* @example
* const result = isPowerOfFour(16); // Returns true (16 is 4^2)
* const result2 = isPowerOfFour(5); // Returns false (5 is not a power of four)
*/
const isPowerOfFour = (n) => n > 0 && (n & (n - 1)) === 0 && n % 3 === 1
export { isPowerOfFour }
================================================
FILE: Bit-Manipulation/LogTwo.js
================================================
/**
* https://handwiki.org/wiki/Binary_logarithm
* Approximate log2 using only bitwise operators
* @param {number} n
* @returns {number} Log2 approximation equal to floor(log2(n))
*/
export const logTwo = (n) => {
let result = 0
while (n >> 1) {
n >>= 1
result++
}
return result
}
================================================
FILE: Bit-Manipulation/NextPowerOfTwo.js
================================================
/**
*
* This script will find next power of two
* of given number.
* More about it:
* https://www.techiedelight.com/round-next-highest-power-2/
*
*/
export const nextPowerOfTwo = (n) => {
if (n > 0 && (n & (n - 1)) === 0) return n
let result = 1
while (n > 0) {
result = result << 1
n = n >> 1
}
return result
}
================================================
FILE: Bit-Manipulation/SetBit.js
================================================
/*
* Setting Bit: https://www.geeksforgeeks.org/set-k-th-bit-given-number/
*
* To set any bit we use bitwise OR (|) operator.
*
* Bitwise OR (|) compares the bits of the 32
* bit binary representations of the number and
* returns a number after comparing each bit.
*
* 0 | 0 -> 0
* 0 | 1 -> 1
* 1 | 0 -> 1
* 1 | 1 -> 1
*
* In-order to set kth bit of a number (where k is the position where bit is to be changed)
* we need to shift 1 k times to its left and then perform bitwise OR operation with the
* number and result of left shift performed just before.
*
* References:
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR
*/
/**
* @param {number} number
* @param {number} bitPosition - zero based.
* @return {number}
*/
export const setBit = (number, bitPosition) => {
return number | (1 << bitPosition)
}
================================================
FILE: Bit-Manipulation/UniqueElementInAnArray.js
================================================
/**
* Finds the unique element in an array where all other elements are repeated twice.
*
* @param {number[]} arr - The input array of integers.
* @returns {number} The unique element.
*
* @example
* const arr = [1, 2, 1, 2, 3];
* const uniqueElement = findUniqueElement(arr); // Returns 3
*/
const findUniqueElement = (arr) => arr.reduce((acc, val) => acc ^ val, 0)
export { findUniqueElement }
================================================
FILE: Bit-Manipulation/test/BinaryCountSetBits.test.js
================================================
import { BinaryCountSetBits } from '../BinaryCountSetBits'
test('check BinaryCountSetBits of 25 is 3', () => {
const res = BinaryCountSetBits(25)
expect(res).toBe(3)
})
test('check BinaryCountSetBits of 36 is 2', () => {
const res = BinaryCountSetBits(36)
expect(res).toBe(2)
})
test('check BinaryCountSetBits of 16 is 1', () => {
const res = BinaryCountSetBits(16)
expect(res).toBe(1)
})
test('check BinaryCountSetBits of 58 is 4', () => {
const res = BinaryCountSetBits(58)
expect(res).toBe(4)
})
test('check BinaryCountSetBits of 4294967295 is 32', () => {
const res = BinaryCountSetBits(4294967295)
expect(res).toBe(32)
})
test('check BinaryCountSetBits of 0 is 0', () => {
const res = BinaryCountSetBits(0)
expect(res).toBe(0)
})
test('check BinaryCountSetBits of 21.1 throws error', () => {
expect(() => BinaryCountSetBits(21.1)).toThrow()
})
test('check BinaryCountSetBits of {} throws error', () => {
expect(() => BinaryCountSetBits({})).toThrow()
})
================================================
FILE: Bit-Manipulation/test/GenerateSubSets.test.js
================================================
import { generateSubSets } from '../GenerateSubSets'
describe('subSets', () => {
it('find the subsets', () => {
expect(generateSubSets([1, 2, 3])).toEqual([
[],
[1],
[2],
[1, 2],
[3],
[1, 3],
[2, 3],
[1, 2, 3]
])
expect(generateSubSets([1, 2])).toEqual([[], [1], [2], [1, 2]])
expect(generateSubSets([1, 2, 3])).toEqual([
[],
[1],
[2],
[1, 2],
[3],
[1, 3],
[2, 3],
[1, 2, 3]
])
expect(() => generateSubSets('invalid')).toThrow(
'Provided input is not an array'
)
expect(() =>
generateSubSets([
1, 2, 2, 1, 2, 3, 4, 3, 2, 3, 4, 3, 2, 2, 2, 3, 12, 11, 4, 2, 2, 2, 2,
1, 2, 3, 5, 6, 7, 7, 8, 6, 5, 6, 7, 8, 9, 8, 0, 6
])
).toThrow('Error size should be less than equal to 32')
})
})
================================================
FILE: Bit-Manipulation/test/GrayCodes.test.js
================================================
import { generateGrayCodes } from '../GrayCodes.js'
describe('Gray codes', () => {
test.each([
[0, [0b0]],
[1, [0b0, 0b1]],
[2, [0b00, 0b01, 0b11, 0b10]],
[3, [0b000, 0b001, 0b011, 0b010, 0b110, 0b111, 0b101, 0b100]],
[
4,
[
0b0000, 0b0001, 0b0011, 0b0010, 0b0110, 0b0111, 0b0101, 0b0100, 0b1100,
0b1101, 0b1111, 0b1110, 0b1010, 0b1011, 0b1001, 0b1000
]
]
])('n = %i -> %j', (n, expected) => {
expect(generateGrayCodes(n)).toEqual(expected)
})
})
================================================
FILE: Bit-Manipulation/test/IsPowerOfFour.test.js
================================================
import { isPowerOfFour } from '../IsPowerofFour'
describe('IsPowerOfFour', () => {
it.each([
[0, false],
[4, true],
[16, true],
[12, false],
[64, true],
[-64, false]
])('should return the number is power of four or not', (n, expected) => {
expect(isPowerOfFour(n)).toBe(expected)
})
})
================================================
FILE: Bit-Manipulation/test/IsPowerOfTwo.test.js
================================================
import { IsPowerOfTwo } from '../IsPowerOfTwo'
test('Check if 0 is a power of 2 or not:', () => {
const res = IsPowerOfTwo(0)
expect(res).toBe(false)
})
test('Check if 1 is a power of 2 or not:', () => {
const res = IsPowerOfTwo(1)
expect(res).toBe(true)
})
test('Check if 4 is a power of 2 or not:', () => {
const res = IsPowerOfTwo(4)
expect(res).toBe(true)
})
test('Check if 1024 is a power of 2 or not:', () => {
const res = IsPowerOfTwo(1024)
expect(res).toBe(true)
})
test('Check if 1025 is a power of 2 or not:', () => {
const res = IsPowerOfTwo(1025)
expect(res).toBe(false)
})
================================================
FILE: Bit-Manipulation/test/LogTwo.test.js
================================================
import { logTwo } from '../LogTwo'
for (let i = 1; i < 100; i++) {
test('log2(' + i + ')', () => {
expect(logTwo(i)).toBe(Math.floor(Math.log2(i)))
})
}
================================================
FILE: Bit-Manipulation/test/NextPowerOfTwo.test.js
================================================
import { nextPowerOfTwo } from '../NextPowerOfTwo'
describe('NextPowerOfTwo', () => {
it.each`
input | result
${0} | ${1}
${1} | ${1}
${2} | ${2}
${3} | ${4}
${5} | ${8}
${125} | ${128}
${1024} | ${1024}
${10000} | ${16384}
`('returns $result when is given $input', ({ input, result }) => {
const res = nextPowerOfTwo(input)
expect(res).toBe(result)
})
})
================================================
FILE: Bit-Manipulation/test/SetBit.test.js
================================================
import { setBit } from '../SetBit'
test('Set bit number 0 in 1:', () => {
const setBitPos = setBit(1, 0)
expect(setBitPos).toBe(1)
})
test('Set bit number 0 in 2:', () => {
const setBitPos = setBit(2, 0)
expect(setBitPos).toBe(3)
})
test('Set bit number 1 in 10:', () => {
const setBitPos = setBit(10, 1)
expect(setBitPos).toBe(10)
})
test('Set bit number 2 in 10:', () => {
const setBitPos = setBit(10, 2)
expect(setBitPos).toBe(14)
})
================================================
FILE: Bit-Manipulation/test/UniqueElementInAnArray.test.js
================================================
import { findUniqueElement } from '../UniqueElementInAnArray'
describe('UniqueElementInAnArray', () => {
it.each([
[[1, 2, 1, 3, 3], 2],
[[1, 2, 3, 4, 5, 4, 3, 2, 1], 5]
])('should return an unique element from an array', (arr, expected) => {
expect(findUniqueElement(arr)).toBe(expected)
})
})
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing guidelines
## Before contributing
Welcome to [TheAlgorithms/JavaScript](https://github.com/TheAlgorithms/JavaScript)! Before sending your pull requests,
make sure that you **read the whole guidelines**. If you have any doubts about the contributing guide, please feel free to
[state them clearly in an issue](https://github.com/TheAlgorithms/JavaScript/issues/new) or by joining our [Discord community](https://the-algorithms.com/discord).
## Contributing
### Contributor
We are very happy that you consider implementing algorithms and data structures for others! This repository is
referenced and used by learners from around the globe. Being one of our contributors, you agree and confirm that:
- You did your work - plagiarism is not allowed.
- Any plagiarized work will not be merged.
- Your work will be distributed under the [GNU GPLv3.0](https://github.com/TheAlgorithms/JavaScript/blob/master/LICENSE) once your pull request is merged.
- Your submitted work must fulfill our styles and standards.
**New implementations** are welcome! For example, new solutions to a problem, different representations of a graph data
structure, or algorithm designs with different complexity.
**Improving comments** and **writing proper tests** are also highly welcome.
### Contribution
We appreciate any contribution, from fixing grammar mistakes to implementing complex algorithms. Please read this
section if you are contributing to your work.
If you submit a pull request that resolves an open issue, please help us to keep our issue list small by adding
`fixes: #{$ISSUE_NO}` to your commit message. GitHub will use this tag to auto-close the issue if your PR is merged.
#### What is an Algorithm?
An Algorithm is one or more functions (or classes) that:
- take one or more inputs.
- perform some internal calculations or data manipulations.
- return one or more outputs.
- have minimal side effects.
Algorithms should be packaged in a way that would make it easy for readers to put them into larger programs.
Algorithms should:
- have intuitive class and function names that make their purpose clear to readers.
- use JavaScript naming conventions and intuitive variable names to ease comprehension.
- be flexible to take different input values.
- raise JavaScript exceptions (RangeError, etc.) on erroneous input values.
Algorithms in this repo should not be how-to examples for existing JavaScript packages. Instead, they should perform
internal calculations or manipulations to convert input values into different output values. Those calculations or
manipulations can use data types, classes, or functions of existing JavaScript packages but each algorithm in this repo
should add a unique value.
#### Commit guidelines
- Follow [**Conventional Commits**](https://www.conventionalcommits.org/en/v1.0.0/) guidelines at all times.
- Use one of the following prefixes (there might be other miscellaneous prefixes, though).
- fix: A bug fix in an algorithm, workflow, configuration/settings, etc..
- feat: A new feature, such as new algorithms, new workflows, etc..
- docs: Documentation changes or fixes, like improving the contributing guidelines, fixing a typo, etc..
- test: Correct existing tests or add new ones.
- chore: Miscellaneous changes that do not match any of the above.
Examples of best commit messages.
```txt
fix: fixed error in XYZ algorithm
feat: re-work the CI workflow
docs: improve the contributing guidelines
test: add self-tests for XYZ algorithm
chore: update readme badges
```
#### File Naming Convention
- Filenames should use the UpperCamelCase (PascalCase) style.
- There should be no spaces in filenames.
- **Example:** `UserProfile.js` is allowed but `userprofile.js`,`Userprofile.js`,`user-Profile.js`,`userProfile.js` are
not.
#### Module System
We use the [ES Module](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/) system, which brings an
official, standardized module system to JavaScript.
It roughly means you will need to use `export` and `import` statements instead of `module.exports` and `require()`.
#### Testing
Be confident that your code works. When was the last time you committed a code change, your build failed, and half of
your app stopped working? Mine was last week. Writing tests for our Algorithms will help us ensure the implementations
are airtight even after multiple fixes and code changes.
We use [Vitest](https://vitest.dev/) to run unit tests on our algorithms. It provides a very readable and expressive
way to structure your test code.
It is advised that the algorithm file (module) does not contain any "live" code but rather just exports the function(s)
needed to execute the algorithm. Your test code can import those function(s), call them with the appropriate parameters
and inspect the outcome. Example: [RatInAMaze.test.js](Backtracking/tests/RatInAMaze.test.js).
Please refrain from using `console` in your implementation AND test code.
First, you should install all dependencies using:
```bash
npm install
```
You can (and should!) run all tests locally before committing your changes:
```bash
npm test
```
If you want to save some time and just run a specific test:
```bash
# This will run any test file where the filename contains "koch" (no need to specify folder path)
npm test -- koch
```
You can also start Vitest in "watch" mode:
```bash
npm run test-watch
```
This will run all tests and watch source and test files for changes. When a change is made, the tests will run again.
#### Coding Style
For consistency and readability, we require that new submissions follow the [Prettier Style](https://prettier.io/).
Before committing, please format your code automatically using Prettier by running the following command:
```bash
npm run style
```
A few (but not all) of the things to keep in mind:
- Use camelCase with the leading character as lowercase for identifier names (variables and functions).
- Names start with a letter.
- Follow code indentation: Always use 2 spaces for code-block indentation.
```js
function sumOfArray(arrayOfNumbers) {
let sum = 0
for (let i = 0; i < arrayOfNumbers.length; i++) {
sum += arrayOfNumbers[i]
}
return sum
}
```
- Avoid using global variables and avoid `==`.
- Please use `let` over `var`.
- Please refrain from using `console.log` or any other console methods.
- **Absolutely** don't use `alert`.
- We strongly recommend the use of ECMAScript 6.
- Avoid importing external libraries for basic algorithms. Only use those libraries for complicated algorithms.
- Most importantly:
- **Be consistent in the use of these guidelines when submitting.**
- Happy coding!
Writer [@itsvinayak](https://github.com/itsvinayak) and contributors, May 2020.
================================================
FILE: Cache/LFUCache.js
================================================
class CacheNode {
constructor(key, value, frequency) {
this.key = key
this.value = value
this.frequency = frequency
return Object.seal(this)
}
}
// This frequency map class will act like javascript Map DS with more two custom method refresh & insert
class FrequencyMap extends Map {
static get [Symbol.species]() {
return Map
} // for using Symbol.species we can access Map constructor @see -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/@@species
get [Symbol.toStringTag]() {
return ''
}
/**
* @method refresh
* @description - It's revive a CacheNode, increment of this nodes frequency and refresh the frequencyMap via new incremented nodes frequency
* @param {CacheNode} node
*/
refresh(node) {
const { frequency } = node
const freqSet = this.get(frequency)
freqSet.delete(node)
node.frequency++
this.insert(node)
}
/**
* @method insert
* @description - Add new CacheNode into HashSet by the frequency
* @param {CacheNode} node
*/
insert(node) {
const { frequency } = node
if (!this.has(frequency)) {
this.set(frequency, new Set())
}
this.get(frequency).add(node)
}
}
class LFUCache {
#capacity
#frequencyMap
/**
* @param {number} capacity - The range of LFUCache
* @returns {LFUCache} - sealed
*/
constructor(capacity) {
this.#capacity = capacity
this.#frequencyMap = new FrequencyMap()
this.misses = 0
this.hits = 0
this.cache = new Map()
return Object.seal(this)
}
/**
* Get the capacity of the LFUCache
* @returns {number}
*/
get capacity() {
return this.#capacity
}
/**
* Get the current size of LFUCache
* @returns {number}
*/
get size() {
return this.cache.size
}
/**
* Set the capacity of the LFUCache if you decrease the capacity its removed CacheNodes following the LFU - least frequency used
*/
set capacity(newCapacity) {
if (this.#capacity > newCapacity) {
let diff = this.#capacity - newCapacity // get the decrement number of capacity
while (diff--) {
this.#removeCacheNode()
}
this.cache.size === 0 && this.#frequencyMap.clear()
}
this.#capacity = newCapacity
}
get info() {
return Object.freeze({
misses: this.misses,
hits: this.hits,
capacity: this.capacity,
currentSize: this.size,
leastFrequency: this.leastFrequency
})
}
get leastFrequency() {
const freqCacheIterator = this.#frequencyMap.keys()
let leastFrequency = freqCacheIterator.next().value || null
// select the non-empty frequency Set
while (this.#frequencyMap.get(leastFrequency)?.size === 0) {
leastFrequency = freqCacheIterator.next().value
}
return leastFrequency
}
#removeCacheNode() {
const leastFreqSet = this.#frequencyMap.get(this.leastFrequency)
// Select the least recently used node from the least Frequency set
const LFUNode = leastFreqSet.values().next().value
leastFreqSet.delete(LFUNode)
this.cache.delete(LFUNode.key)
}
/**
* if key exist then return true otherwise false
* @param {any} key
* @returns {boolean}
*/
has(key) {
key = String(key) // converted to string
return this.cache.has(key)
}
/**
* @method get
* @description - This method return the value of key & refresh the frequencyMap by the oldNode
* @param {string} key
* @returns {any}
*/
get(key) {
key = String(key) // converted to string
if (this.cache.has(key)) {
const oldNode = this.cache.get(key)
this.#frequencyMap.refresh(oldNode)
this.hits++
return oldNode.value
}
this.misses++
return null
}
/**
* @method set
* @description - This method stored the value by key & add frequency if it doesn't exist
* @param {string} key
* @param {any} value
* @param {number} frequency
* @returns {LFUCache}
*/
set(key, value, frequency = 1) {
key = String(key) // converted to string
if (this.#capacity === 0) {
throw new RangeError('LFUCache ERROR: The Capacity is 0')
}
if (this.cache.has(key)) {
const node = this.cache.get(key)
node.value = value
this.#frequencyMap.refresh(node)
return this
}
// if the cache size is full, then it's delete the Least Frequency Used node
if (this.#capacity === this.cache.size) {
this.#removeCacheNode()
}
const newNode = new CacheNode(key, value, frequency)
this.cache.set(key, newNode)
this.#frequencyMap.insert(newNode)
return this
}
/**
* @method parse
* @description - This method receive a valid LFUCache JSON & run JSON.prase() method and merge with existing LFUCache
* @param {JSON} json
* @returns {LFUCache} - merged
*/
parse(json) {
const { misses, hits, cache } = JSON.parse(json)
this.misses += misses ?? 0
this.hits += hits ?? 0
for (const key in cache) {
const { value, frequency } = cache[key]
this.set(key, value, frequency)
}
return this
}
/**
* @method clear
* @description - This method cleared the whole LFUCache
* @returns {LFUCache}
*/
clear() {
this.cache.clear()
this.#frequencyMap.clear()
return this
}
/**
* @method toString
* @description - This method generate a JSON format of LFUCache & return it.
* @param {number} indent
* @returns {string} - JSON
*/
toString(indent) {
const replacer = (_, value) => {
if (value instanceof Set) {
return [...value]
}
if (value instanceof Map) {
return Object.fromEntries(value)
}
return value
}
return JSON.stringify(this, replacer, indent)
}
}
export default LFUCache
================================================
FILE: Cache/LRUCache.js
================================================
class LRUCache {
// LRU Cache to store a given capacity of data
#capacity
/**
* @param {number} capacity - the capacity of LRUCache
* @returns {LRUCache} - sealed
*/
constructor(capacity) {
if (!Number.isInteger(capacity) || capacity < 0) {
throw new TypeError('Invalid capacity')
}
this.#capacity = ~~capacity
this.misses = 0
this.hits = 0
this.cache = new Map()
return Object.seal(this)
}
get info() {
return Object.freeze({
misses: this.misses,
hits: this.hits,
capacity: this.capacity,
size: this.size
})
}
get size() {
return this.cache.size
}
get capacity() {
return this.#capacity
}
set capacity(newCapacity) {
if (newCapacity < 0) {
throw new RangeError('Capacity should be greater than 0')
}
if (newCapacity < this.capacity) {
let diff = this.capacity - newCapacity
while (diff--) {
this.#removeLeastRecentlyUsed()
}
}
this.#capacity = newCapacity
}
/**
* delete oldest key existing in map by the help of iterator
*/
#removeLeastRecentlyUsed() {
this.cache.delete(this.cache.keys().next().value)
}
/**
* @param {string} key
* @returns {*}
*/
has(key) {
key = String(key)
return this.cache.has(key)
}
/**
* @param {string} key
* @param {*} value
*/
set(key, value) {
key = String(key)
// Sets the value for the input key and if the key exists it updates the existing key
if (this.size === this.capacity) {
this.#removeLeastRecentlyUsed()
}
this.cache.set(key, value)
}
/**
* @param {string} key
* @returns {*}
*/
get(key) {
key = String(key)
// Returns the value for the input key. Returns null if key is not present in cache
if (this.cache.has(key)) {
const value = this.cache.get(key)
// refresh the cache to update the order of key
this.cache.delete(key)
this.cache.set(key, value)
this.hits++
return value
}
this.misses++
return null
}
/**
* @param {JSON} json
* @returns {LRUCache}
*/
parse(json) {
const { misses, hits, cache } = JSON.parse(json)
this.misses += misses ?? 0
this.hits += hits ?? 0
for (const key in cache) {
this.set(key, cache[key])
}
return this
}
/**
* @param {number} indent
* @returns {JSON} - string
*/
toString(indent) {
const replacer = (_, value) => {
if (value instanceof Set) {
return [...value]
}
if (value instanceof Map) {
return Object.fromEntries(value)
}
return value
}
return JSON.stringify(this, replacer, indent)
}
}
export default LRUCache
================================================
FILE: Cache/Memoize.js
================================================
/**
* @function memoize
* @description ->
* From [Wikipedia](https://en.wikipedia.org/wiki/Memoization),
* memoization is an optimization technique
* used primarily to speed up computer programs,
* by storing the results of expensive function calls
* and returning the cached result when the same inputs occur again
* This function is a first class objects,
* which lets us use it as [Higher-Order Function](https://eloquentjavascript.net/05_higher_order.html)
* and return another function
* @param {Function} func Original function
* @param {Map} cache - it's receive any cache DS which have get, set & has method
* @returns {Function} Memoized function
*/
const memoize = (func, cache = new Map()) => {
const jsonReplacer = (_, value) => {
if (value instanceof Set) {
// if the value is Set it's converted to Array cause JSON.stringify can't convert Set
return [...value]
}
if (value instanceof Map) {
// if the value is Map it's converted to Object cause JSON.stringify can't convert Map
return Object.fromEntries(value)
}
return value
}
return (...args) => {
/**
* Arguments converted to JSON string for use as a key of Map - it's easy to detect collections like -> Object and Array
* If the args input is -> [new Set([1, 2, 3, 4]), {name: 'myName', age: 23}]
* Then the argsKey generate to -> '[[1,2,3,4],{"name":"myName","age":23}]' which is JSON mean string
* Now it's ready to be a perfect key for Map
*/
const argsKey = JSON.stringify(args, jsonReplacer)
/**
* Checks if the argument is already present in the cache,
* then return the associated value / result
*/
if (cache.has(argsKey)) {
return cache.get(argsKey)
}
/**
* If the argument is not yet present in the cache,
* execute original function and save its value / result in cache,
* finally return it
*/
const result = func(...args) // spread all args
cache.set(argsKey, result)
return result
}
}
export { memoize }
================================================
FILE: Cache/test/LFUCache.test.js
================================================
import LFUCache from '../LFUCache'
import { fibonacciCache } from './cacheTest'
describe('Testing LFUCache class', () => {
it('Example 1 (Small Cache, size = 2)', () => {
const cache = new LFUCache(1) // initially capacity 1
cache.capacity = 2 // increase the capacity
expect(cache.capacity).toBe(2)
cache.set(1, 1) // frequency = 1
cache.set(2, 2) // frequency = 1
expect(cache.get(1)).toBe(1) // frequency = 2
expect(cache.get(2)).toBe(2) // frequency = 2
// Additional entries triggers cache rotate
cache.set(3, 3) // frequency = 1 & key 1 removed from the cached, cause now it's tie and followed the LRU system
expect(cache.get(1)).toBe(null) // misses = 1
expect(cache.get(2)).toBe(2) // frequency = 3
expect(cache.get(3)).toBe(3) // frequency = 2
cache.set(4, 4) // frequency = 1 & key 3 removed cause the frequency of 3 is 2 which is least frequency
expect(cache.get(1)).toBe(null) // misses = 2
expect(cache.get(2)).toBe(2) // frequency = 4
expect(cache.get(3)).toBe(null) // misses = 3
expect(cache.get(4)).toBe(4) // frequency = 2 which is least
expect(cache.info).toEqual({
misses: 3,
hits: 6,
capacity: 2,
currentSize: 2,
leastFrequency: 2
})
const json =
'{"misses":3,"hits":6,"cache":{"2":{"key":"2","value":2,"frequency":4},"4":{"key":"4","value":4,"frequency":2}}}'
expect(cache.toString()).toBe(json)
const cacheInstance = cache.parse(json) // again merge the json
expect(cacheInstance).toBe(cache) // return the same cache
cache.capacity = 1 // decrease the capacity
expect(cache.info).toEqual({
// after merging the info
misses: 6,
hits: 12,
capacity: 1,
currentSize: 1,
leastFrequency: 5
})
const clearedCache = cache.clear() // clear the cache
expect(clearedCache.size).toBe(0)
})
it('Example 2 (Computing Fibonacci Series, size = 100)', () => {
const cache = new LFUCache(100)
for (let i = 1; i <= 100; i++) {
fibonacciCache(i, cache)
}
expect(cache.info).toEqual({
misses: 103,
hits: 193,
capacity: 100,
currentSize: 98,
leastFrequency: 1
})
})
})
================================================
FILE: Cache/test/LRUCache.test.js
================================================
import LRUCache from '../LRUCache'
import { fibonacciCache } from './cacheTest'
describe('Testing LRUCache', () => {
it('Testing with invalid capacity', () => {
expect(() => new LRUCache()).toThrow()
expect(() => new LRUCache('Invalid')).toThrow()
expect(() => new LRUCache(-1)).toThrow()
expect(() => new LRUCache(Infinity)).toThrow()
})
it('Example 1 (Small Cache, size = 2)', () => {
const cache = new LRUCache(1) // initially capacity
cache.capacity++ // now the capacity is increasing by one
cache.set(1, 1)
cache.set(2, 2)
expect(cache.get(1)).toBe(1)
expect(cache.get(2)).toBe(2)
// Additional entries triggers cache rotate
cache.set(3, 3)
// Then we should have a cache miss for the first entry added
expect(cache.get(1)).toBe(null)
expect(cache.get(2)).toBe(2)
expect(cache.get(3)).toBe(3)
cache.set(4, 4)
expect(cache.get(1)).toBe(null) // cache miss
expect(cache.get(2)).toBe(null) // cache miss
expect(cache.get(3)).toBe(3)
expect(cache.get(4)).toBe(4)
expect(cache.info).toEqual({
misses: 3,
hits: 6,
capacity: 2,
size: 2
})
const json = '{"misses":3,"hits":6,"cache":{"3":3,"4":4}}'
expect(cache.toString()).toBe(json)
// merge with json
cache.parse(json)
cache.capacity-- // now the capacity decreasing by one
expect(cache.info).toEqual({
misses: 6,
hits: 12,
capacity: 1,
size: 1
})
})
it('Example 2 (Computing Fibonacci Series, size = 100)', () => {
const cache = new LRUCache(100)
for (let i = 1; i <= 100; i++) {
fibonacciCache(i, cache)
}
expect(cache.info).toEqual({
misses: 103,
hits: 193,
capacity: 100,
size: 98
})
})
})
================================================
FILE: Cache/test/Memoize.test.js
================================================
import { memoize } from '../Memoize'
import { union } from './cacheTest'
import { fibonacci } from '../../Dynamic-Programming/FibonacciNumber'
import { factorial } from '../../Recursive/Factorial'
import LFUCache from '../LFUCache'
const multipleFactorials = (arr) => arr.map(factorial)
describe('Testing Memoize', () => {
it('expects the fibonacci function to use the cache on the second call', () => {
const memoFibonacci = memoize(fibonacci)
expect(memoFibonacci(5)).toEqual(fibonacci(5))
expect(memoFibonacci(5)).toEqual(5)
expect(memoFibonacci(10)).toEqual(fibonacci(10))
expect(memoFibonacci(10)).toEqual(55)
})
it('expects the factorial function to use the cache on the second call', () => {
const memoFactorial = memoize(factorial)
expect(memoFactorial(5)).toEqual(factorial(5))
expect(memoFactorial(5)).toEqual(120)
expect(memoFactorial(10)).toEqual(factorial(10))
expect(memoFactorial(10)).toEqual(3628800)
})
it('expects the multipleFactorials function to use the cache on the second call', () => {
const memoMultipleFactorials = memoize(multipleFactorials)
const input = [2, 3, 4, 5]
expect(memoMultipleFactorials(input)).toEqual([2, 6, 24, 120])
expect(memoMultipleFactorials(input)).toEqual(multipleFactorials(input))
})
it('expects the multipleFactorials function to use the cache on the second call', () => {
const memoMultipleFactorials = memoize(multipleFactorials)
const input = [2, 3, 4, 5]
expect(memoMultipleFactorials(input)).toEqual([2, 6, 24, 120])
expect(memoMultipleFactorials(input)).toEqual(multipleFactorials(input))
})
it('expects the union function to use the cache on the second call', () => {
const memoUnion = memoize(union)
const inputs = [new Set([1, 2, 3]), new Set([4, 3, 2]), new Set([5, 3, 6])]
expect(memoUnion(...inputs)).toEqual(new Set([1, 2, 3, 4, 5, 6]))
expect(memoUnion(...inputs)).toEqual(union(...inputs))
})
it('Testing with explicit cache -> LFUCache', () => {
const LFU = new LFUCache(2)
const memoizeFibonacci = memoize(fibonacci, LFU) // added LFU cache explicitly
const fibOfFiveHundred = memoizeFibonacci(500)
const fibOfOneHundred = memoizeFibonacci(100)
expect(memoizeFibonacci(500)).toBe(fibOfFiveHundred)
expect(memoizeFibonacci(100)).toBe(fibOfOneHundred)
expect(LFU.leastFrequency).toBe(2)
})
})
================================================
FILE: Cache/test/cacheTest.js
================================================
/**
* @function fibonacciCache
* @description - this is a cached variant of fib number
* @param {number} n - Real number (n > -1)
* @param {Object} cache
* @returns {number}
*/
export const fibonacciCache = (n, cache = null) => {
if (cache) {
const value = cache.get(n)
if (value !== null) {
return value
}
}
if (n === 1 || n === 2) {
return 1
}
const result = fibonacciCache(n - 1, cache) + fibonacciCache(n - 2, cache)
cache && cache.set(n, result)
return result
}
/**
* @title implementation of union function
* @param {Set} sets
* @return {new Set}
*/
export const union = (...sets) => {
return new Set(sets.reduce((flatArray, set) => [...flatArray, ...set], []))
}
================================================
FILE: Cellular-Automata/ConwaysGameOfLife.js
================================================
/*
Conway's Game of Life
The Game of Life is a cellular automaton devised by the British mathematician John Horton Conway in 1970. The universe of the Game of Life is an infinite, two-dimensional orthogonal grid of square cells, each of which is in one of two possible states, live or dead, (or populated and unpopulated, respectively). Every cell interacts with its eight neighbours, which are the cells that are horizontally, vertically, or diagonally adjacent. At each step in time, the following transitions occur:
1. Any live cell with two or three live neighbours survives.
2. Any dead cell with three live neighbours becomes a live cell.
3. All other live cells die in the next generation. Similarly, all other dead cells stay dead.
(description adapted from https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life )
(example adapted from https://github.com/TheAlgorithms/Python/blob/master/cellular_automata/conways_game_of_life.py )
*/
/**
* Generates the next generation for a given state of Conway's Game of Life.
*/
export function newGeneration(cells) {
const nextGeneration = []
for (let i = 0; i < cells.length; i++) {
const nextGenerationRow = []
for (let j = 0; j < cells[i].length; j++) {
// Get the number of living neighbours
let neighbourCount = 0
if (i > 0 && j > 0) neighbourCount += cells[i - 1][j - 1]
if (i > 0) neighbourCount += cells[i - 1][j]
if (i > 0 && j < cells[i].length - 1)
neighbourCount += cells[i - 1][j + 1]
if (j > 0) neighbourCount += cells[i][j - 1]
if (j < cells[i].length - 1) neighbourCount += cells[i][j + 1]
if (i < cells.length - 1 && j > 0) neighbourCount += cells[i + 1][j - 1]
if (i < cells.length - 1) neighbourCount += cells[i + 1][j]
if (i < cells.length - 1 && j < cells[i].length - 1)
neighbourCount += cells[i + 1][j + 1]
// Decide whether the cell is alive or dead
const alive = cells[i][j] === 1
const cellIsAlive =
(alive && neighbourCount >= 2 && neighbourCount <= 3) ||
(!alive && neighbourCount === 3)
nextGenerationRow.push(cellIsAlive ? 1 : 0)
}
nextGeneration.push(nextGenerationRow)
}
return nextGeneration
}
================================================
FILE: Cellular-Automata/Elementary.js
================================================
/**
* Author: Jacoby Johnson (cobyj33)
*
* Generates generations of Elementary 1D cellular automata
*
* Wikipedia: https://en.wikipedia.org/wiki/Elementary_cellular_automaton
* See all 255 possible rules and find another explanation here: https://mathworld.wolfram.com/ElementaryCellularAutomaton.html
*
* My personal take on the explanation of Elementary Cellular Automata:
*
* Elementary 1D cellular automata defines the growth and decay of populations of "cells" according to a specific rule, where the population is a line (array) and each cell is in either an "alive" (1) or a "dead" (0) state.
*
* The next generation of for a cell in the simulation ONLY depends on the state of its neighborhood (the state of the cell itself as well as the states of the cells to the immediate right and the immediate left)
* Therefore, since each neighborhood consists of 3 cells each with 2 states there are 2^3 possibilities that determine a cell's next state, where each possible neighborhood could be represented in binary as
*
* 111
* 110
* 101
* 100
* 011
* 010
* 001
* 000
*
* Where "1" represents the cell being alive and "0" represents the cell being dead. The leftmost bit represents the left neighbor of the currently analyzed cell, the middle bit represents the currently analyzed cell, and the rightmost bit represents the right neighbor of the currently analyzed cell.
*
* Rules are represented between 0 and 255 (0 and 255 inclusive), or more conceptually is seen as an 8 bit binary number. Each bit represents whether a cell should survive according to one of the 8 states of a cell's neighborhood. In this way, the number can act like an array of data of length 8.
* The most significant bit (ex: ->10100100 ) represents the output for the "all on" state while the least significant bit (ex: 10100100<- ) represents the output for the "all off" state
* In other words, all of the 8 possible neighborhood configurations map toward the 8 bits in a rule's output values
*
* Therefore, to find whether the a cell is born, survives, or dies, one could convert the state of a cell and it's neighbors into a binary number, then use the numerical value of that binary number as an index to find the corresponding rule's output, which is what has been implemented below
* This analysis of a cell's neighborhood is performed on each cell in a generation until a new generation is created and returned.
*
* Rules are usually demonstrated visually by how a single cell grows independently according to that rule
*
* Example: First generations of Rule 94 First Generations of Rule 126
* 000000000000000000000000001000000000000000000000000 000000000000000000000000001000000000000000000000000
* 000000000000000000000000011100000000000000000000000 000000000000000000000000011100000000000000000000000
* 000000000000000000000000110110000000000000000000000 000000000000000000000000110110000000000000000000000
* 000000000000000000000001110111000000000000000000000 000000000000000000000001111111000000000000000000000
* 000000000000000000000011010101100000000000000000000 000000000000000000000011000001100000000000000000000
* 000000000000000000000111010101110000000000000000000 000000000000000000000111100011110000000000000000000
* 000000000000000000001101010101011000000000000000000 000000000000000000001100110110011000000000000000000
* 000000000000000000011101010101011100000000000000000 000000000000000000011111111111111100000000000000000
* 000000000000000000110101010101010110000000000000000 000000000000000000110000000000000110000000000000000
* 000000000000000001110101010101010111000000000000000 000000000000000001111000000000001111000000000000000
* 000000000000000011010101010101010101100000000000000 000000000000000011001100000000011001100000000000000
* 000000000000000111010101010101010101110000000000000 000000000000000111111110000000111111110000000000000
* 000000000000001101010101010101010101011000000000000 000000000000001100000011000001100000011000000000000
* 000000000000011101010101010101010101011100000000000 000000000000011110000111100011110000111100000000000
* 000000000000110101010101010101010101010110000000000 000000000000110011001100110110011001100110000000000
* 000000000001110101010101010101010101010111000000000 000000000001111111111111111111111111111111000000000
* 000000000011010101010101010101010101010101100000000 000000000011000000000000000000000000000001100000000
* 000000000111010101010101010101010101010101110000000 000000000111100000000000000000000000000011110000000
* 000000001101010101010101010101010101010101011000000 000000001100110000000000000000000000000110011000000
* 000000011101010101010101010101010101010101011100000 000000011111111000000000000000000000001111111100000
*
* DEV NOTE: This implementation assumes that cells on the edge (who only have 1 neighbor) have 1 neighbor and a permanently "dead" neighbor, which is technically correct in a finite space. However, most diagrams of these elementary cellular automata rules assume a infinite line of cells. Therefore, the edges of the array may not evolve perfectly in line with pictured diagrams which assume infinite space.
*/
/**
* Find the next Elementary Cell Automata Generation given the previous generation and the rule [0-255] to follow
* @param {(0 | 1)[]} generation The current generation of the Elementary Cellular Automata simulation
* @param {number} rule The current rule of the Elementary Cellular Automata simulation. Must be an integer between 0 and 255 inclusive
* @returns {(0 | 1)[]} The next generation according to the inputted rule
*/
export function getNextElementaryGeneration(generation, rule) {
const NUM_ELEMENTARY_NEIGHBORHOOD_STATES = 8
const MIN_RULE = 0
const MAX_RULE = 255
if (!Number.isInteger(rule)) {
throw new Error(
`Rule must be an integer between the values 0 and 255 (got ${rule})`
)
}
if (rule < MIN_RULE || rule > MAX_RULE) {
throw new RangeError(
`Rule must be an integer between the values 0 and 255 (got ${rule})`
)
}
const binaryRule = rule
.toString(2)
.padStart(NUM_ELEMENTARY_NEIGHBORHOOD_STATES, '0')
const ruleData = binaryRule.split('').map((bit) => Number.parseInt(bit)) // note that ruleData[0] represents "all alive" while ruleData[7] represents "all dead"
const output = new Array(generation.length)
const LEFT_DEAD = 4 // 100 in binary
const MIDDLE_DEAD = 2 // 010 in binary
const RIGHT_DEAD = 1 // 001 in binary
for (let i = 0; i < generation.length; i++) {
let neighborhoodValue = LEFT_DEAD | MIDDLE_DEAD | RIGHT_DEAD
if (i - 1 > 0 && generation[i - 1] === 1) {
neighborhoodValue ^= LEFT_DEAD
}
if (generation[i] === 1) {
neighborhoodValue ^= MIDDLE_DEAD
}
if (i + 1 < generation.length && generation[i + 1] === 1) {
neighborhoodValue ^= RIGHT_DEAD
}
output[i] = ruleData[neighborhoodValue]
}
return output
}
================================================
FILE: Cellular-Automata/test/ConwaysGameOfLife.test.js
================================================
import { newGeneration } from '../ConwaysGameOfLife'
describe('newGeneration', () => {
it('should produce the next generation according to the rules', () => {
expect(
newGeneration([
[0, 1, 0],
[0, 1, 0],
[0, 1, 0]
])
).toEqual([
[0, 0, 0],
[1, 1, 1],
[0, 0, 0]
])
})
})
================================================
FILE: Cellular-Automata/test/Elementary.test.js
================================================
import { getNextElementaryGeneration } from '../Elementary'
describe('Elementary Cellular Automata', () => {
describe('Rule Errors', () => {
it('Correct', () => {
expect(() =>
getNextElementaryGeneration([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 128)
).not.toThrow()
})
it('Less than 0', () => {
expect(() =>
getNextElementaryGeneration([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], -1)
).toThrow()
})
it('Greater than 255', () => {
expect(() =>
getNextElementaryGeneration([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 256)
).toThrow()
})
it('Decimal', () => {
expect(() =>
getNextElementaryGeneration([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 100.4)
).toThrow()
})
})
describe('Rule 54 Iterations', () => {
it('Generation 1', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 54)
).toEqual([0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0])
})
it('Generation 2', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 54)
).toEqual([0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0])
})
it('Generation 3', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0], 54)
).toEqual([0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0])
})
it('Generation 4', () => {
expect(
getNextElementaryGeneration([0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0], 54)
).toEqual([0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0])
})
})
describe('Rule 222 Iterations', () => {
it('Generation 1', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 222)
).toEqual([0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0])
})
it('Generation 2', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 222)
).toEqual([0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0])
})
it('Generation 3', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], 222)
).toEqual([0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0])
})
it('Generation 4', () => {
expect(
getNextElementaryGeneration([0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0], 222)
).toEqual([0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0])
})
})
describe('Rule 60 Iterations', () => {
it('Generation 1', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 60)
).toEqual([0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0])
})
it('Generation 2', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], 60)
).toEqual([0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0])
})
it('Generation 3', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0], 60)
).toEqual([0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0])
})
it('Generation 4', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0], 60)
).toEqual([0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0])
})
})
describe('Rule 90 Iterations', () => {
it('Generation 1', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 90)
).toEqual([0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0])
})
it('Generation 2', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], 90)
).toEqual([0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0])
})
it('Generation 3', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0], 90)
).toEqual([0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0])
})
it('Generation 4', () => {
expect(
getNextElementaryGeneration([0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0], 90)
).toEqual([0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0])
})
})
describe('Rule 30 Iterations', () => {
it('Generation 1', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 30)
).toEqual([0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0])
})
it('Generation 2', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 30)
).toEqual([0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0])
})
it('Generation 3', () => {
expect(
getNextElementaryGeneration([0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0], 30)
).toEqual([0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0])
})
})
})
================================================
FILE: Ciphers/AffineCipher.js
================================================
/**
* @description - The affine cipher is a type of monoalphabetic substitution cipher, where each letter in an alphabet is mapped to its numeric equivalent, encrypted using a simple mathematical function, and converted back to a letter
* @see - [wiki](https://en.wikipedia.org/wiki/Affine_cipher)
*/
import { CoPrimeCheck } from '../Maths/CoPrimeCheck'
// Default key for Affine Cipher
const key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
/**
* Fix result for negative value in modulas equation
* @param {Number} n - Constant number
* @param {Number} m - Modulos value
* @return {Number} Return n mod m
*/
function mod(n, m) {
return ((n % m) + m) % m
}
/**
* Modular multiplicative inverse
* @param {Number} a - A coefficient
* @param {Number} m - Modulos value
* @return {Number} Return modular multiplicative inverse of coefficient a and modulos m
*/
function inverseMod(a, m) {
for (let x = 1; x < m; x++) {
if (mod(a * x, m) === 1) return x
}
}
/**
* Argument validation
* @param {String} str - String to be checked
* @param {Number} a - A coefficient to be checked
* @param {Number} b - B coefficient to be checked
* @return {Boolean} Result of the checking
*/
function isCorrectFormat(str, a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw new TypeError('Coefficient a, b should be number')
}
if (typeof str !== 'string') {
throw new TypeError('Argument str should be String')
}
if (!CoPrimeCheck(a, 26)) {
throw new Error(a + ' is not coprime of 26')
}
return true
}
/**
* Find character index based on ASCII order
* @param {String} char - Character index to be found
* @return {Boolean} Character index
*/
function findCharIndex(char) {
return char.toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0)
}
/**
* Encrypt a Affine Cipher
* @param {String} str - String to be encrypted
* @param {Number} a - A coefficient
* @param {Number} b - B coefficient
* @return {String} result - Encrypted string
*/
function encrypt(str, a, b) {
let result = ''
if (isCorrectFormat(str, a, b)) {
for (let x = 0; x < str.length; x++) {
const charIndex = findCharIndex(str[x])
if (charIndex < 0) result += '-1' + ' '
else result += key.charAt(mod(a * charIndex + b, 26)) + ' '
}
}
return result.trim()
}
/**
* Decrypt a Affine Cipher
* @param {String} str - String to be decrypted
* @param {Number} a - A coefficient
* @param {Number} b - B coefficient
* @return {String} result - Decrypted string
*/
function decrypt(str, a, b) {
let result = ''
if (isCorrectFormat(str, a, b)) {
str = str.split(' ')
for (let x = 0; x < str.length; x++) {
if (str[x] === '-1') result += ' '
else {
const charIndex = findCharIndex(str[x])
result += key[mod(inverseMod(a, 26) * (charIndex - b), 26)]
}
}
return result
}
}
export { encrypt, decrypt }
================================================
FILE: Ciphers/Atbash.js
================================================
/**
* @function Atbash - Decrypt a Atbash cipher
* @description - The Atbash cipher is a particular type of monoalphabetic cipher formed by taking the alphabet and mapping it to its reverse, so that the first letter becomes the last letter, the second letter becomes the second to last letter, and so on.
* @param {string} str - string to be decrypted/encrypt
* @return {string} decrypted/encrypted string
* @see - [wiki](https://en.wikipedia.org/wiki/Atbash)
*/
const Atbash = (str) => {
if (typeof str !== 'string') {
throw new TypeError('Argument should be string')
}
return str.replace(/[a-z]/gi, (char) => {
const charCode = char.charCodeAt()
if (/[A-Z]/.test(char)) {
return String.fromCharCode(90 + 65 - charCode)
}
return String.fromCharCode(122 + 97 - charCode)
})
}
export default Atbash
================================================
FILE: Ciphers/CaesarCipher.js
================================================
/**
* @function caesarsCipher
* @description - In cryptography, a Caesar cipher, also known as Caesar's cipher, the shift cipher, Caesar's code or Caesar shift, is one of the simplest and most widely known encryption techniques. It is a type of substitution cipher in which each letter in the plaintext is replaced by a letter some fixed number of positions down the alphabet. For example, with a left shift of 3, D would be replaced by A, E would become B, and so on. The method is named after Julius Caesar, who used it in his private correspondence.
* @see - [wiki](https://en.wikipedia.org/wiki/Caesar_cipher)
* @param {string} str - string to be encrypted
* @param {number} rotation - the number of rotation, expect real number ( > 0)
* @return {string} - decrypted string
*/
const caesarCipher = (str, rotation) => {
if (typeof str !== 'string' || !Number.isInteger(rotation) || rotation < 0) {
throw new TypeError('Arguments are invalid')
}
const alphabets = new Array(26)
.fill()
.map((_, index) => String.fromCharCode(97 + index)) // generate all lower alphabets array a-z
const cipherMap = alphabets.reduce(
(map, char, index) => map.set(char, alphabets[(rotation + index) % 26]),
new Map()
)
return str.replace(/[a-z]/gi, (char) => {
if (/[A-Z]/.test(char)) {
return cipherMap.get(char.toLowerCase()).toUpperCase()
}
return cipherMap.get(char)
})
}
export default caesarCipher
================================================
FILE: Ciphers/KeyFinder.js
================================================
/**
* Find and retrieve the encryption key automatically.
* @param {string} str - The input encrypted string.
* @returns {number} - The encryption key found, or 0 if not found.
*/
function keyFinder(str) {
// str is used to get the input of encrypted string
const wordBank = [
'I ',
'You ',
'We ',
'They ',
'He ',
'She ',
'It ',
' the ',
'The ',
' of ',
' is ',
'Is ',
' am ',
'Am ',
' are ',
'Are ',
' have ',
'Have ',
' has ',
'Has ',
' may ',
'May ',
' be ',
'Be '
]
const inStr = str.toString() // convert the input to String
let outStr = '' // store the output value
let outStrElement = '' // temporary store the word inside the outStr, it is used for comparison
for (let k = 0; k < 26; k++) {
// try the number of key shifted, the sum of character from a-z or A-Z is 26
outStr = caesarCipherEncodeAndDecodeEngine(inStr, k) // use the encryption engine to decrypt the input string
// loop through the whole input string
for (let s = 0; s < outStr.length; s++) {
for (let i = 0; i < wordBank.length; i++) {
// initialize the outStrElement which is a temp output string for comparison,
// use a loop to find the next digit of wordBank element and compare with outStr's digit
for (let w = 0; w < wordBank[i].length; w++) {
outStrElement += outStr[s + w]
}
// this part need to be optimize with the calculation of the number of occurrence of word's probabilities
// linked list will be used in the next stage of development to calculate the number of occurrence of the key
if (wordBank[i] === outStrElement) {
return k // return the key number if founded
}
outStrElement = '' // reset the temp word
} // end for (let i=0; i < wordBank.length; i++)
}
}
return 0 // return 0 if found nothing
}
/**
* This sub-function is used to assist the keyFinder in finding the key.
* @param {string} inStr - The input string.
* @param {number} numShifted - The number of characters to shift in the Caesar cipher.
* @returns {string} - The decrypted string.
*/
function caesarCipherEncodeAndDecodeEngine(inStr, numShifted) {
const shiftNum = numShifted
let charCode = 0
let shiftedCharCode = 0
let result = 0
return inStr
.split('')
.map((char) => {
charCode = char.charCodeAt()
shiftedCharCode = charCode + shiftNum
result = charCode
if (charCode >= 48 && charCode <= 57) {
if (shiftedCharCode < 48) {
let diff = Math.abs(48 - 1 - shiftedCharCode) % 10
while (diff >= 10) {
diff = diff % 10
}
document.getElementById('diffID').innerHTML = diff
shiftedCharCode = 57 - diff
result = shiftedCharCode
} else if (shiftedCharCode >= 48 && shiftedCharCode <= 57) {
result = shiftedCharCode
} else if (shiftedCharCode > 57) {
let diff = Math.abs(57 + 1 - shiftedCharCode) % 10
while (diff >= 10) {
diff = diff % 10
}
document.getElementById('diffID').innerHTML = diff
shiftedCharCode = 48 + diff
result = shiftedCharCode
}
} else if (charCode >= 65 && charCode <= 90) {
if (shiftedCharCode <= 64) {
let diff = Math.abs(65 - 1 - shiftedCharCode) % 26
while (diff % 26 >= 26) {
diff = diff % 26
}
shiftedCharCode = 90 - diff
result = shiftedCharCode
} else if (shiftedCharCode >= 65 && shiftedCharCode <= 90) {
result = shiftedCharCode
} else if (shiftedCharCode > 90) {
let diff = Math.abs(shiftedCharCode - 1 - 90) % 26
while (diff % 26 >= 26) {
diff = diff % 26
}
shiftedCharCode = 65 + diff
result = shiftedCharCode
}
} else if (charCode >= 97 && charCode <= 122) {
if (shiftedCharCode <= 96) {
let diff = Math.abs(97 - 1 - shiftedCharCode) % 26
while (diff % 26 >= 26) {
diff = diff % 26
}
shiftedCharCode = 122 - diff
result = shiftedCharCode
} else if (shiftedCharCode >= 97 && shiftedCharCode <= 122) {
result = shiftedCharCode
} else if (shiftedCharCode > 122) {
let diff = Math.abs(shiftedCharCode - 1 - 122) % 26
while (diff % 26 >= 26) {
diff = diff % 26
}
shiftedCharCode = 97 + diff
result = shiftedCharCode
}
}
return String.fromCharCode(parseInt(result))
})
.join('')
}
export { keyFinder }
// > keyFinder('test')
// 0
================================================
FILE: Ciphers/KeywordShiftedAlphabet.js
================================================
/**
* Keyword shifted alphabet is a simple cipher using a translation table created with a help of a keyword.
* Keyword must be a word where each character can occur only once.
* To create the translation table, we write all the alphabet characters to the first.
* Second row start with the keyword, then we continue with the rest of the characters that are missing in alphabetical order.
*
* |A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|
* |K|E|Y|W|O|R|D|A|B|C|F|G|H|I|J|L|M|N|P|Q|S|T|U|V|W|Z|
*
* Encryption is then just a matter of writing the matching (same index) letter from the second row instead of the first row:
* 'Hello world' -> 'Aoggj ujngw'
*
* Decryption is then just the reverse process of writing the matching (same index) letter from the first row instead of the second row
* 'Aogg ujngw' -> 'Hello world'
*
* Non alphabetical characters (space, exclamation mark, ...) are kept as they are
*/
const alphabet = [
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z'
]
function checkKeywordValidity(keyword) {
keyword.split('').forEach((char, index) => {
const rest = keyword.slice(0, index) + keyword.slice(index + 1)
if (rest.indexOf(char) !== -1) {
return false
}
})
return true
}
function getEncryptedAlphabet(keyword) {
const encryptedAlphabet = keyword.split('')
alphabet.forEach((char) => {
if (encryptedAlphabet.indexOf(char) === -1) {
encryptedAlphabet.push(char)
}
})
return encryptedAlphabet
}
function translate(sourceAlphabet, targetAlphabet, message) {
return message.split('').reduce((encryptedMessage, char) => {
const isUpperCase = char === char.toUpperCase()
const encryptedCharIndex = sourceAlphabet.indexOf(char.toLowerCase())
const encryptedChar =
encryptedCharIndex !== -1 ? targetAlphabet[encryptedCharIndex] : char
encryptedMessage += isUpperCase
? encryptedChar.toUpperCase()
: encryptedChar
return encryptedMessage
}, '')
}
function checkInputs(keyword, message) {
if (!keyword || !message) {
throw new Error('Both keyword and message must be specified')
}
if (!checkKeywordValidity(keyword)) {
throw new Error('Invalid keyword!')
}
}
function encrypt(keyword, message) {
checkInputs(keyword, message)
return translate(
alphabet,
getEncryptedAlphabet(keyword.toLowerCase()),
message
)
}
function decrypt(keyword, message) {
checkInputs(keyword, message)
return translate(
getEncryptedAlphabet(keyword.toLowerCase()),
alphabet,
message
)
}
export { encrypt, decrypt }
// encrypt('keyword', 'Hello world!') // Prints 'Aoggj ujngw!'
// decrypt('keyword', 'Aoggj ujngw!') // Prints 'Hello world!
================================================
FILE: Ciphers/MorseCode.js
================================================
/**
* @author mrmagic2020
* @description Enciphers a combination of letters, numbers and symbols into morse code.
* @see https://en.wikipedia.org/wiki/Morse_code
* @param {string} msg The message to be enciphered.
* @param {string} dot Symbol representing the dots.
* @param {string} dash Symbol representing the dash.
* @returns {string} Enciphered morse code.
* @example morse('Hello World!') = '**** * *-** *-** --- *-- --- *-* *-** -** -*-*--'
*/
const morse = (msg, dot = '*', dash = '-') => {
const key = {
A: '*-',
B: '-***',
C: '-*-*',
D: '-**',
E: '*',
F: '**-*',
G: '--*',
H: '****',
I: '**',
J: '*---',
K: '-*-',
L: '*-**',
M: '--',
N: '-*',
O: '---',
P: '*--*',
Q: '--*-',
R: '*-*',
S: '***',
T: '-',
U: '**-',
V: '***-',
W: '*--',
X: '-**-',
Y: '-*--',
Z: '--**',
1: '*----',
2: '**---',
3: '***--',
4: '****-',
5: '*****',
6: '-****',
7: '--***',
8: '---**',
9: '----*',
0: '-----',
'.': '*-*-*-',
',': '--**--',
'?': '**--**',
'!': '-*-*--',
"'": '*----*',
'"': '*-**-*',
'(': '-*--*',
')': '-*--*-',
'&': '*-***',
':': '---***',
';': '-*-*-*',
'/': '-**-*',
_: '**--*-',
'=': '-***-',
'+': '*-*-*',
'-': '-****-',
$: '***-**-',
'@': '*--*-*'
}
let newMsg = ''
msg
.toString()
.split('')
.forEach((e) => {
if (/[a-zA-Z]/.test(e)) {
newMsg += key[e.toUpperCase()]
.replaceAll('*', dot)
.replaceAll('-', dash)
} else if (Object.keys(key).includes(e)) {
newMsg += key[e].replaceAll('*', dot).replaceAll('-', dash)
} else {
newMsg += e
}
newMsg += ' '
})
return newMsg.trim()
}
export { morse }
================================================
FILE: Ciphers/ROT13.js
================================================
/**
* @function ROT13
* @description - ROT13 ("rotate by 13 places", sometimes hyphenated ROT-13) is a simple letter substitution cipher that replaces a letter with the 13th letter after it in the alphabet. ROT13 is a special case of the Caesar cipher which was developed in ancient Rome. Because there are 26 letters (2×13) in the basic Latin alphabet, ROT13 is its own inverse; that is, to undo ROT13, the same algorithm is applied, so the same action can be used for encoding and decoding. The algorithm provides virtually no cryptographic security, and is often cited as a canonical example of weak encryption.
* @see - [wiki](https://en.wikipedia.org/wiki/ROT13)
* @param {String} str - string to be decrypted
* @return {String} decrypted string
*/
function ROT13(str) {
if (typeof str !== 'string') {
throw new TypeError('Argument should be string')
}
return str.replace(/[a-z]/gi, (char) => {
const charCode = char.charCodeAt()
if (/[n-z]/i.test(char)) {
return String.fromCharCode(charCode - 13)
}
return String.fromCharCode(charCode + 13)
})
}
export default ROT13
================================================
FILE: Ciphers/VigenereCipher.js
================================================
/**
* Check if the Character is letter or not
* @param {String} str - character to check
* @return {object} An array with the character or null if isn't a letter
*/
function isLetter(str) {
return str.length === 1 && str.match(/[a-zA-Z]/i)
}
/**
* Check if is Uppercase or Lowercase
* @param {String} character - character to check
* @return {Boolean} result of the checking
*/
function isUpperCase(character) {
if (character === character.toUpperCase()) {
return true
}
if (character === character.toLowerCase()) {
return false
}
}
/**
* Encrypt a Vigenere cipher
* @param {String} message - string to be encrypted
* @param {String} key - key for encrypt
* @return {String} result - encrypted string
*/
function encrypt(message, key) {
let result = ''
for (let i = 0, j = 0; i < message.length; i++) {
const c = message.charAt(i)
if (isLetter(c)) {
if (isUpperCase(c)) {
result += String.fromCharCode(
((c.charCodeAt(0) + key.toUpperCase().charCodeAt(j) - 2 * 65) % 26) +
65
) // A: 65
} else {
result += String.fromCharCode(
((c.charCodeAt(0) + key.toLowerCase().charCodeAt(j) - 2 * 97) % 26) +
97
) // a: 97
}
} else {
result += c
}
j = ++j % key.length
}
return result
}
/**
* Decrypt a Vigenere cipher
* @param {String} message - string to be decrypted
* @param {String} key - key for decrypt
* @return {String} result - decrypted string
*/
function decrypt(message, key) {
let result = ''
for (let i = 0, j = 0; i < message.length; i++) {
const c = message.charAt(i)
if (isLetter(c)) {
if (isUpperCase(c)) {
result += String.fromCharCode(
90 - ((25 - (c.charCodeAt(0) - key.toUpperCase().charCodeAt(j))) % 26)
)
} else {
result += String.fromCharCode(
122 -
((25 - (c.charCodeAt(0) - key.toLowerCase().charCodeAt(j))) % 26)
)
}
} else {
result += c
}
j = ++j % key.length
}
return result
}
export { encrypt, decrypt }
// > encrypt('Hello World!', 'code')
// 'Jsopq Zstzg!'
// > decrypt('Jsopq Zstzg!', 'code')
// 'Hello World!'
================================================
FILE: Ciphers/XORCipher.js
================================================
/**
* @function XORCipher
* @description - Encrypt using an XOR cipher
* The XOR cipher is a type of additive cipher.
* Each character is bitwise XORed with the key.
* We loop through the input string, XORing each
* character with the key.
* @param {string} str - string to be encrypted
* @param {number} key - key for encryption
* @return {string} encrypted string
*/
const XORCipher = (str, key) => {
if (typeof str !== 'string' || !Number.isInteger(key)) {
throw new TypeError('Arguments type are invalid')
}
return str.replace(/./g, (char) =>
String.fromCharCode(char.charCodeAt() ^ key)
)
}
export default XORCipher
================================================
FILE: Ciphers/test/AffineCipher.test.js
================================================
import { encrypt, decrypt } from '../AffineCipher'
describe('Test Affine Cipher', () => {
it('Test - 1, Pass invalid input to encrypt function', () => {
expect(() => encrypt(null, null, null)).toThrow()
expect(() => encrypt('null', null, null)).toThrow()
expect(() => encrypt('null', 1, null)).toThrow()
expect(() => encrypt('null', null, 1)).toThrow()
expect(() => encrypt('null', 2, 1)).toThrow()
expect(() => encrypt('null', 4, 1)).toThrow()
})
it('Test - 2, Pass invalid input to decrypt function', () => {
expect(() => decrypt(null, null, null)).toThrow()
expect(() => decrypt('null', null, null)).toThrow()
expect(() => decrypt('null', 1, null)).toThrow()
expect(() => decrypt('null', null, 1)).toThrow()
expect(() => encrypt('null', 2, 1)).toThrow()
expect(() => encrypt('null', 4, 1)).toThrow()
})
it('Test - 3 Pass string value to encrypt and decrypt function', () => {
expect(decrypt(encrypt('HELLO WORLD', 5, 8), 5, 8)).toBe('HELLO WORLD')
expect(decrypt(encrypt('ABC DEF', 3, 5), 3, 5)).toBe('ABC DEF')
expect(decrypt(encrypt('Brown fox jump over the fence', 7, 3), 7, 3)).toBe(
'BROWN FOX JUMP OVER THE FENCE'
)
})
})
================================================
FILE: Ciphers/test/Atbash.test.js
================================================
import Atbash from '../Atbash'
describe('Testing Atbash function', () => {
it('Test - 1, passing a non-string as an argument', () => {
expect(() => Atbash(0x345)).toThrow()
expect(() => Atbash(123)).toThrow()
expect(() => Atbash(123n)).toThrow()
expect(() => Atbash(false)).toThrow()
expect(() => Atbash({})).toThrow()
expect(() => Atbash([])).toThrow()
})
it('Test - 2, passing a string as an argument', () => {
const clearText = 'The quick brown fox jumps over the lazy dog'
const cryptText = Atbash(clearText)
expect(Atbash(cryptText)).toBe(clearText)
})
})
================================================
FILE: Ciphers/test/CaesarCipher.test.js
================================================
import caesarCipher from '../CaesarCipher'
describe('Testing the caesarsCipher function', () => {
it('Test - 1, Testing for invalid types', () => {
expect(() => caesarCipher(false, 3)).toThrow()
expect(() => caesarCipher('false', -1)).toThrow()
expect(() => caesarCipher('true', null)).toThrow()
})
it('Test - 2, Testing for valid string and rotation', () => {
expect(caesarCipher('middle-Outz', 2)).toBe('okffng-Qwvb')
expect(caesarCipher('abcdefghijklmnopqrstuvwxyz', 3)).toBe(
'defghijklmnopqrstuvwxyzabc'
)
expect(caesarCipher('Always-Look-on-the-Bright-Side-of-Life', 5)).toBe(
'Fqbfdx-Qttp-ts-ymj-Gwnlmy-Xnij-tk-Qnkj'
)
expect(
caesarCipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG', 23)
).toBe('QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD')
})
})
================================================
FILE: Ciphers/test/KeywordShiftedAlphabet.test.js
================================================
import { encrypt, decrypt } from '../KeywordShiftedAlphabet'
test('Hello world! === decrypt(encrypt(Hello world!))', () => {
const word = 'Hello world!'
const result = decrypt('keyword', encrypt('keyword', word))
expect(result).toMatch(word)
})
test('The Algorithms === decrypt(encrypt(The Algorithms))', () => {
const word = 'The Algorithms'
const result = decrypt('keyword', encrypt('keyword', word))
expect(result).toMatch(word)
})
================================================
FILE: Ciphers/test/MorseCode.test.js
================================================
import { morse } from '../MorseCode'
describe('Testing morse function', () => {
it('should return an enciphered string with a given input string', () => {
expect(morse('Hello World!')).toBe(
'**** * *-** *-** --- *-- --- *-* *-** -** -*-*--'
)
expect(morse('1+1=2')).toBe('*---- *-*-* *---- -***- **---')
})
it('should leave symbols that does not have its corresponding morse representation', () => {
expect(morse('© 2023 GitHub, Inc.')).toBe(
'© **--- ----- **--- ***-- --* ** - **** **- -*** --**-- ** -* -*-* *-*-*-'
)
})
it('should be able to accept custom morse code symbols', () => {
expect(morse('Nodejs', '.', '|')).toBe('|. ||| |.. . .||| ...')
})
})
================================================
FILE: Ciphers/test/ROT13.test.js
================================================
import ROT13 from '../ROT13'
describe('Testing ROT13 function', () => {
it('Test - 1, passing a non-string as an argument', () => {
expect(() => ROT13(0x345)).toThrow()
expect(() => ROT13(123)).toThrow()
expect(() => ROT13(123n)).toThrow()
expect(() => ROT13(false)).toThrow()
expect(() => ROT13({})).toThrow()
expect(() => ROT13([])).toThrow()
})
it('Test - 2, passing a string as an argument', () => {
expect(ROT13('Uryyb Jbeyq')).toBe('Hello World')
expect(ROT13('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')).toBe(
'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'
)
expect(ROT13('The quick brown fox jumps over the lazy dog')).toBe(
'Gur dhvpx oebja sbk whzcf bire gur ynml qbt'
)
})
})
================================================
FILE: Ciphers/test/VigenereCipher.test.js
================================================
import { encrypt, decrypt } from '../VigenereCipher'
test('Hello world! === decrypt(encrypt(Hello world!))', () => {
const word = 'Hello world!'
const result = decrypt(encrypt(word, 'code'), 'code')
expect(result).toMatch(word)
})
test('The Algorithms === decrypt(encrypt(The Algorithms))', () => {
const word = 'The Algorithms'
const result = decrypt(encrypt(word, 'code'), 'code')
expect(result).toMatch(word)
})
================================================
FILE: Ciphers/test/XORCipher.test.js
================================================
import XORCipher from '../XORCipher'
describe('Testing XORCipher function', () => {
it('Test - 1, passing a non-string as an argument', () => {
expect(() => XORCipher(false, 0x345)).toThrow()
expect(() => XORCipher(true, 123)).toThrow()
expect(() => XORCipher(1n, 123n)).toThrow()
expect(() => XORCipher(false, 0.34)).toThrow()
expect(() => XORCipher({})).toThrow()
expect(() => XORCipher([])).toThrow()
})
it('Test - 2, passing a string & number as an argument', () => {
// NB: Node REPL might not output the null char '\x00' (charcode 0)
expect(XORCipher('test string', 32)).toBe('TEST\x00STRING')
expect(XORCipher('TEST\x00STRING', 32)).toBe('test string')
})
})
================================================
FILE: Compression/RLE.js
================================================
/*
* RLE (Run Length Encoding) is a simple form of data compression.
* The basic idea is to represent repeated successive characters as a single count and character.
* For example, the string "AAAABBBCCDAA" would be encoded as "4A3B2C1D2A".
*
* @author - [ddaniel27](https://github.com/ddaniel27)
*/
function Compress(str) {
let compressed = ''
let count = 1
for (let i = 0; i < str.length; i++) {
if (str[i] !== str[i + 1]) {
compressed += count + str[i]
count = 1
continue
}
count++
}
return compressed
}
function Decompress(str) {
let decompressed = ''
let match = [...str.matchAll(/(\d+)(\D)/g)] // match all groups of digits followed by a non-digit character
match.forEach((item) => {
let [count, char] = [item[1], item[2]]
decompressed += char.repeat(count)
})
return decompressed
}
export { Compress, Decompress }
================================================
FILE: Compression/test/RLE.test.js
================================================
import { Compress, Decompress } from '../RLE'
describe('Test RLE Compressor/Decompressor', () => {
it('Test - 1, Pass long repetitive strings', () => {
expect(Compress('AAAAAAAAAAAAAA')).toBe('14A')
expect(Compress('AAABBQQQQQFG')).toBe('3A2B5Q1F1G')
})
it('Test - 2, Pass compressed strings', () => {
expect(Decompress('14A')).toBe('AAAAAAAAAAAAAA')
expect(Decompress('3A2B5Q1F1G')).toBe('AAABBQQQQQFG')
})
})
================================================
FILE: Conversions/ArbitraryBase.js
================================================
/**
* Divide two numbers and get the result of floor division and remainder
* @param {number} dividend
* @param {number} divisor
* @returns {[result: number, remainder: number]}
*/
const floorDiv = (dividend, divisor) => {
const remainder = dividend % divisor
const result = Math.floor(dividend / divisor)
return [result, remainder]
}
/**
* Converts a string from one base to other. Loses accuracy above the value of `Number.MAX_SAFE_INTEGER`.
* @param {string} stringInBaseOne String in input base
* @param {string} baseOneCharacters Character set for the input base
* @param {string} baseTwoCharacters Character set for the output base
* @returns {string}
*/
const convertArbitraryBase = (
stringInBaseOne,
baseOneCharacterString,
baseTwoCharacterString
) => {
if (
[stringInBaseOne, baseOneCharacterString, baseTwoCharacterString]
.map((arg) => typeof arg)
.some((type) => type !== 'string')
) {
throw new TypeError('Only string arguments are allowed')
}
const baseOneCharacters = [...baseOneCharacterString]
const baseTwoCharacters = [...baseTwoCharacterString]
for (const charactersInBase of [baseOneCharacters, baseTwoCharacters]) {
if (charactersInBase.length !== new Set(charactersInBase).size) {
throw new TypeError(
'Duplicate characters in character set are not allowed'
)
}
}
const reversedStringOneChars = [...stringInBaseOne].reverse()
const stringOneBase = baseOneCharacters.length
let value = 0
let placeValue = 1
for (const digit of reversedStringOneChars) {
const digitNumber = baseOneCharacters.indexOf(digit)
if (digitNumber === -1) {
throw new TypeError(`Not a valid character: ${digit}`)
}
value += digitNumber * placeValue
placeValue *= stringOneBase
}
const outputChars = []
const stringTwoBase = baseTwoCharacters.length
while (value > 0) {
const [divisionResult, remainder] = floorDiv(value, stringTwoBase)
outputChars.push(baseTwoCharacters[remainder])
value = divisionResult
}
return outputChars.reverse().join('') || baseTwoCharacters[0]
}
/**
* Converts a arbitrary-length string from one base to other. Doesn't lose accuracy.
* @param {string} stringInBaseOne String in input base
* @param {string} baseOneCharacters Character set for the input base
* @param {string} baseTwoCharacters Character set for the output base
* @returns {string}
*/
const convertArbitraryBaseBigIntVersion = (
stringInBaseOne,
baseOneCharacterString,
baseTwoCharacterString
) => {
if (
[stringInBaseOne, baseOneCharacterString, baseTwoCharacterString]
.map((arg) => typeof arg)
.some((type) => type !== 'string')
) {
throw new TypeError('Only string arguments are allowed')
}
const baseOneCharacters = [...baseOneCharacterString]
const baseTwoCharacters = [...baseTwoCharacterString]
for (const charactersInBase of [baseOneCharacters, baseTwoCharacters]) {
if (charactersInBase.length !== new Set(charactersInBase).size) {
throw new TypeError(
'Duplicate characters in character set are not allowed'
)
}
}
const reversedStringOneChars = [...stringInBaseOne].reverse()
const stringOneBase = BigInt(baseOneCharacters.length)
let value = 0n
let placeValue = 1n
for (const digit of reversedStringOneChars) {
const digitNumber = BigInt(baseOneCharacters.indexOf(digit))
if (digitNumber === -1n) {
throw new TypeError(`Not a valid character: ${digit}`)
}
value += digitNumber * placeValue
placeValue *= stringOneBase
}
const outputChars = []
const stringTwoBase = BigInt(baseTwoCharacters.length)
while (value > 0n) {
const divisionResult = value / stringTwoBase
const remainder = value % stringTwoBase
outputChars.push(baseTwoCharacters[remainder])
value = divisionResult
}
return outputChars.reverse().join('') || baseTwoCharacters[0]
}
export { convertArbitraryBase, convertArbitraryBaseBigIntVersion }
================================================
FILE: Conversions/ArrayBufferToBase64.js
================================================
// About base64: https://en.wikipedia.org/wiki/Base64
/**
* Converts an array of bytes to base64 encoding
* @param {ArrayBuffer} binaryData An ArrayBuffer which represents an array of bytes
* @returns {string} A string containing the base64 encoding of `binaryData`
*/
function bufferToBase64(binaryData) {
// The base64 encoding uses the following set of characters to encode any binary data as text
const base64Table =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
// Every 3 bytes translates to 4 base64 characters, if we have less than 3 bytes we must append '=' chars as padding
const padding = 3 - (binaryData.byteLength % 3)
// Create an instance of Uint8Array, to read from the binaryData array buffer
const byteView = new Uint8Array(binaryData)
let result = ''
// Loop through all bytes in the buffer, in increments of 3 bytes
for (let i = 0; i < byteView.byteLength; i += 3) {
// Get the index for the next 4 base64 chars
const char1 = (byteView[i] & 252) >> 2
const char2 = ((byteView[i] & 3) << 4) + ((byteView[i + 1] & 240) >> 4)
const char3 = ((byteView[i + 1] & 15) << 2) + ((byteView[i + 2] & 192) >> 6)
const char4 = byteView[i + 2] & 63
result +=
base64Table[char1] +
base64Table[char2] +
base64Table[char3] +
base64Table[char4]
}
// Add padding '=' chars if needed
if (padding !== 3) {
const paddedResult =
result.slice(0, result.length - padding) + '='.repeat(padding)
return paddedResult
}
return result
}
export { bufferToBase64 }
================================================
FILE: Conversions/Base64ToArrayBuffer.js
================================================
// About base64: https://en.wikipedia.org/wiki/Base64
/**
* Converts a base64 string to an array of bytes
* @param {string} b64 A base64 string
* @returns {ArrayBuffer} An ArrayBuffer representing the bytes encoded by the base64 string
*/
function base64ToBuffer(b64) {
// The base64 encoding uses the following set of characters to encode any binary data as text
const base64Table =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
// Find the index of char '=' first occurrence
const paddingIdx = b64.indexOf('=')
// Remove padding chars from base64 string, if there are any
const b64NoPadding = paddingIdx !== -1 ? b64.slice(0, paddingIdx) : b64
// Calculate the length of the result buffer
const bufferLength = Math.floor((b64NoPadding.length * 6) / 8)
// Create the result buffer
const result = new ArrayBuffer(bufferLength)
// Create an instance of Uint8Array, to write to the `result` buffer
const byteView = new Uint8Array(result)
// Loop through all chars in the base64 string, in increments of 4 chars, and in increments of 3 bytes
for (let i = 0, j = 0; i < b64NoPadding.length; i += 4, j += 3) {
// Get the index of the next 4 base64 chars
const b64Char1 = base64Table.indexOf(b64NoPadding[i])
const b64Char2 = base64Table.indexOf(b64NoPadding[i + 1])
let b64Char3 = base64Table.indexOf(b64NoPadding[i + 2])
let b64Char4 = base64Table.indexOf(b64NoPadding[i + 3])
// If base64 chars 3 and 4 don't exit, then set them to 0
if (b64Char3 === -1) b64Char3 = 0
if (b64Char4 === -1) b64Char4 = 0
// Calculate the next 3 bytes
const byte1 = (b64Char1 << 2) + ((b64Char2 & 48) >> 4)
const byte2 = ((b64Char2 & 15) << 4) + ((b64Char3 & 60) >> 2)
const byte3 = ((b64Char3 & 3) << 6) + b64Char4
byteView[j] = byte1
byteView[j + 1] = byte2
byteView[j + 2] = byte3
}
return result
}
export { base64ToBuffer }
================================================
FILE: Conversions/BinaryToDecimal.js
================================================
export default function binaryToDecimal(binaryString) {
let decimalNumber = 0
const binaryDigits = binaryString.split('').reverse() // Splits the binary number into reversed single digits
binaryDigits.forEach((binaryDigit, index) => {
decimalNumber += binaryDigit * Math.pow(2, index) // Summation of all the decimal converted digits
})
return decimalNumber
}
================================================
FILE: Conversions/BinaryToHex.js
================================================
const pad = (num, padlen) => {
const pad = new Array(1 + padlen).join(0)
return (pad + num).slice(-pad.length)
}
const hexLookup = (bin) => {
let binary = bin
if (binary.length < 4) {
binary = pad(binary, 4)
}
switch (binary) {
case '0000':
return '0'
case '0001':
return '1'
case '0010':
return '2'
case '0011':
return '3'
case '0100':
return '4'
case '0101':
return '5'
case '0110':
return '6'
case '0111':
return '7'
case '1000':
return '8'
case '1001':
return '9'
case '1010':
return 'A'
case '1011':
return 'B'
case '1100':
return 'C'
case '1101':
return 'D'
case '1110':
return 'E'
case '1111':
return 'F'
}
}
const binaryToHex = (binaryString) => {
/*
Function for converting Binary to Hex
1. The conversion will start from Least Significant Digit (LSB) to the Most Significant Bit (MSB).
2. We divide the bits into sections of 4-bits starting from LSB to MSB.
3. If the MSB get less than 4 bits, then we pad 0s to the front of it.
For Example:
Binary String = '1001101'
1. Divide it to 2 parts => ['100', '1101']
2. Pad 0s the MSB so it'll be => ['0100', '1101']
3. Use the lookup table and merge them, therefore the result is 4D.
*/
let result = ''
binaryString = binaryString.split('')
for (let i = binaryString.length - 1; i >= 0; i = i - 4) {
if (i >= 3) {
result += hexLookup(binaryString.slice(i - 3, i + 1).join(''))
} else {
result += hexLookup(binaryString.slice(0, i + 1).join(''))
}
}
return result.split('').reverse().join('')
}
export default binaryToHex
================================================
FILE: Conversions/DateDayDifference.js
================================================
/*
DateDayDifference Method
------------------------
DateDayDifference method calculates the number of days between two dates.
Algorithm & Explanation : https://ncalculators.com/time-date/date-difference-calculator.htm
*/
import { isLeapYear } from '../Maths/LeapYear'
import { parseDate } from '../Timing-Functions/ParseDate'
const DateToDay = (dd, mm, yyyy) => {
return (
365 * (yyyy - 1) +
Math.floor((yyyy - 1) / 4) -
Math.floor((yyyy - 1) / 100) +
Math.floor((yyyy - 1) / 400) +
dd +
Math.floor((367 * mm - 362) / 12) +
(mm <= 2 ? 0 : isLeapYear(yyyy) ? -1 : -2)
)
}
const DateDayDifference = (date1, date2) => {
const firstDate = parseDate(date1)
const secondDate = parseDate(date2)
return Math.abs(
DateToDay(secondDate.day, secondDate.month, secondDate.year) -
DateToDay(firstDate.day, firstDate.month, firstDate.year)
)
}
// Example : DateDayDifference('17/08/2002', '10/10/2020') => 6630
export { DateDayDifference }
================================================
FILE: Conversions/DateToDay.js
================================================
/*
DateToDay Method
----------------
The DateToDay method takes a date in string format and
returns the name of a day. The approach behind this method
is very simple, we first take a string date and check
whether their date is valid or not, if the date is valid
then we do this But apply the algorithm shown below. The
algorithm shown below gives us the number of the day and
finally converts it to the name of the day.
Algorithm & Explanation : https://en.wikipedia.org/wiki/Zeller%27s_congruence
*/
import { parseDate } from '../Timing-Functions/ParseDate'
// Array holding name of the day: Saturday - Sunday - Friday => 0 - 1 - 6
const daysNameArr = [
'Saturday',
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday'
]
const DateToDay = (date) => {
// firstly, check that input is a string or not.
const dateStruct = parseDate(date)
let year = dateStruct.year
let month = dateStruct.month
let day = dateStruct.day
// In case of Jan and Feb:
// Year: we consider it as previous year
// e.g., 1/1/1987 here year is 1986 (-1)
// Month: we consider value as 13 & 14 respectively
if (month < 3) {
year--
month += 12
}
// divide year into century and the last two digits of the century
const yearDigits = year % 100
const century = Math.floor(year / 100)
/*
In mathematics, remainders of divisions are usually defined to always be positive;
As an example, -2 mod 7 = 5.
Many programming languages including JavaScript implement the remainder of `n % m` as `sign(n) * (abs(n) % m)`.
This means the result has the same sign as the numerator. Here, `-2 % 7 = -1 * (2 % 7) = -2`.
To ensure a positive numerator, the formula is adapted: `- 2 * century` is replaced with `+ 5 * century`
which does not alter the resulting numbers mod 7 since `7 - 2 = 5`
The following example shows the issue with modulo division:
Without the adaption, the formula yields `weekDay = -6` for the date 2/3/2014;
With the adaption, it yields the positive result `weekDay = 7 - 6 = 1` (Sunday), which is what we need to index the array
*/
const weekDay =
(day +
Math.floor((month + 1) * 2.6) +
yearDigits +
Math.floor(yearDigits / 4) +
Math.floor(century / 4) +
5 * century) %
7
return daysNameArr[weekDay] // name of the weekday
}
// Example : DateToDay("18/12/2020") => Friday
export { DateToDay }
================================================
FILE: Conversions/DecimalToBinary.js
================================================
function decimalToBinary(num) {
const bin = []
while (num > 0) {
bin.unshift(num % 2)
num >>= 1 // basically /= 2 without remainder if any
}
return bin.join('')
}
export { decimalToBinary }
// > decimalToBinary(2)
// '10'
// > decimalToBinary(7)
// '111'
// > decimalToBinary(35)
// '100011'
================================================
FILE: Conversions/DecimalToHex.js
================================================
function intToHex(num) {
switch (num) {
case 10:
return 'A'
case 11:
return 'B'
case 12:
return 'C'
case 13:
return 'D'
case 14:
return 'E'
case 15:
return 'F'
}
return num
}
function decimalToHex(num) {
const hexOut = []
while (num > 15) {
hexOut.unshift(intToHex(num % 16))
num = Math.floor(num / 16)
}
return intToHex(num) + hexOut.join('')
}
export { decimalToHex }
================================================
FILE: Conversions/DecimalToOctal.js
================================================
function decimalToOctal(num) {
let oct = 0
let c = 0
while (num > 0) {
const r = num % 8
oct = oct + r * Math.pow(10, c++)
num = Math.floor(num / 8) // basically /= 8 without remainder if any
}
return oct
}
export { decimalToOctal }
// > decimalToOctal(2)
// 2
// > decimalToOctal(8)
// 10
// > decimalToOctal(65)
// 101
// > decimalToOctal(216)
// 330
// > decimalToOctal(512)
// 1000
================================================
FILE: Conversions/DecimalToRoman.js
================================================
/*
Decimal To Roman
This algorithm take decimal number and convert to roman numeral according to standard form (https://en.wikipedia.org/wiki/Roman_numerals#Description)
Algorithm & Explanation : https://www.rapidtables.com/convert/number/how-number-to-roman-numerals.html
*/
const values = {
M: 1000,
CM: 900,
D: 500,
CD: 400,
C: 100,
XC: 90,
L: 50,
XL: 40,
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1
}
const orders = [
'M',
'CM',
'D',
'CD',
'C',
'XC',
'L',
'XL',
'X',
'IX',
'V',
'IV',
'I'
]
function decimalToRoman(num) {
let roman = ''
for (const symbol of orders) {
while (num >= values[symbol]) {
roman += symbol
num -= values[symbol]
}
}
return roman
}
export { decimalToRoman }
================================================
FILE: Conversions/HexToBinary.js
================================================
const binLookup = (key) =>
({
0: '0000',
1: '0001',
2: '0010',
3: '0011',
4: '0100',
5: '0101',
6: '0110',
7: '0111',
8: '1000',
9: '1001',
a: '1010',
b: '1011',
c: '1100',
d: '1101',
e: '1110',
f: '1111'
})[key.toLowerCase()] // select the binary number by valid hex key with the help javascript object
const hexToBinary = (hexString) => {
if (typeof hexString !== 'string') {
throw new TypeError('Argument is not a string type')
}
if (/[^\da-f]/gi.test(hexString)) {
throw new Error('Argument is not a valid HEX code!')
}
/*
Function for converting Hex to Binary
1. We convert every hexadecimal bit to 4 binary bits
2. Conversion goes by searching in the lookup table
*/
return hexString.replace(/[0-9a-f]/gi, (lexeme) => binLookup(lexeme))
}
export default hexToBinary
================================================
FILE: Conversions/HexToDecimal.js
================================================
function hexToInt(hexNum) {
if (!/^[0-9A-F]+$/.test(hexNum)) {
throw new Error('Invalid hex string.')
}
const numArr = hexNum.split('') // converts number to array
return numArr.map((item, index) => {
switch (item) {
case 'A':
return 10
case 'B':
return 11
case 'C':
return 12
case 'D':
return 13
case 'E':
return 14
case 'F':
return 15
default:
return parseInt(item)
}
})
}
function hexToDecimal(hexNum) {
const intItemsArr = hexToInt(hexNum)
return intItemsArr.reduce((accumulator, current, index) => {
return (
accumulator + current * Math.pow(16, intItemsArr.length - (1 + index))
)
}, 0)
}
export { hexToDecimal }
================================================
FILE: Conversions/HexToRGB.js
================================================
function hexStringToRGB(hexString) {
let r = hexString.substring(0, 2)
let g = hexString.substring(2, 4)
let b = hexString.substring(4, 6)
r = parseInt(r, 16)
g = parseInt(g, 16)
b = parseInt(b, 16)
const obj = { r, g, b }
return obj
}
export { hexStringToRGB }
// > hexStringToRGB('ffffff')
// { r: 255, g: 255, b: 255 }
================================================
FILE: Conversions/LengthConversion.js
================================================
/**
* Converts a length from one unit to another.
*
* @param {number} length - The length to convert.
* @param {string} fromUnit - The unit to convert from (e.g., "km", "m", "cm").
* @param {string} toUnit - The unit to convert to (e.g., "km", "m", "cm").
* @returns {number} The converted length.
* @throws {Error} If the units are invalid or not found in the conversion dictionary.
*/
const lengthConversion = (length, fromUnit, toUnit) => {
// Define a dictionary to map units to meters
const meters = {
mm: 0.001,
cm: 0.01,
m: 1,
km: 1000,
inch: 0.0254,
ft: 0.3048,
yd: 0.9144,
mi: 1609.34
}
// Check if the units are in the dictionary, otherwise, throw an error
if (!(fromUnit in meters) || !(toUnit in meters)) {
throw new Error('Invalid units')
}
// Perform the conversion
const metersFrom = length * meters[fromUnit]
const convertedLength = metersFrom / meters[toUnit]
return convertedLength
}
export { lengthConversion }
================================================
FILE: Conversions/LitersToImperialGallons.js
================================================
/**
* This function converts liters to imperial gallons
* @constructor
* @param {number} liters - Amount of liters to convert to gallons
* @see https://en.wikipedia.org/wiki/Gallon
*/
const litersToImperialGallons = (liters) => {
return liters / 4.54609
}
export default litersToImperialGallons
================================================
FILE: Conversions/LitersToUSGallons.js
================================================
/**
* This function converts liters to US gallons
* https://en.wikipedia.org/wiki/Gallon
* @constructor
* @param {number} liters - Amount of liters to convert to gallons
*/
const litersToUSGallons = (liters) => {
return liters / 3.785411784
}
export default litersToUSGallons
================================================
FILE: Conversions/LowerCaseConversion.js
================================================
/*
Explanation :- a user gives a String (it can be incomplete uppercase or
partial uppercase) and then the program would convert it into a
complete(all characters in lower case) lower case string. The
logic we have used in the following program is: All the upper case
characters (A-Z) has ASCII value ranging from 65 to 90 and their
corresponding lower case characters (a-z) have ASCII values 32
greater than them. For example ‘A‘ has an ASCII value of 65
and ‘a‘ has an ASCII value of 97 (65+32). The same applies to other
characters.
*/
/**
* LowerCaseConversion takes any case-style string and converts it to the lower case-style string.
* @param {String} inputString any case style string
* @returns {String} lower case string
*/
const LowerCaseConversion = (inputString) => {
// Take a string and split it into characters.
const newString = inputString.split('').map((char) => {
// Get a character code by the use charCodeAt method.
const presentCharCode = char.charCodeAt()
// If the character code lies between 65 to 90 it means they are in the upper case so convert it.
if (presentCharCode >= 65 && presentCharCode <= 90) {
// Convert the case by use of the above explanation.
return String.fromCharCode(presentCharCode + 32)
}
// Else return the characters without any modification.
return char
})
// After modification, with the help of the join method, join all the characters and return them.
return newString.join('')
}
export { LowerCaseConversion }
================================================
FILE: Conversions/MeterToFeetConversion.js
================================================
// Foot: https://en.wikipedia.org/wiki/Foot_(unit)
const feetToMeter = (feet) => {
return feet * 0.3048
}
const meterToFeet = (meter) => {
return meter / 0.3048
}
export { feetToMeter, meterToFeet }
================================================
FILE: Conversions/OctToDecimal.js
================================================
function octalToDecimal(num) {
let dec = 0
let base = 1
while (num > 0) {
const r = num % 10
num = Math.floor(num / 10)
dec = dec + r * base
base = base * 8
}
return dec
}
export { octalToDecimal }
// > octalToDecimal(56)
// 46
// > octalToDecimal(2365)
// 1269
================================================
FILE: Conversions/OuncesToKilograms.js
================================================
/**
* This function converts ounces to kilograms
* https://en.wikipedia.org/wiki/Ounce
* @constructor
* @param {number} oz - Amount of ounces to convert to kilograms
*/
const ouncesToKilograms = (oz) => {
return (oz * 28.3498) / 1000
}
export default ouncesToKilograms
================================================
FILE: Conversions/RGBToHex.js
================================================
function RGBToHex(r, g, b) {
if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number') {
throw new TypeError('argument is not a Number')
}
const toHex = (n) => (n || '0').toString(16).padStart(2, '0')
return `#${toHex(r)}${toHex(g)}${toHex(b)}`
}
export { RGBToHex }
// > RGBToHex(255, 255, 255)
// '#ffffff'
// > RGBToHex(255, 99, 71)
// '#ff6347'
================================================
FILE: Conversions/RailwayTimeConversion.js
================================================
/*
The time conversion of normalized time to the railway is a simple algorithm
because we know that if the time is in 'AM' value it means they only want
some changes on hours and minutes and if the time in 'PM' it means the only
want some changes in hour value.
Input Format -> 07:05:45PM
Output Format -> 19:05:45
Problem & Explanation Source : https://www.mathsisfun.com/time.html
*/
/**
* RailwayTimeConversion method converts normalized time string to Railway time string.
* @param {String} timeString Normalized time string.
* @returns {String} Railway time string.
*/
const RailwayTimeConversion = (timeString) => {
// firstly, check that input is a string or not.
if (typeof timeString !== 'string') {
throw new TypeError('Argument is not a string.')
}
// split the string by ':' character.
const [hour, minute, secondWithShift] = timeString.split(':')
// split second and shift value.
const [second, shift] = [
secondWithShift.substring(0, 2),
secondWithShift.substring(2)
]
// convert shifted time to not-shift time(Railway time) by using the above explanation.
if (shift === 'PM') {
if (parseInt(hour) === 12) {
return `${hour}:${minute}:${second}`
} else {
return `${parseInt(hour) + 12}:${minute}:${second}`
}
} else {
if (parseInt(hour) === 12) {
return `00:${minute}:${second}`
} else {
return `${hour}:${minute}:${second}`
}
}
}
export { RailwayTimeConversion }
================================================
FILE: Conversions/RgbHslConversion.js
================================================
/**
* Given a color in RGB format, convert it to HSL format.
*
* For more info: https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/
*
* @param {number[]} colorRgb - One dimensional array of integers (RGB color format).
* @returns {number[]} - One dimensional array of integers (HSL color format).
*
* @example
* const colorRgb = [24, 98, 118]
*
* const result = rgbToHsl(colorRgb)
*
* // The function returns the corresponding color in HSL format:
* // result = [193, 66, 28]
*/
const checkRgbFormat = (colorRgb) => colorRgb.every((c) => c >= 0 && c <= 255)
const rgbToHsl = (colorRgb) => {
if (!checkRgbFormat(colorRgb)) {
throw new Error('Input is not a valid RGB color.')
}
let colorHsl = colorRgb
let red = Math.round(colorRgb[0])
let green = Math.round(colorRgb[1])
let blue = Math.round(colorRgb[2])
const limit = 255
colorHsl[0] = red / limit
colorHsl[1] = green / limit
colorHsl[2] = blue / limit
let minValue = Math.min(...colorHsl)
let maxValue = Math.max(...colorHsl)
let channel = 0
if (maxValue === colorHsl[1]) {
channel = 1
} else if (maxValue === colorHsl[2]) {
channel = 2
}
let luminance = (minValue + maxValue) / 2
let saturation = 0
if (minValue !== maxValue) {
if (luminance <= 0.5) {
saturation = (maxValue - minValue) / (maxValue + minValue)
} else {
saturation = (maxValue - minValue) / (2 - maxValue - minValue)
}
}
let hue = 0
if (saturation !== 0) {
if (channel === 0) {
hue = (colorHsl[1] - colorHsl[2]) / (maxValue - minValue)
} else if (channel === 1) {
hue = 2 + (colorHsl[2] - colorHsl[0]) / (maxValue - minValue)
} else {
hue = 4 + (colorHsl[0] - colorHsl[1]) / (maxValue - minValue)
}
}
hue *= 60
if (hue < 0) {
hue += 360
}
colorHsl[0] = Math.round(hue)
colorHsl[1] = Math.round(saturation * 100)
colorHsl[2] = Math.round(luminance * 100)
return colorHsl
}
export { rgbToHsl }
================================================
FILE: Conversions/RgbHsvConversion.js
================================================
/*
* The RGB color model is an additive color model in which red, green, and blue light are added
* together in various ways to reproduce a broad array of colors. The name of the model comes from
* the initials of the three additive primary colors, red, green, and blue. Meanwhile, the HSV
* representation models how colors appear under light. In it, colors are represented using three
* components: hue, saturation and (brightness-)value. This file provides functions for converting
* colors from one representation to the other. (description adapted from
* https://en.wikipedia.org/wiki/RGB_color_model and https://en.wikipedia.org/wiki/HSL_and_HSV).
*/
/**
* Conversion from the HSV-representation to the RGB-representation.
*
* @param hue Hue of the color.
* @param saturation Saturation of the color.
* @param value Brightness-value of the color.
* @return The tuple of RGB-components.
*/
export function hsvToRgb(hue, saturation, value) {
if (hue < 0 || hue > 360) {
throw new Error('hue should be between 0 and 360')
}
if (saturation < 0 || saturation > 1) {
throw new Error('saturation should be between 0 and 1')
}
if (value < 0 || value > 1) {
throw new Error('value should be between 0 and 1')
}
const chroma = value * saturation
const hueSection = hue / 60
const secondLargestComponent = chroma * (1 - Math.abs((hueSection % 2) - 1))
const matchValue = value - chroma
return getRgbBySection(hueSection, chroma, matchValue, secondLargestComponent)
}
/**
* Conversion from the RGB-representation to the HSV-representation.
*
* @param red Red-component of the color.
* @param green Green-component of the color.
* @param blue Blue-component of the color.
* @return The tuple of HSV-components.
*/
export function rgbToHsv(red, green, blue) {
if (red < 0 || red > 255) {
throw new Error('red should be between 0 and 255')
}
if (green < 0 || green > 255) {
throw new Error('green should be between 0 and 255')
}
if (blue < 0 || blue > 255) {
throw new Error('blue should be between 0 and 255')
}
const dRed = red / 255
const dGreen = green / 255
const dBlue = blue / 255
const value = Math.max(Math.max(dRed, dGreen), dBlue)
const chroma = value - Math.min(Math.min(dRed, dGreen), dBlue)
const saturation = value === 0 ? 0 : chroma / value
let hue
if (chroma === 0) {
hue = 0
} else if (value === dRed) {
hue = 60 * ((dGreen - dBlue) / chroma)
} else if (value === dGreen) {
hue = 60 * (2 + (dBlue - dRed) / chroma)
} else {
hue = 60 * (4 + (dRed - dGreen) / chroma)
}
hue = (hue + 360) % 360
return [hue, saturation, value]
}
export function approximatelyEqualHsv(hsv1, hsv2) {
const bHue = Math.abs(hsv1[0] - hsv2[0]) < 0.2
const bSaturation = Math.abs(hsv1[1] - hsv2[1]) < 0.002
const bValue = Math.abs(hsv1[2] - hsv2[2]) < 0.002
return bHue && bSaturation && bValue
}
function getRgbBySection(
hueSection,
chroma,
matchValue,
secondLargestComponent
) {
function convertToInt(input) {
return Math.round(255 * input)
}
let red
let green
let blue
if (hueSection >= 0 && hueSection <= 1) {
red = convertToInt(chroma + matchValue)
green = convertToInt(secondLargestComponent + matchValue)
blue = convertToInt(matchValue)
} else if (hueSection > 1 && hueSection <= 2) {
red = convertToInt(secondLargestComponent + matchValue)
green = convertToInt(chroma + matchValue)
blue = convertToInt(matchValue)
} else if (hueSection > 2 && hueSection <= 3) {
red = convertToInt(matchValue)
green = convertToInt(chroma + matchValue)
blue = convertToInt(secondLargestComponent + matchValue)
} else if (hueSection > 3 && hueSection <= 4) {
red = convertToInt(matchValue)
green = convertToInt(secondLargestComponent + matchValue)
blue = convertToInt(chroma + matchValue)
} else if (hueSection > 4 && hueSection <= 5) {
red = convertToInt(secondLargestComponent + matchValue)
green = convertToInt(matchValue)
blue = convertToInt(chroma + matchValue)
} else {
red = convertToInt(chroma + matchValue)
green = convertToInt(matchValue)
blue = convertToInt(secondLargestComponent + matchValue)
}
return [red, green, blue]
}
================================================
FILE: Conversions/RomanToDecimal.js
================================================
const values = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000
}
export function romanToDecimal(romanNumber) {
let prev = ' '
let sum = 0
let newPrev = 0
for (let i = romanNumber.length - 1; i >= 0; i--) {
const c = romanNumber.charAt(i)
if (prev !== ' ') {
newPrev = values[prev] > newPrev ? values[prev] : newPrev
}
const currentNum = values[c]
if (currentNum >= newPrev) {
sum += currentNum
} else {
sum -= currentNum
}
prev = c
}
return sum
}
================================================
FILE: Conversions/TemperatureConversion.js
================================================
// This files has functions to convert different temperature units
// Functions take temperature value as a argument and returns corresponding converted value
const celsiusToFahrenheit = (celsius) => {
// Wikipedia reference: https://en.wikipedia.org/wiki/Celsius
// Wikipedia reference: https://en.wikipedia.org/wiki/Fahrenheit
return Math.round((celsius * 9) / 5 + 32)
}
const celsiusToKelvin = (celsius) => {
// Wikipedia reference: https://en.wikipedia.org/wiki/Celsius
// Wikipedia reference: https://en.wikipedia.org/wiki/Kelvin
return Math.round(celsius + 273.15)
}
const celsiusToRankine = (celsius) => {
// Wikipedia reference: https://en.wikipedia.org/wiki/Celsius
// Wikipedia reference: https://en.wikipedia.org/wiki/Rankine_scale
return Math.round((celsius * 9) / 5 + 491.67)
}
const fahrenheitToCelsius = (fahrenheit) => {
// Wikipedia reference: https://en.wikipedia.org/wiki/Fahrenheit
// Wikipedia reference: https://en.wikipedia.org/wiki/Celsius
return Math.round(((fahrenheit - 32) * 5) / 9)
}
const fahrenheitToKelvin = (fahrenheit) => {
// Wikipedia reference: https://en.wikipedia.org/wiki/Fahrenheit
// Wikipedia reference: https://en.wikipedia.org/wiki/Kelvin
return Math.round(((fahrenheit - 32) * 5) / 9 + 273.15)
}
const fahrenheitToRankine = (fahrenheit) => {
// Wikipedia reference: https://en.wikipedia.org/wiki/Fahrenheit
// Wikipedia reference: https://en.wikipedia.org/wiki/Rankine_scale
return Math.round(fahrenheit + 459.67)
}
const kelvinToCelsius = (kelvin) => {
// Wikipedia reference: https://en.wikipedia.org/wiki/Kelvin
// Wikipedia reference: https://en.wikipedia.org/wiki/Celsius
return Math.round(kelvin - 273.15)
}
const kelvinToFahrenheit = (kelvin) => {
// Wikipedia reference: https://en.wikipedia.org/wiki/Kelvin
// Wikipedia reference: https://en.wikipedia.org/wiki/Fahrenheit
return Math.round(((kelvin - 273.15) * 9) / 5 + 32)
}
const kelvinToRankine = (kelvin) => {
// Wikipedia reference: https://en.wikipedia.org/wiki/Kelvin
// Wikipedia reference: https://en.wikipedia.org/wiki/Rankine_scale
return Math.round((kelvin * 9) / 5)
}
const rankineToCelsius = (rankine) => {
// Wikipedia reference: https://en.wikipedia.org/wiki/Rankine_scale
// Wikipedia reference: https://en.wikipedia.org/wiki/Celsius
return Math.round(((rankine - 491.67) * 5) / 9)
}
const rankineToFahrenheit = (rankine) => {
// Wikipedia reference: https://en.wikipedia.org/wiki/Rankine_scale
// Wikipedia reference: https://en.wikipedia.org/wiki/Fahrenheit
return Math.round(rankine - 459.67)
}
const rankineToKelvin = (rankine) => {
// Wikipedia reference: https://en.wikipedia.org/wiki/Rankine_scale
// Wikipedia reference: https://en.wikipedia.org/wiki/Kelvin
return Math.round((rankine * 5) / 9)
}
const reaumurToKelvin = (reaumur) => {
// Reference:- http://www.csgnetwork.com/temp2conv.html
return Math.round(reaumur * 1.25 + 273.15)
}
const reaumurToFahrenheit = (reaumur) => {
// Reference:- http://www.csgnetwork.com/temp2conv.html
return Math.round(reaumur * 2.25 + 32)
}
const reaumurToCelsius = (reaumur) => {
// Reference:- http://www.csgnetwork.com/temp2conv.html
return Math.round(reaumur * 1.25)
}
const reaumurToRankine = (reaumur) => {
// Reference:- http://www.csgnetwork.com/temp2conv.html
return Math.round(reaumur * 2.25 + 32 + 459.67)
}
export {
celsiusToFahrenheit,
celsiusToKelvin,
celsiusToRankine,
fahrenheitToCelsius,
fahrenheitToKelvin,
fahrenheitToRankine,
kelvinToCelsius,
kelvinToFahrenheit,
kelvinToRankine,
rankineToCelsius,
rankineToFahrenheit,
rankineToKelvin,
reaumurToCelsius,
reaumurToFahrenheit,
reaumurToKelvin,
reaumurToRankine
}
================================================
FILE: Conversions/TitleCaseConversion.js
================================================
/*
Problem statement and Explanation : https://www.codeproject.com/Tips/162540/Letter-Case-Conversion-Algorithms-Title-Case-Toggl.
[Title case](https://en.wikipedia.org/wiki/Title_case) is a style where all words are capitalized. Officially, title case
does not capitalize some words, such as very short words like "a" or "is", but for the purposes of this function, a general approach
is taken where all words are capitalized regardless of length.
*/
/**
* The titleCaseConversion function converts a string into a title case string.
* @param {string} inputString The input string which can have any types of letter casing.
* @returns {string} A string that is in title case.
*/
const titleCaseConversion = (inputString) => {
if (inputString === '') return ''
// Extract all space separated string.
const stringCollections = inputString.split(' ').map((word) => {
let firstChar = ''
// Get the [ASCII](https://en.wikipedia.org/wiki/ASCII) character code by the use charCodeAt method.
const firstCharCode = word[0].charCodeAt()
// If the ASCII character code lies between 97 to 122 it means they are in the lowercase so convert it.
if (firstCharCode >= 97 && firstCharCode <= 122) {
// Convert the case by use of the above explanation.
firstChar += String.fromCharCode(firstCharCode - 32)
} else {
// Else store the characters without any modification.
firstChar += word[0]
}
const newWordChar = word
.slice(1)
.split('')
.map((char) => {
// Get the ASCII character code by the use charCodeAt method.
const presentCharCode = char.charCodeAt()
// If the ASCII character code lies between 65 to 90, it means they are in the uppercase so convert it.
if (presentCharCode >= 65 && presentCharCode <= 90) {
// Convert the case by use of the above explanation.
return String.fromCharCode(presentCharCode + 32)
}
// Else return the characters without any modification.
return char
})
// Return the first converted character and remaining character string.
return firstChar + newWordChar.join('')
})
// Convert all words in a string and return it.
return stringCollections.join(' ')
}
export { titleCaseConversion }
================================================
FILE: Conversions/UpperCaseConversion.js
================================================
/*
Explanation :- A user gives a string (it can be incomplete lowercase or
partially in lowercase) and then the program converts it into a
completely (all characters in uppercase) uppercase string. The
logic we have used in the following program is: All the lowercase
characters (a-z) has [ASCII](https://en.wikipedia.org/wiki/ASCII) value ranging from 97 to 122 and their
corresponding uppercase characters (A-Z) have ASCII values 32
lesser than them. For example ‘a‘ has an ASCII value of 97
and ‘A‘ has an ASCII value of 65 (97 - 32). The same applies to other
characters.
*/
/**
* upperCaseConversion takes any case-style string and converts it to the uppercase-style string.
* @param {string} inputString Any case style string
* @returns {string} Uppercase string
*/
const upperCaseConversion = (inputString) => {
// Take a string and split it into characters.
const newString = inputString.split('').map((char) => {
// Get a character code by the use charCodeAt method.
const presentCharCode = char.charCodeAt()
// If the character code lies between 97 to 122, it means they are in the lowercase so convert it.
if (presentCharCode >= 97 && presentCharCode <= 122) {
// Convert the case by use of the above explanation.
return String.fromCharCode(presentCharCode - 32)
}
// Else return the characters without any modification.
return char
})
// After modification, with the help of the join method, join all the characters and return them.
return newString.join('')
}
export { upperCaseConversion }
================================================
FILE: Conversions/test/ArbitraryBase.test.js
================================================
import {
convertArbitraryBase,
convertArbitraryBaseBigIntVersion
} from '../ArbitraryBase'
test('Check the answer of convertArbitraryBase(98, 0123456789, 01234567) is 142', () => {
const res = convertArbitraryBase('98', '0123456789', '01234567')
expect(res).toBe('142')
})
test('Check the answer of convertArbitraryBase(98, 0123456789, abcdefgh) is bec', () => {
const res = convertArbitraryBase('98', '0123456789', 'abcdefgh')
expect(res).toBe('bec')
})
test('Check the answer of convertArbitraryBase(98, 0123456789, 98765432) is 857', () => {
const res = convertArbitraryBase('98', '0123456789', '98765432')
expect(res).toBe('857')
})
test('Check the answer of convertArbitraryBase(129, 0123456789, 01234567) is 201', () => {
const res = convertArbitraryBase('129', '0123456789', '01234567')
expect(res).toBe('201')
})
test('Check the answer of convertArbitraryBase(112, 0123456789, 12345678) is 271', () => {
const res = convertArbitraryBase('112', '0123456789', '12345678')
expect(res).toBe('271')
})
test('Check the answer of convertArbitraryBase(112, 0123456789, 123456789) is 245', () => {
const res = convertArbitraryBase('112', '0123456789', '123456789')
expect(res).toBe('245')
})
test('Check the answer of convertArbitraryBase(111, 0123456789, abcdefgh) is bfh', () => {
const res = convertArbitraryBase('111', '0123456789', 'abcdefgh')
expect(res).toBe('bfh')
})
test('Unicode awareness', () => {
const res = convertArbitraryBase('98', '0123456789', '💝🎸🦄')
expect(res).toBe('🎸💝🎸🦄🦄')
})
test('zero', () => {
const res = convertArbitraryBase('0', '0123456789', 'abc')
expect(res).toBe('a')
})
test('BigInt version with input string of arbitrary length', () => {
const resBigIntVersion = convertArbitraryBaseBigIntVersion(
String(10n ** 100n),
'0123456789',
'0123456789abcdefghijklmnopqrstuvwxyz'
)
expect(resBigIntVersion).toBe((10n ** 100n).toString(36))
})
================================================
FILE: Conversions/test/ArrayBufferToBase64.test.js
================================================
import { bufferToBase64 } from '../ArrayBufferToBase64'
import { TextEncoder } from 'util'
describe('ArrayBufferToBase64', () => {
it('should encode "Hello, world!" as "SGVsbG8sIHdvcmxkIQ=="', () => {
const testString = 'Hello, world!'
const encoder = new TextEncoder()
const helloWorldBuffer = encoder.encode(testString)
const result = bufferToBase64(helloWorldBuffer)
expect(result).toBe('SGVsbG8sIHdvcmxkIQ==')
})
it('should encode binary buffer [55,23,177,234,68,26,90] as "Nxex6kQaWg=="', () => {
const testBuffer = new Uint8Array([55, 23, 177, 234, 68, 26, 90])
const result = bufferToBase64(testBuffer)
expect(result).toBe('Nxex6kQaWg==')
})
it('should encode binary buffer [0,1,2,3,4,5,6,7,8,9] as "AAECAwQFBgcICQ=="', () => {
const testBuffer = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
const result = bufferToBase64(testBuffer)
expect(result).toBe('AAECAwQFBgcICQ==')
})
})
================================================
FILE: Conversions/test/Base64ToArrayBuffer.test.js
================================================
import { base64ToBuffer } from '../Base64ToArrayBuffer'
import { TextDecoder } from 'util'
describe('Base64ToArrayBuffer', () => {
it('should decode "SGVsbG8sIHdvcmxkIQ==" as "Hello, world!"', () => {
const testBase64String = 'SGVsbG8sIHdvcmxkIQ=='
const buffer = base64ToBuffer(testBase64String)
const decoder = new TextDecoder()
const helloWorldString = decoder.decode(buffer)
expect(helloWorldString).toBe('Hello, world!')
})
it('should decode base64 "Nxex6kQaWg==" as binary buffer [55,23,177,234,68,26,90]', () => {
const testBase64String = 'Nxex6kQaWg=='
const buffer = base64ToBuffer(testBase64String)
const array = [...new Uint8Array(buffer)]
expect(array).toEqual([55, 23, 177, 234, 68, 26, 90])
})
it('should decode base64 "AAECAwQFBgcICQ==" as binary buffer [0,1,2,3,4,5,6,7,8,9]', () => {
const testBase64String = 'AAECAwQFBgcICQ=='
const buffer = base64ToBuffer(testBase64String)
const array = [...new Uint8Array(buffer)]
expect(array).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
})
})
================================================
FILE: Conversions/test/BinaryToDecimal.test.js
================================================
import binaryToDecimal from '../BinaryToDecimal'
describe('BinaryToDecimal', () => {
it('expects to return correct decimal value', () => {
expect(binaryToDecimal('1000')).toBe(8)
})
it('expects to return correct hexadecimal value for more than one hex digit', () => {
expect(binaryToDecimal('01101000')).toBe(104)
})
it('expects to return correct hexadecimal value for padding-required binary', () => {
expect(binaryToDecimal('1000101')).toBe(69)
})
})
================================================
FILE: Conversions/test/BinaryToHex.test.js
================================================
import binaryToHex from '../BinaryToHex'
describe('BinaryToHex', () => {
it('expects to return correct hexadecimal value', () => {
expect(binaryToHex('1000')).toBe('8')
})
it('expects to return correct hexadecimal value for more than one hex digit', () => {
expect(binaryToHex('11101010')).toBe('EA')
})
it('expects to return correct hexadecimal value for padding-required binary', () => {
expect(binaryToHex('1001101')).toBe('4D')
})
it('expects to return correct hexadecimal value, matching (num).toString(16)', () => {
expect(binaryToHex('1111')).toBe(
parseInt('1111', 2).toString(16).toUpperCase()
)
})
})
================================================
FILE: Conversions/test/DateDayDiffernce.test.js
================================================
import { DateDayDifference } from '../DateDayDifference'
describe('DateDayDifference', () => {
it.each([
['17/08/2002', '10/10/2020', 6629],
['18/02/2001', '16/03/2022', 7696],
['11/11/2011', '12/12/2012', 397],
['01/01/2001', '16/03/2011', 3726],
['04/03/2024', '04/03/2024', 0],
['03/03/2024', '04/03/2024', 1],
['02/03/2024', '04/03/2024', 2],
['01/03/2024', '04/03/2024', 3],
['29/02/2024', '04/03/2024', 4],
['04/03/2024', '04/03/2025', 365],
['04/03/2023', '04/03/2024', 366]
])(
'The difference between %s and %s is %i',
(firstDate, secondDate, expected) => {
expect(DateDayDifference(firstDate, secondDate)).toBe(expected)
expect(DateDayDifference(secondDate, firstDate)).toBe(expected)
}
)
it('should throw when any input is not a string', () => {
expect(() => DateDayDifference(10102024, '11/10/2024')).toThrowError()
expect(() => DateDayDifference('11/10/2024', 10102024)).toThrowError()
})
it.each(['32/01/2000', '00/01/2000', '15/00/2000', '15/13/2000'])(
'should throw when input is not a correct date %s',
(wrongDate) => {
expect(() => DateDayDifference(wrongDate, '04/03/2024')).toThrowError()
expect(() => DateDayDifference('04/03/2024', wrongDate)).toThrowError()
}
)
})
================================================
FILE: Conversions/test/DateToDay.test.js
================================================
import { DateToDay } from '../DateToDay'
describe('DateToDay', () => {
it.each([
['18/02/2001', 'Sunday'],
['18/12/2020', 'Friday'],
['12/12/2012', 'Wednesday'],
['01/01/2001', 'Monday'],
['1/1/2020', 'Wednesday'],
['2/3/2014', 'Sunday'],
['28/2/2017', 'Tuesday'],
['02/03/2024', 'Saturday'],
['29/02/2024', 'Thursday']
])('%s is %s', (date, day) => {
expect(DateToDay(date)).toBe(day)
})
it('should throw when input is not a string', () => {
expect(() => DateToDay(100)).toThrowError()
})
it.each(['32/01/2000', '00/01/2000', '15/00/2000', '15/13/2000'])(
'should throw when input is not a correct date %s',
(wrongDate) => {
expect(() => DateToDay(wrongDate)).toThrowError()
}
)
})
================================================
FILE: Conversions/test/DecimalToBinary.test.js
================================================
import { decimalToBinary } from '../DecimalToBinary'
test('The Binary representation of 35 is 100011', () => {
const res = decimalToBinary(35)
expect(res).toBe('100011')
})
test('The Binary representation of 1 is 1', () => {
const res = decimalToBinary(1)
expect(res).toBe('1')
})
test('The Binary representation of 1000 is 1111101000', () => {
const res = decimalToBinary(1000)
expect(res).toBe('1111101000')
})
test('The Binary representation of 2 is 10', () => {
const res = decimalToBinary(2)
expect(res).toBe('10')
})
test('The Binary representation of 17 is 10001', () => {
const res = decimalToBinary(17)
expect(res).toBe('10001')
})
================================================
FILE: Conversions/test/DecimalToHex.test.js
================================================
import { decimalToHex } from '../DecimalToHex'
describe('DecimalToHex', () => {
it('expects to return correct hexadecimal value', () => {
expect(decimalToHex(255)).toBe('FF')
})
it('expects to return correct hexadecimal value, matching (num).toString(16)', () => {
expect(decimalToHex(32768)).toBe((32768).toString(16).toUpperCase())
})
it('expects to not handle negative numbers', () => {
expect(decimalToHex(-32768)).not.toBe((-32768).toString(16).toUpperCase())
})
})
================================================
FILE: Conversions/test/DecimalToOctal.test.js
================================================
import { decimalToOctal } from '../DecimalToOctal'
test('The Octal representation of 8 is 10', () => {
const res = decimalToOctal(8)
expect(res).toBe(10)
})
test('The Octal representation of 1 is 1', () => {
const res = decimalToOctal(1)
expect(res).toBe(1)
})
test('The Octal representation of 0 is 0', () => {
const res = decimalToOctal(0)
expect(res).toBe(0)
})
test('The Octal representation of 100 is 144', () => {
const res = decimalToOctal(100)
expect(res).toBe(144)
})
test('The Octal representation of 111 is 157', () => {
const res = decimalToOctal(111)
expect(res).toBe(157)
})
================================================
FILE: Conversions/test/DecimalToRoman.test.js
================================================
import { decimalToRoman } from '../DecimalToRoman'
describe('decimalToRoman', () => {
it('expects to return correct roman numeral of given number', () => {
expect(decimalToRoman(34)).toBe('XXXIV')
})
it('expects to return correct roman numeral of given number', () => {
expect(decimalToRoman(28)).toBe('XXVIII')
})
it('expects to return correct roman numeral of given number', () => {
expect(decimalToRoman(2021)).toBe('MMXXI')
})
})
================================================
FILE: Conversions/test/HexToBinary.test.js
================================================
import hexToBinary from '../HexToBinary'
describe('Testing hexToBinary', () => {
it('expects throw error in invalid types', () => {
expect(() => hexToBinary(false)).toThrowError()
expect(() => hexToBinary(null)).toThrowError()
expect(() => hexToBinary(23464)).toThrowError()
})
it('expects throw error in invalid hex', () => {
expect(() => hexToBinary('Hello i am not a valid Hex')).toThrowError()
expect(() => hexToBinary('Gf46f')).toThrowError()
expect(() => hexToBinary('M')).toThrowError()
})
it('expects to return correct hexadecimal value', () => {
expect(hexToBinary('8')).toBe('1000')
})
it('expects to return correct binary value for more than one hex digit', () => {
expect(hexToBinary('EA')).toBe('11101010')
})
it('expects to test its robustness as it should be case-insensitive', () => {
expect(hexToBinary('4d')).toBe('01001101')
})
it('expects to return correct hexadecimal value, matching (num).toString(2)', () => {
expect(hexToBinary('F')).toBe(parseInt('F', 16).toString(2))
})
})
================================================
FILE: Conversions/test/HexToDecimal.test.js
================================================
import { hexToDecimal } from '../HexToDecimal'
describe('Testing HexToDecimal', () => {
it.each([
['0', 0],
['1', 1],
['A', 10],
['B', 11],
['C', 12],
['D', 13],
['E', 14],
['F', 15],
['10', 16],
['859', 2137],
['4D2', 1234],
['81323ABD92', 554893491602]
])('check with %s', (hexStr, expected) => {
expect(hexToDecimal(hexStr)).toBe(expected)
})
it.each(['a', '-1', 'G', ''])('throws for %s', (hexStr) => {
expect(() => hexToDecimal(hexStr)).toThrowError()
})
})
================================================
FILE: Conversions/test/HexToRGB.test.js
================================================
import { hexStringToRGB } from '../HexToRGB'
test('The RGB form of Hex String E1E1E1 is {r: 225, g: 225, b: 225}', () => {
const res = hexStringToRGB('E1E1E1')
expect(res).toEqual({ r: 225, g: 225, b: 225 })
})
test('The RGB form of Hex String 000000 is {r: 0, g: 0, b: 0}', () => {
const res = hexStringToRGB('000000')
expect(res).toEqual({ r: 0, g: 0, b: 0 })
})
test('The RGB form of Hex String 6CE1CD is {r: 108, g: 225, b: 205}', () => {
const res = hexStringToRGB('6CE1CD')
expect(res).toEqual({ r: 108, g: 225, b: 205 })
})
================================================
FILE: Conversions/test/LengthConversion.test.js
================================================
import { lengthConversion } from '../LengthConversion.js'
describe('LengthConversion', () => {
it.each`
length | fromUnit | toUnit | expected
${10} | ${'km'} | ${'m'} | ${10000}
${100} | ${'m'} | ${'km'} | ${0.1}
${5} | ${'cm'} | ${'mm'} | ${50}
${12} | ${'ft'} | ${'inch'} | ${144.00000000000003}
`(
'converts $length $fromUnit to $toUnit',
({ length, fromUnit, toUnit, expected }) => {
try {
const result = lengthConversion(length, fromUnit, toUnit)
expect(result).toBe(expected)
} catch (error) {
expect(error).toBeUndefined()
}
}
)
it.each`
length | fromUnit | toUnit | expected
${10} | ${'m'} | ${'km'} | ${0.01}
${1000} | ${'mm'} | ${'cm'} | ${100}
${1} | ${'inch'} | ${'ft'} | ${0.08333333333}
`(
'converts $length $fromUnit to $toUnit (vice versa)',
({ length, fromUnit, toUnit, expected }) => {
try {
const result = lengthConversion(length, fromUnit, toUnit)
expect(result).toBeCloseTo(expected, 10) // Close comparison due to floating-point precision
} catch (error) {
expect(error).toBeUndefined()
}
}
)
it.each`
length | fromUnit | toUnit | expectedError
${10} | ${'km'} | ${'invalid'} | ${'Invalid units'}
${5} | ${'invalid'} | ${'m'} | ${'Invalid units'}
`(
'returns error message for invalid units: $fromUnit to $toUnit',
({ length, fromUnit, toUnit, expectedError }) => {
try {
lengthConversion(length, fromUnit, toUnit)
} catch (error) {
expect(error.message).toBe(expectedError)
}
}
)
})
================================================
FILE: Conversions/test/LitersToImperialGallons.test.js
================================================
import litersToImperialGallons from '../LitersToImperialGallons'
test('Convert 25 liters to imperial gallons', () => {
expect(parseFloat(litersToImperialGallons(25).toFixed(2))).toBe(5.5)
})
================================================
FILE: Conversions/test/LitersToUSGallons.test.js
================================================
import litersToUSGallons from '../LitersToUSGallons'
test('Convert 50 liters to US gallons', () => {
expect(parseFloat(litersToUSGallons(50).toFixed(2))).toBe(13.21)
})
================================================
FILE: Conversions/test/LowerCaseConversion.test.js
================================================
import { LowerCaseConversion } from '../LowerCaseConversion'
test('The LowerCaseConversion of ApoLO is apolo', () => {
const res = LowerCaseConversion('ApoLO')
expect(res).toBe('apolo')
})
test('The LowerCaseConversion of WEB is web', () => {
const res = LowerCaseConversion('WEB')
expect(res).toBe('web')
})
test('The LowerCaseConversion of EaRTh is earth', () => {
const res = LowerCaseConversion('EaRTh')
expect(res).toBe('earth')
})
test('The LowerCaseConversion of TiGER is tiger', () => {
const res = LowerCaseConversion('TiGER')
expect(res).toBe('tiger')
})
test('The LowerCaseConversion of Cricket is cricket', () => {
const res = LowerCaseConversion('Cricket')
expect(res).toBe('cricket')
})
================================================
FILE: Conversions/test/MeterToFeetConversion.test.js
================================================
import { meterToFeet, feetToMeter } from '../MeterToFeetConversion'
describe('Testing conversion of Meter to Feet', () => {
it('with feet value', () => {
expect(meterToFeet(30.48)).toBe(100)
})
})
describe('Testing conversion of Feet to Meter', () => {
it('with feet value', () => {
expect(feetToMeter(10)).toBe(3.048)
})
})
================================================
FILE: Conversions/test/OctToDecimal.test.js
================================================
import { octalToDecimal } from '../OctToDecimal'
test('The Decimal representation of Octal number 56 is 46', () => {
const res = octalToDecimal(56)
expect(res).toBe(46)
})
test('The Decimal representation of Octal number 99 is 81', () => {
const res = octalToDecimal(99)
expect(res).toBe(81)
})
test('The Decimal representation of Octal number 17 is 15', () => {
const res = octalToDecimal(17)
expect(res).toBe(15)
})
test('The Decimal representation of Octal number 100 is 64', () => {
const res = octalToDecimal(100)
expect(res).toBe(64)
})
test('The Decimal representation of Octal number 0 is 0', () => {
const res = octalToDecimal(0)
expect(res).toBe(0)
})
================================================
FILE: Conversions/test/OuncesToKilogram.test.js
================================================
import ouncesToKilograms from '../OuncesToKilograms'
test('Convert 60 ounces to kilograms', () => {
expect(parseFloat(ouncesToKilograms(60).toFixed(3))).toBe(1.701)
})
================================================
FILE: Conversions/test/RGBToHex.test.js
================================================
import { RGBToHex } from '../RGBToHex'
test('The Hex format of RGB (225, 225, 225) is #ffffff', () => {
const res = RGBToHex(255, 255, 255)
expect(res).toBe('#ffffff')
})
test('The Hex format of RGB (190, 108, 217) is #be6cd9', () => {
const res = RGBToHex(190, 108, 217)
expect(res).toBe('#be6cd9')
})
test('The Hex format of RGB (255, 99, 71) is #ff6347', () => {
const res = RGBToHex(255, 99, 71)
expect(res).toBe('#ff6347')
})
test('The Hex format of RGB (100, 108, 217) is #646cd9', () => {
const res = RGBToHex(100, 108, 217)
expect(res).toBe('#646cd9')
})
================================================
FILE: Conversions/test/RailwayTimeConversion.test.js
================================================
import { RailwayTimeConversion } from '../RailwayTimeConversion'
test('The RailwayTimeConversion of 07:05:45AM is 07:05:45', () => {
const res = RailwayTimeConversion('07:05:45AM')
expect(res).toEqual('07:05:45')
})
test('The RailwayTimeConversion of 07:05:45PM is 19:05:45', () => {
const res = RailwayTimeConversion('07:05:45PM')
expect(res).toEqual('19:05:45')
})
test('The RailwayTimeConversion of 10:20:00AM is 10:20:00', () => {
const res = RailwayTimeConversion('10:20:00AM')
expect(res).toEqual('10:20:00')
})
test('The RailwayTimeConversion of 11:20:00PM is 23:20:00', () => {
const res = RailwayTimeConversion('11:20:00PM')
expect(res).toEqual('23:20:00')
})
test('The RailwayTimeConversion throws when input is not a string', () => {
expect(() => RailwayTimeConversion(1120)).toThrowError()
})
================================================
FILE: Conversions/test/RgbHslConversion.test.js
================================================
import { rgbToHsl } from '../RgbHslConversion'
describe('RgbHslConversion', () => {
test.each([
[
[215, 19, 180],
[311, 84, 46]
],
[
[21, 190, 18],
[119, 83, 41]
],
[
[80, 100, 160],
[225, 33, 47]
],
[
[80, 1, 16],
[349, 98, 16]
],
[
[8, 20, 0],
[96, 100, 4]
],
[
[0, 0, 0],
[0, 0, 0]
],
[
[255, 255, 255],
[0, 0, 100]
]
])('Should return the color in HSL format.', (colorRgb, expected) => {
expect(rgbToHsl(colorRgb)).toEqual(expected)
})
test.each([
[[256, 180, 9], 'Input is not a valid RGB color.'],
[[-90, 46, 8], 'Input is not a valid RGB color.'],
[[1, 39, 900], 'Input is not a valid RGB color.']
])('Should return the error message.', (colorRgb, expected) => {
expect(() => rgbToHsl(colorRgb)).toThrowError(expected)
})
})
================================================
FILE: Conversions/test/RgbHsvConversion.test.js
================================================
import { approximatelyEqualHsv, hsvToRgb, rgbToHsv } from '../RgbHsvConversion'
describe('hsvToRgb', () => {
// Expected RGB-values taken from https://www.rapidtables.com/convert/color/hsv-to-rgb.html
it('should calculate the correct RGB values', () => {
expect(hsvToRgb(0, 0, 0)).toEqual([0, 0, 0])
expect(hsvToRgb(0, 0, 1)).toEqual([255, 255, 255])
expect(hsvToRgb(0, 1, 1)).toEqual([255, 0, 0])
expect(hsvToRgb(60, 1, 1)).toEqual([255, 255, 0])
expect(hsvToRgb(120, 1, 1)).toEqual([0, 255, 0])
expect(hsvToRgb(240, 1, 1)).toEqual([0, 0, 255])
expect(hsvToRgb(300, 1, 1)).toEqual([255, 0, 255])
expect(hsvToRgb(180, 0.5, 0.5)).toEqual([64, 128, 128])
expect(hsvToRgb(234, 0.14, 0.88)).toEqual([193, 196, 224])
expect(hsvToRgb(330, 0.75, 0.5)).toEqual([128, 32, 80])
})
})
describe('rgbToHsv', () => {
// "approximatelyEqualHsv" needed because of small deviations due to rounding for the RGB-values
it('should calculate the correct HSV values', () => {
expect(approximatelyEqualHsv(rgbToHsv(0, 0, 0), [0, 0, 0])).toEqual(true)
expect(approximatelyEqualHsv(rgbToHsv(255, 255, 255), [0, 0, 1])).toEqual(
true
)
expect(approximatelyEqualHsv(rgbToHsv(255, 0, 0), [0, 1, 1])).toEqual(true)
expect(approximatelyEqualHsv(rgbToHsv(255, 255, 0), [60, 1, 1])).toEqual(
true
)
expect(approximatelyEqualHsv(rgbToHsv(0, 255, 0), [120, 1, 1])).toEqual(
true
)
expect(approximatelyEqualHsv(rgbToHsv(0, 0, 255), [240, 1, 1])).toEqual(
true
)
expect(approximatelyEqualHsv(rgbToHsv(255, 0, 255), [300, 1, 1])).toEqual(
true
)
expect(
approximatelyEqualHsv(rgbToHsv(64, 128, 128), [180, 0.5, 0.5])
).toEqual(true)
expect(
approximatelyEqualHsv(rgbToHsv(193, 196, 224), [234, 0.14, 0.88])
).toEqual(true)
expect(
approximatelyEqualHsv(rgbToHsv(128, 32, 80), [330, 0.75, 0.5])
).toEqual(true)
})
})
================================================
FILE: Conversions/test/RomanToDecimal.test.js
================================================
import { romanToDecimal } from '../RomanToDecimal'
describe('romanToDecimal', () => {
it('XXIIVV', () => {
expect(romanToDecimal('XXIIVV')).toBe(28)
})
it('MDCCCIV', () => {
expect(romanToDecimal('MDCCCIV')).toBe(1804)
})
it('XXIVI', () => {
expect(romanToDecimal('XXIVI')).toBe(25)
})
})
================================================
FILE: Conversions/test/TemperatureConversion.test.js
================================================
import * as tc from '../TemperatureConversion.js'
describe('Testing Conversion of Celsius to fahrenheit', () => {
it('with celsius value', () => {
const test1 = tc.celsiusToFahrenheit(10)
expect(test1).toBe(50)
})
})
describe('Testing Conversion of Celsius to kelvin', () => {
it('with celsius value', () => {
const test1 = tc.celsiusToKelvin(15)
expect(test1).toBe(288)
})
})
describe('Testing Conversion of Celsius to Rankine', () => {
it('with celsius value', () => {
const test1 = tc.celsiusToRankine(28)
expect(test1).toBe(542)
})
})
describe('Testing Conversion of Fahrenheit to Celsius', () => {
it('with Fahrenheit value', () => {
const test1 = tc.fahrenheitToCelsius(134)
expect(test1).toBe(57)
})
})
describe('Testing Conversion of Fahrenheit to Kelvin', () => {
it('with Fahrenheit value', () => {
const test1 = tc.fahrenheitToKelvin(125)
expect(test1).toBe(325)
})
})
describe('Testing Conversion of Fahrenheit to Rankine', () => {
it('with Fahrenheit value', () => {
const test1 = tc.fahrenheitToRankine(10)
expect(test1).toBe(470)
})
})
describe('Testing Conversion of Kelvin to Celsius', () => {
it('with Kelvin value', () => {
const test1 = tc.kelvinToCelsius(100)
expect(test1).toBe(-173)
})
})
describe('Testing Conversion of Kelvin to Fahrenheit', () => {
it('with Kelvin value', () => {
const test1 = tc.kelvinToFahrenheit(20)
expect(test1).toBe(-424)
})
})
describe('Testing Conversion of Kelvin to Rankine', () => {
it('with kelvin value', () => {
const test1 = tc.kelvinToRankine(69)
expect(test1).toBe(124)
})
})
describe('Testing Conversion of Rankine to Celsius', () => {
it('with Rankine value', () => {
const test1 = tc.rankineToCelsius(234)
expect(test1).toBe(-143)
})
})
describe('Testing Conversion of Rankine to Fahrenheit', () => {
it('with Rankine value', () => {
const test1 = tc.rankineToFahrenheit(98)
expect(test1).toBe(-362)
})
})
describe('Testing Conversion of Rankine to Kelvin', () => {
it('with Rankine value', () => {
const test1 = tc.rankineToKelvin(10)
expect(test1).toBe(6)
})
})
describe('Testing Conversion of Reaumur to Celsius', () => {
it('with Reaumur value', () => {
const test1 = tc.reaumurToCelsius(100)
expect(test1).toBe(125)
})
})
describe('Testing Conversion of Reaumur to Fahrenheit', () => {
it('with Reaumur value', () => {
const test1 = tc.reaumurToFahrenheit(100)
expect(test1).toBe(257)
})
})
describe('Testing Conversion of Reaumur to Kelvin', () => {
it('with Reamur value', () => {
const test1 = tc.reaumurToKelvin(100)
expect(test1).toBe(398)
})
})
describe('Testing Conversion of Reamur to Rankine', () => {
it('with Reamur value', () => {
const test1 = tc.reaumurToRankine(100)
expect(test1).toBe(717)
})
})
================================================
FILE: Conversions/test/TitleCaseConversion.test.js
================================================
import { titleCaseConversion } from '../TitleCaseConversion'
describe('Tests for the titleCaseConversion function', () => {
it('should return an empty string when the input is an empty string', () => {
expect(titleCaseConversion('')).toEqual('')
})
it('should return the input string when the input string is a title case string', () => {
expect(titleCaseConversion('A Proper Title Case String')).toEqual(
'A Proper Title Case String'
)
})
it('should return a title case string when input is an all-uppercase string', () => {
expect(titleCaseConversion('ALL UPPER CASE')).toEqual('All Upper Case')
})
it('should return a title case string when input is a title case string of with spaces', () => {
expect(titleCaseConversion('ALL UPPERCASE')).toEqual('All Uppercase')
})
it('should return a title case string when input is a title case string of with no spaces', () => {
expect(titleCaseConversion('ALLUPPERCASE')).toEqual('Alluppercase')
})
it('should return a title case string when input is a title case string with punctuation', () => {
expect(titleCaseConversion('All Title Case!')).toEqual('All Title Case!')
})
it('should return a title case string when input is an all-lowercase string with no spaces', () => {
expect(titleCaseConversion('lowercaseinput')).toEqual('Lowercaseinput')
})
it('should return a title case string when input is an all-lowercase string with spaces', () => {
expect(titleCaseConversion('lowercase input')).toEqual('Lowercase Input')
})
it('should return a title case string when input is an all-lowercase string with punctuation', () => {
expect(titleCaseConversion('lower, case, input.')).toEqual(
'Lower, Case, Input.'
)
})
it('should return a title case string when input is an mixed-case string', () => {
expect(titleCaseConversion('mixeD CaSe INPuT')).toEqual('Mixed Case Input')
})
it('should return a title case string when input is an mixed-case string with no spaces', () => {
expect(titleCaseConversion('mixeDCaSeINPuT')).toEqual('Mixedcaseinput')
})
it('should return a title case string when input is an mixed-case string with punctuation', () => {
expect(titleCaseConversion('mixeD, CaSe, INPuT!')).toEqual(
'Mixed, Case, Input!'
)
})
})
================================================
FILE: Conversions/test/UpperCaseConverstion.test.js
================================================
import { upperCaseConversion } from '../UpperCaseConversion'
describe('Test the upperCaseConversion function', () => {
it('should return an empty string when the input is an empty string', () => {
expect(upperCaseConversion('')).toEqual('')
})
it('should return an all-uppercase string when input is an all-uppercase string', () => {
expect(upperCaseConversion('ALLUPPERCASE')).toEqual('ALLUPPERCASE')
})
it('should return an all-uppercase string when input is an all-uppercase string with spaces', () => {
expect(upperCaseConversion('ALL UPPERCASE')).toEqual('ALL UPPERCASE')
})
it('should return an all-uppercase string when input is an all-uppercase string with punctuation', () => {
expect(upperCaseConversion('ALL UPPER-CASE!')).toEqual('ALL UPPER-CASE!')
})
it('should return an all-uppercase string when input is an all-lowercase string', () => {
expect(upperCaseConversion('lowercaseinput')).toEqual('LOWERCASEINPUT')
})
it('should return an all-uppercase string when input is an all-lowercase string with spaces', () => {
expect(upperCaseConversion('lowercase input')).toEqual('LOWERCASE INPUT')
})
it('should return an all-uppercase string when input is an all-lowercase string with punctuation', () => {
expect(upperCaseConversion('lower-case, input.')).toEqual(
'LOWER-CASE, INPUT.'
)
})
it('should return an all-uppercase string when input is an mixed-case string', () => {
expect(upperCaseConversion('mixeDCaSeINPuT')).toEqual('MIXEDCASEINPUT')
})
it('should return an all-uppercase string when input is an mixed-case string with spaces', () => {
expect(upperCaseConversion('mixeD CaSe INPuT')).toEqual('MIXED CASE INPUT')
})
it('should return an all-uppercase string when input is an mixed-case string with punctuation', () => {
expect(upperCaseConversion('mixeD-CaSe INPuT!')).toEqual(
'MIXED-CASE INPUT!'
)
})
})
================================================
FILE: DIRECTORY.md
================================================
* **Backtracking**
* [AllCombinationsOfSizeK](Backtracking/AllCombinationsOfSizeK.js)
* [generateParentheses](Backtracking/generateParentheses.js)
* [GeneratePermutations](Backtracking/GeneratePermutations.js)
* [KnightTour](Backtracking/KnightTour.js)
* [MColoringProblem](Backtracking/MColoringProblem.js)
* [NQueens](Backtracking/NQueens.js)
* [RatInAMaze](Backtracking/RatInAMaze.js)
* [Sudoku](Backtracking/Sudoku.js)
* [SumOfSubset](Backtracking/SumOfSubset.js)
* **Bit-Manipulation**
* [BinaryCountSetBits](Bit-Manipulation/BinaryCountSetBits.js)
* [GenerateSubSets](Bit-Manipulation/GenerateSubSets.js)
* [GrayCodes](Bit-Manipulation/GrayCodes.js)
* [IsPowerofFour](Bit-Manipulation/IsPowerofFour.js)
* [IsPowerOfTwo](Bit-Manipulation/IsPowerOfTwo.js)
* [LogTwo](Bit-Manipulation/LogTwo.js)
* [NextPowerOfTwo](Bit-Manipulation/NextPowerOfTwo.js)
* [SetBit](Bit-Manipulation/SetBit.js)
* [UniqueElementInAnArray](Bit-Manipulation/UniqueElementInAnArray.js)
* **Cache**
* [LFUCache](Cache/LFUCache.js)
* [LRUCache](Cache/LRUCache.js)
* [Memoize](Cache/Memoize.js)
* **Cellular-Automata**
* [ConwaysGameOfLife](Cellular-Automata/ConwaysGameOfLife.js)
* [Elementary](Cellular-Automata/Elementary.js)
* **Ciphers**
* [AffineCipher](Ciphers/AffineCipher.js)
* [Atbash](Ciphers/Atbash.js)
* [CaesarCipher](Ciphers/CaesarCipher.js)
* [KeyFinder](Ciphers/KeyFinder.js)
* [KeywordShiftedAlphabet](Ciphers/KeywordShiftedAlphabet.js)
* [MorseCode](Ciphers/MorseCode.js)
* [ROT13](Ciphers/ROT13.js)
* [VigenereCipher](Ciphers/VigenereCipher.js)
* [XORCipher](Ciphers/XORCipher.js)
* **Compression**
* [RLE](Compression/RLE.js)
* **Conversions**
* [ArbitraryBase](Conversions/ArbitraryBase.js)
* [ArrayBufferToBase64](Conversions/ArrayBufferToBase64.js)
* [Base64ToArrayBuffer](Conversions/Base64ToArrayBuffer.js)
* [BinaryToDecimal](Conversions/BinaryToDecimal.js)
* [BinaryToHex](Conversions/BinaryToHex.js)
* [DateDayDifference](Conversions/DateDayDifference.js)
* [DateToDay](Conversions/DateToDay.js)
* [DecimalToBinary](Conversions/DecimalToBinary.js)
* [DecimalToHex](Conversions/DecimalToHex.js)
* [DecimalToOctal](Conversions/DecimalToOctal.js)
* [DecimalToRoman](Conversions/DecimalToRoman.js)
* [HexToBinary](Conversions/HexToBinary.js)
* [HexToDecimal](Conversions/HexToDecimal.js)
* [HexToRGB](Conversions/HexToRGB.js)
* [LengthConversion](Conversions/LengthConversion.js)
* [LitersToImperialGallons](Conversions/LitersToImperialGallons.js)
* [LitersToUSGallons](Conversions/LitersToUSGallons.js)
* [LowerCaseConversion](Conversions/LowerCaseConversion.js)
* [MeterToFeetConversion](Conversions/MeterToFeetConversion.js)
* [OctToDecimal](Conversions/OctToDecimal.js)
* [OuncesToKilograms](Conversions/OuncesToKilograms.js)
* [RailwayTimeConversion](Conversions/RailwayTimeConversion.js)
* [RgbHslConversion](Conversions/RgbHslConversion.js)
* [RgbHsvConversion](Conversions/RgbHsvConversion.js)
* [RGBToHex](Conversions/RGBToHex.js)
* [RomanToDecimal](Conversions/RomanToDecimal.js)
* [TemperatureConversion](Conversions/TemperatureConversion.js)
* [TitleCaseConversion](Conversions/TitleCaseConversion.js)
* [UpperCaseConversion](Conversions/UpperCaseConversion.js)
* **Data-Structures**
* **Array**
* [LocalMaximumPoint](Data-Structures/Array/LocalMaximumPoint.js)
* [NumberOfLocalMaximumPoints](Data-Structures/Array/NumberOfLocalMaximumPoints.js)
* [QuickSelect](Data-Structures/Array/QuickSelect.js)
* [Reverse](Data-Structures/Array/Reverse.js)
* **Graph**
* [Graph](Data-Structures/Graph/Graph.js)
* [Graph2](Data-Structures/Graph/Graph2.js)
* [Graph3](Data-Structures/Graph/Graph3.js)
* **Heap**
* [BinaryHeap](Data-Structures/Heap/BinaryHeap.js)
* [KeyPriorityQueue](Data-Structures/Heap/KeyPriorityQueue.js)
* [MinPriorityQueue](Data-Structures/Heap/MinPriorityQueue.js)
* **Linked-List**
* [AddTwoNumbers](Data-Structures/Linked-List/AddTwoNumbers.js)
* [CycleDetection](Data-Structures/Linked-List/CycleDetection.js)
* [CycleDetectionII](Data-Structures/Linked-List/CycleDetectionII.js)
* [DoublyLinkedList](Data-Structures/Linked-List/DoublyLinkedList.js)
* [MergeTwoSortedLinkedLists](Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js)
* [ReverseSinglyLinkedList](Data-Structures/Linked-List/ReverseSinglyLinkedList.js)
* [SinglyCircularLinkedList](Data-Structures/Linked-List/SinglyCircularLinkedList.js)
* [SinglyLinkedList](Data-Structures/Linked-List/SinglyLinkedList.js)
* **Queue**
* [CircularQueue](Data-Structures/Queue/CircularQueue.js)
* [Queue](Data-Structures/Queue/Queue.js)
* [QueueUsing2Stacks](Data-Structures/Queue/QueueUsing2Stacks.js)
* **Stack**
* [EvaluateExpression](Data-Structures/Stack/EvaluateExpression.js)
* [Stack](Data-Structures/Stack/Stack.js)
* [StackES6](Data-Structures/Stack/StackES6.js)
* **Tree**
* [AVLTree](Data-Structures/Tree/AVLTree.js)
* [BinarySearchTree](Data-Structures/Tree
gitextract_1dh1r31z/ ├── .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/ │ │ ├── LocalMaximumPoint.js │ │ ├── NumberOfLocalMaximumPoints.js │ │ ├── QuickSelect.js │ │ ├── Reverse.js │ │ └── test/ │ │ ├── LocalMaximumPoint.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 ├── Sliding-Windows/ │ ├── LongestSubarrayWithSumAtMost.js │ ├── MaxSumSubarrayFixed.js │ └── test/ │ ├── LongestSubarrayWithSumAtMost.test.js │ └── MaxSumSubarrayFixed.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.json └── vitest.config.ts
SYMBOL INDEX (618 symbols across 186 files)
FILE: .github/workflows/UpdateDirectory.js
function pathPrefix (line 5) | function pathPrefix (i) {
function printPath (line 10) | function printPath (oldPath, newPath, output) {
function pathsToMarkdown (line 26) | function pathsToMarkdown (filePaths) {
FILE: Backtracking/AllCombinationsOfSizeK.js
function generateCombinations (line 1) | function generateCombinations(n, k) {
FILE: Backtracking/KnightTour.js
class OpenKnightTour (line 3) | class OpenKnightTour {
method constructor (line 4) | constructor(size) {
method getMoves (line 10) | getMoves([i, j]) {
method isComplete (line 29) | isComplete() {
method solve (line 34) | solve() {
method solveHelper (line 44) | solveHelper([i, j], curr) {
method printBoard (line 60) | printBoard(output = (value) => console.log(value)) {
FILE: Backtracking/MColoringProblem.js
function mColoring (line 8) | function mColoring(graph, m) {
FILE: Backtracking/NQueens.js
class NQueens (line 1) | class NQueens {
method constructor (line 2) | constructor(size) {
method isValid (line 11) | isValid([row, col]) {
method placeQueen (line 32) | placeQueen(row, col) {
method removeQueen (line 36) | removeQueen(row, col) {
method solve (line 40) | solve(col = 0) {
method printBoard (line 57) | printBoard(output = (value) => console.log(value)) {
FILE: Backtracking/RatInAMaze.js
function validateGrid (line 24) | function validateGrid(grid) {
function isSafe (line 40) | function isSafe(grid, x, y) {
function getPathPart (line 55) | function getPathPart(grid, x, y, solution, path) {
function getPath (line 96) | function getPath(grid) {
class RatInAMaze (line 114) | class RatInAMaze {
method constructor (line 115) | constructor(grid) {
FILE: Backtracking/Sudoku.js
class Sudoku (line 1) | class Sudoku {
method constructor (line 3) | constructor(board) {
method findEmptyCell (line 7) | findEmptyCell() {
method check (line 17) | check([y, x], value) {
method solve (line 41) | solve() {
method getSection (line 59) | getSection(row, [start, end]) {
method printBoard (line 63) | printBoard(output = (...v) => console.log(...v)) {
FILE: Bit-Manipulation/BinaryCountSetBits.js
function BinaryCountSetBits (line 10) | function BinaryCountSetBits(a) {
FILE: Bit-Manipulation/GenerateSubSets.js
function generateSubSets (line 9) | function generateSubSets(inputArray) {
FILE: Bit-Manipulation/GrayCodes.js
function generateGrayCodes (line 25) | function generateGrayCodes(n) {
FILE: Cache/LFUCache.js
class CacheNode (line 1) | class CacheNode {
method constructor (line 2) | constructor(key, value, frequency) {
class FrequencyMap (line 12) | class FrequencyMap extends Map {
method refresh (line 25) | refresh(node) {
method insert (line 40) | insert(node) {
method [Symbol.species] (line 13) | static get [Symbol.species]() {
method [Symbol.toStringTag] (line 16) | get [Symbol.toStringTag]() {
class LFUCache (line 51) | class LFUCache {
method constructor (line 59) | constructor(capacity) {
method capacity (line 73) | get capacity() {
method size (line 81) | get size() {
method capacity (line 88) | set capacity(newCapacity) {
method info (line 102) | get info() {
method leastFrequency (line 112) | get leastFrequency() {
method #removeCacheNode (line 124) | #removeCacheNode() {
method has (line 138) | has(key) {
method get (line 150) | get(key) {
method set (line 174) | set(key, value, frequency = 1) {
method parse (line 209) | parse(json) {
method clear (line 228) | clear() {
method toString (line 241) | toString(indent) {
FILE: Cache/LRUCache.js
class LRUCache (line 1) | class LRUCache {
method constructor (line 9) | constructor(capacity) {
method info (line 22) | get info() {
method size (line 31) | get size() {
method capacity (line 35) | get capacity() {
method capacity (line 39) | set capacity(newCapacity) {
method #removeLeastRecentlyUsed (line 58) | #removeLeastRecentlyUsed() {
method has (line 66) | has(key) {
method set (line 76) | set(key, value) {
method get (line 90) | get(key) {
method parse (line 112) | parse(json) {
method toString (line 129) | toString(indent) {
FILE: Cellular-Automata/ConwaysGameOfLife.js
function newGeneration (line 14) | function newGeneration(cells) {
FILE: Cellular-Automata/Elementary.js
function getNextElementaryGeneration (line 67) | function getNextElementaryGeneration(generation, rule) {
FILE: Ciphers/AffineCipher.js
function mod (line 16) | function mod(n, m) {
function inverseMod (line 26) | function inverseMod(a, m) {
function isCorrectFormat (line 39) | function isCorrectFormat(str, a, b) {
function findCharIndex (line 60) | function findCharIndex(char) {
function encrypt (line 72) | function encrypt(str, a, b) {
function decrypt (line 91) | function decrypt(str, a, b) {
FILE: Ciphers/KeyFinder.js
function keyFinder (line 6) | function keyFinder(str) {
function caesarCipherEncodeAndDecodeEngine (line 67) | function caesarCipherEncodeAndDecodeEngine(inStr, numShifted) {
FILE: Ciphers/KeywordShiftedAlphabet.js
function checkKeywordValidity (line 48) | function checkKeywordValidity(keyword) {
function getEncryptedAlphabet (line 58) | function getEncryptedAlphabet(keyword) {
function translate (line 68) | function translate(sourceAlphabet, targetAlphabet, message) {
function checkInputs (line 81) | function checkInputs(keyword, message) {
function encrypt (line 91) | function encrypt(keyword, message) {
function decrypt (line 100) | function decrypt(keyword, message) {
FILE: Ciphers/ROT13.js
function ROT13 (line 8) | function ROT13(str) {
FILE: Ciphers/VigenereCipher.js
function isLetter (line 6) | function isLetter(str) {
function isUpperCase (line 15) | function isUpperCase(character) {
function encrypt (line 30) | function encrypt(message, key) {
function decrypt (line 61) | function decrypt(message, key) {
FILE: Compression/RLE.js
function Compress (line 9) | function Compress(str) {
function Decompress (line 26) | function Decompress(str) {
FILE: Conversions/ArrayBufferToBase64.js
function bufferToBase64 (line 8) | function bufferToBase64(binaryData) {
FILE: Conversions/Base64ToArrayBuffer.js
function base64ToBuffer (line 8) | function base64ToBuffer(b64) {
FILE: Conversions/BinaryToDecimal.js
function binaryToDecimal (line 1) | function binaryToDecimal(binaryString) {
FILE: Conversions/DecimalToBinary.js
function decimalToBinary (line 1) | function decimalToBinary(num) {
FILE: Conversions/DecimalToHex.js
function intToHex (line 1) | function intToHex(num) {
function decimalToHex (line 19) | function decimalToHex(num) {
FILE: Conversions/DecimalToOctal.js
function decimalToOctal (line 1) | function decimalToOctal(num) {
FILE: Conversions/DecimalToRoman.js
function decimalToRoman (line 41) | function decimalToRoman(num) {
FILE: Conversions/HexToDecimal.js
function hexToInt (line 1) | function hexToInt(hexNum) {
function hexToDecimal (line 26) | function hexToDecimal(hexNum) {
FILE: Conversions/HexToRGB.js
function hexStringToRGB (line 1) | function hexStringToRGB(hexString) {
FILE: Conversions/OctToDecimal.js
function octalToDecimal (line 1) | function octalToDecimal(num) {
FILE: Conversions/RGBToHex.js
function RGBToHex (line 1) | function RGBToHex(r, g, b) {
FILE: Conversions/RgbHsvConversion.js
function hsvToRgb (line 19) | function hsvToRgb(hue, saturation, value) {
function rgbToHsv (line 48) | function rgbToHsv(red, green, blue) {
function approximatelyEqualHsv (line 84) | function approximatelyEqualHsv(hsv1, hsv2) {
function getRgbBySection (line 92) | function getRgbBySection(
FILE: Conversions/RomanToDecimal.js
function romanToDecimal (line 11) | function romanToDecimal(romanNumber) {
FILE: Data-Structures/Array/QuickSelect.js
function QuickSelect (line 14) | function QuickSelect(items, kth) {
function RandomizedSelect (line 22) | function RandomizedSelect(items, left, right, i) {
function RandomizedPartition (line 34) | function RandomizedPartition(items, left, right) {
function Partition (line 40) | function Partition(items, left, right) {
function getRandomInt (line 56) | function getRandomInt(min, max) {
function Swap (line 60) | function Swap(arr, x, y) {
FILE: Data-Structures/Graph/Graph.js
class Graph (line 1) | class Graph {
method constructor (line 2) | constructor() {
method addVertex (line 6) | addVertex(vertex) {
method containsVertex (line 10) | containsVertex(vertex) {
method addEdge (line 14) | addEdge(vertex1, vertex2) {
method printGraph (line 21) | printGraph(output = (value) => console.log(value)) {
method bfs (line 37) | bfs(source, output = (value) => console.log(value)) {
method dfs (line 60) | dfs(source, visited = new Set(), output = (value) => console.log(value...
FILE: Data-Structures/Graph/Graph2.js
class Graph (line 2) | class Graph {
method constructor (line 5) | constructor(noOfVertices) {
method addVertex (line 20) | addVertex(v) {
method addEdge (line 28) | addEdge(v, w) {
method printGraph (line 39) | printGraph(output = (value) => console.log(value)) {
FILE: Data-Structures/Graph/Graph3.js
class Graph (line 1) | class Graph {
method constructor (line 2) | constructor() {
method addVertex (line 6) | addVertex(vertex) {
method addEdge (line 10) | addEdge(vertex1, vertex2) {
method removeEdge (line 15) | removeEdge(vertex1, vertex2) {
method removeVertex (line 24) | removeVertex(vertex) {
method DFS (line 34) | DFS(start) {
method DFSIterative (line 59) | DFSIterative(start) {
method BFS (line 83) | BFS(start) {
FILE: Data-Structures/Heap/BinaryHeap.js
class BinaryHeap (line 8) | class BinaryHeap {
method constructor (line 14) | constructor(comparatorFunction) {
method insert (line 32) | insert(value) {
method size (line 41) | size() {
method empty (line 49) | empty() {
method #bubbleUp (line 58) | #bubbleUp(currIdx) {
method #sinkDown (line 76) | #sinkDown(currIdx) {
method peek (line 101) | peek() {
method extractTop (line 109) | extractTop() {
method #swap (line 127) | #swap(index1, index2) {
FILE: Data-Structures/Heap/KeyPriorityQueue.js
class KeyPriorityQueue (line 25) | class KeyPriorityQueue {
method constructor (line 27) | constructor() {
method isEmpty (line 36) | isEmpty() {
method push (line 45) | push(key, priority) {
method pop (line 55) | pop() {
method contains (line 68) | contains(key) {
method update (line 78) | update(key, priority) {
method _getPriorityOrInfinite (line 98) | _getPriorityOrInfinite(position) {
method _shiftUp (line 105) | _shiftUp(position) {
method _shiftDown (line 121) | _shiftDown(position) {
method _swap (line 148) | _swap(position1, position2) {
FILE: Data-Structures/Heap/MinPriorityQueue.js
class MinPriorityQueue (line 13) | class MinPriorityQueue {
method constructor (line 15) | constructor(c) {
method insert (line 23) | insert(key) {
method peek (line 39) | peek() {
method isEmpty (line 44) | isEmpty() {
method isFull (line 49) | isFull() {
method print (line 54) | print(output = (value) => console.log(value)) {
method heapReverse (line 61) | heapReverse() {
method sink (line 80) | sink() {
method delete (line 112) | delete() {
FILE: Data-Structures/Linked-List/AddTwoNumbers.js
class AddTwoNumbers (line 16) | class AddTwoNumbers {
method constructor (line 17) | constructor() {
method solution (line 21) | solution(firstList, secondList) {
method solutionToArray (line 47) | solutionToArray() {
FILE: Data-Structures/Linked-List/CycleDetection.js
function detectCycle (line 6) | function detectCycle(head) {
FILE: Data-Structures/Linked-List/CycleDetectionII.js
function findCycleStart (line 8) | function findCycleStart(head) {
function cycleLength (line 46) | function cycleLength(head) {
FILE: Data-Structures/Linked-List/DoublyLinkedList.js
class Node (line 1) | class Node {
method constructor (line 2) | constructor(element) {
class DoubleLinkedList (line 9) | class DoubleLinkedList {
method constructor (line 10) | constructor() {
method append (line 17) | append(element) {
method insert (line 33) | insert(position, element) {
method removeAt (line 77) | removeAt(position) {
method indexOf (line 117) | indexOf(elm) {
method isPresent (line 136) | isPresent(elm) {
method delete (line 141) | delete(elm) {
method deleteHead (line 146) | deleteHead() {
method deleteTail (line 151) | deleteTail() {
method toString (line 156) | toString() {
method toArray (line 169) | toArray() {
method isEmpty (line 182) | isEmpty() {
method size (line 187) | size() {
method getHead (line 192) | getHead() {
method getTail (line 197) | getTail() {
method iterator (line 202) | iterator() {
method log (line 217) | log() {
FILE: Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js
function mergeLinkedLists (line 18) | function mergeLinkedLists(list1, list2) {
FILE: Data-Structures/Linked-List/ReverseSinglyLinkedList.js
class ReverseSinglyLinkedList (line 3) | class ReverseSinglyLinkedList {
method solution (line 4) | solution(head) {
FILE: Data-Structures/Linked-List/SinglyCircularLinkedList.js
class SinglyCircularLinkedList (line 4) | class SinglyCircularLinkedList {
method constructor (line 5) | constructor() {
method initiateNodeAndIndex (line 18) | initiateNodeAndIndex() {
method getElementAt (line 23) | getElementAt(index) {
method addAtFirst (line 35) | addAtFirst(data) {
method add (line 44) | add(data) {
method insertAt (line 58) | insertAt(index, data) {
method indexOf (line 72) | indexOf(data) {
method remove (line 87) | remove() {
method removeFirst (line 97) | removeFirst() {
method removeAt (line 112) | removeAt(index) {
method removeData (line 125) | removeData(data) {
method printData (line 132) | printData(output = (value) => console.log(value)) {
method get (line 143) | get() {
method clear (line 154) | clear() {
FILE: Data-Structures/Linked-List/SinglyLinkedList.js
class Node (line 11) | class Node {
method constructor (line 12) | constructor(data) {
class LinkedList (line 18) | class LinkedList {
method constructor (line 19) | constructor(listOfValues) {
method initiateNodeAndIndex (line 32) | initiateNodeAndIndex() {
method size (line 37) | size() {
method head (line 42) | head() {
method tail (line 47) | tail() {
method isEmpty (line 52) | isEmpty() {
method addLast (line 57) | addLast(element) {
method addFirst (line 71) | addFirst(element) {
method removeFirst (line 85) | removeFirst() {
method removeLast (line 102) | removeLast() {
method remove (line 121) | remove(element) {
method indexOf (line 147) | indexOf(element) {
method elementAt (line 161) | elementAt(index) {
method addAt (line 174) | addAt(index, element) {
method removeAt (line 199) | removeAt(index) {
method findMiddle (line 219) | findMiddle() {
method clean (line 232) | clean() {
method get (line 239) | get() {
method rotateListRight (line 250) | rotateListRight(k) {
method iterator (line 271) | iterator() {
method log (line 285) | log() {
method reverse (line 290) | reverse() {
FILE: Data-Structures/Queue/CircularQueue.js
class CircularQueue (line 6) | class CircularQueue {
method constructor (line 7) | constructor(maxLength) {
method enqueue (line 15) | enqueue(value) {
method dequeue (line 29) | dequeue() {
method checkEmpty (line 47) | checkEmpty() {
method checkSingleelement (line 53) | checkSingleelement() {
method checkOverflow (line 61) | checkOverflow() {
method display (line 72) | display(output = (value) => console.log(value)) {
method length (line 79) | length() {
method peek (line 84) | peek() {
FILE: Data-Structures/Queue/Queue.js
class Queue (line 9) | class Queue {
method constructor (line 12) | constructor() {
method length (line 20) | get length() {
method enqueue (line 29) | enqueue(data) {
method dequeue (line 47) | dequeue() {
method peekFirst (line 69) | peekFirst() {
method peekLast (line 81) | peekLast() {
method toArray (line 93) | toArray() {
method isEmpty (line 109) | isEmpty() {
FILE: Data-Structures/Queue/QueueUsing2Stacks.js
class Queue (line 4) | class Queue {
method constructor (line 5) | constructor() {
method enqueue (line 11) | enqueue(item) {
method dequeue (line 15) | dequeue() {
FILE: Data-Structures/Stack/EvaluateExpression.js
function evaluatePostfixExpression (line 8) | function evaluatePostfixExpression(expression) {
FILE: Data-Structures/Stack/Stack.js
class Stack (line 11) | class Stack {
method constructor (line 12) | constructor() {
method push (line 20) | push(value) {
method pop (line 26) | pop() {
method size (line 38) | size() {
method peek (line 43) | peek() {
method view (line 48) | view(output = (value) => console.log(value)) {
FILE: Data-Structures/Stack/StackES6.js
class Stack (line 12) | class Stack {
method constructor (line 13) | constructor() {
method push (line 19) | push(newValue) {
method pop (line 25) | pop() {
method length (line 34) | get length() {
method isEmpty (line 39) | get isEmpty() {
method last (line 44) | get last() {
method isStack (line 52) | static isStack(el) {
FILE: Data-Structures/Tree/AVLTree.js
function comparator (line 18) | function comparator() {
class AVLTree (line 34) | class AVLTree {
method constructor (line 35) | constructor(comp) {
method add (line 54) | add(_val) {
method find (line 65) | find(_val) {
method remove (line 77) | remove(_val) {
class Node (line 85) | class Node {
method constructor (line 86) | constructor(val) {
FILE: Data-Structures/Tree/BinarySearchTree.js
class Node (line 16) | class Node {
method constructor (line 17) | constructor(val) {
method search (line 24) | search(val) {
method visit (line 36) | visit(output = (value) => console.log(value)) {
method addNode (line 50) | addNode(n) {
method removeNode (line 67) | removeNode(val) {
class Tree (line 112) | class Tree {
method constructor (line 113) | constructor() {
method traverse (line 119) | traverse(output = (value) => console.log(value)) {
method search (line 128) | search(val) {
method addValue (line 141) | addValue(val) {
method removeValue (line 151) | removeValue(val) {
FILE: Data-Structures/Tree/SegmentTree.js
class SegmentTree (line 13) | class SegmentTree {
method constructor (line 16) | constructor(arr) {
method build (line 31) | build(arr) {
method update (line 48) | update(index, value) {
method query (line 68) | query(left, right) {
FILE: Data-Structures/Tree/Trie.js
class TrieNode (line 1) | class TrieNode {
method constructor (line 2) | constructor(key, parent) {
class Trie (line 14) | class Trie {
method constructor (line 15) | constructor() {
method findAllWords (line 21) | static findAllWords(root, word, output) {
method insert (line 36) | insert(word) {
method findPrefix (line 54) | findPrefix(word) {
method remove (line 67) | remove(word, count) {
method findAllWords (line 106) | findAllWords(prefix) {
method contains (line 116) | contains(word) {
method findOccurrences (line 123) | findOccurrences(word) {
FILE: Data-Structures/Vectors/Vector2.js
class Vector2 (line 8) | class Vector2 {
method constructor (line 9) | constructor(x, y) {
method equalsExactly (line 20) | equalsExactly(vector) {
method equalsApproximately (line 31) | equalsApproximately(vector, epsilon) {
method length (line 43) | length() {
method normalize (line 52) | normalize() {
method add (line 66) | add(vector) {
method subtract (line 78) | subtract(vector) {
method multiply (line 90) | multiply(scalar) {
method distance (line 102) | distance(vector) {
method dotProduct (line 113) | dotProduct(vector) {
method rotate (line 123) | rotate(angleInRadians) {
method angleBetween (line 137) | angleBetween(vector) {
FILE: Dynamic-Programming/FindMonthCalendar.js
class Month (line 8) | class Month {
method constructor (line 9) | constructor() {
method printCal (line 17) | printCal(days, startDay, output = (value) => console.log(value)) {
method parseDate (line 40) | parseDate(date) {
method isGreater (line 58) | isGreater(startDate, endDate) {
method getDayDiff (line 71) | getDayDiff(startDate, endDate) {
method generateMonthCal (line 100) | generateMonthCal(date) {
FILE: Dynamic-Programming/KadaneAlgo.js
function kadaneAlgo (line 12) | function kadaneAlgo(array) {
FILE: Dynamic-Programming/LevenshteinDistance.js
function minimum (line 10) | function minimum(a, b, c) {
function costOfSubstitution (line 20) | function costOfSubstitution(x, y) {
function calculateLevenshteinDp (line 25) | function calculateLevenshteinDp(x, y) {
FILE: Dynamic-Programming/LongestCommonSubsequence.js
function longestCommonSubsequence (line 30) | function longestCommonSubsequence(str1, str2) {
FILE: Dynamic-Programming/LongestIncreasingSubsequence.js
function longestIncreasingSubsequence (line 7) | function longestIncreasingSubsequence(x) {
FILE: Dynamic-Programming/MaxNonAdjacentSum.js
function maximumNonAdjacentSum (line 1) | function maximumNonAdjacentSum(nums) {
FILE: Dynamic-Programming/MaxProductOfThree.js
function maxProductOfThree (line 8) | function maxProductOfThree(arrayItems) {
FILE: Dynamic-Programming/NumberOfSubsetEqualToGivenSum.js
function NumberOfSubsetSum (line 9) | function NumberOfSubsetSum(array, sum) {
FILE: Dynamic-Programming/RodCutting.js
function rodCut (line 6) | function rodCut(prices, n) {
FILE: Dynamic-Programming/Shuf.js
function shuf (line 6) | function shuf(datasetSource, sampleSize) {
function fillBaseSample (line 19) | function fillBaseSample(datasetSource, sampleSize) {
function randomizeOutputFromDataset (line 61) | function randomizeOutputFromDataset(datasetSource, output) {
FILE: Dynamic-Programming/SieveOfEratosthenes.js
function sieveOfEratosthenes (line 8) | function sieveOfEratosthenes(n) {
FILE: Dynamic-Programming/Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js
function LongestSubstringWithoutRepeatingCharacters (line 13) | function LongestSubstringWithoutRepeatingCharacters(s) {
FILE: Dynamic-Programming/Sliding-Window/PermutationinString.js
function PermutationinString (line 15) | function PermutationinString(s1, s2) {
function equals (line 38) | function equals(a, b) {
function SetHash (line 42) | function SetHash() {
FILE: Dynamic-Programming/tests/MaxProductOfThree.test.js
function completeMaxThree (line 24) | function completeMaxThree(array) {
FILE: Geometry/Circle.js
class Circle (line 7) | class Circle {
method constructor (line 8) | constructor(radius) {
FILE: Geometry/Cone.js
class Cone (line 8) | class Cone {
method constructor (line 9) | constructor(baseRadius, height) {
FILE: Geometry/ConvexHullGraham.js
function compare (line 9) | function compare(a, b) {
function orientation (line 15) | function orientation(a, b, c) {
function convexHull (line 28) | function convexHull(points) {
FILE: Geometry/Pyramid.js
class Pyramid (line 8) | class Pyramid {
method constructor (line 9) | constructor(bsl, height) {
FILE: Geometry/Sphere.js
class Sphere (line 7) | class Sphere {
method constructor (line 8) | constructor(radius) {
FILE: Graphs/BellmanFord.js
function BellmanFord (line 28) | function BellmanFord(graph, V, E, src, dest) {
FILE: Graphs/BinaryLifting.js
class BinaryLifting (line 12) | class BinaryLifting {
method constructor (line 13) | constructor(root, tree) {
method addNode (line 24) | addNode(node) {
method addEdge (line 29) | addEdge(node1, node2) {
method dfs (line 41) | dfs(node, parent) {
method kthAncestor (line 56) | kthAncestor(node, k) {
function binaryLifting (line 72) | function binaryLifting(root, tree, queries) {
FILE: Graphs/BreadthFirstSearch.js
function breadthFirstSearch (line 12) | function breadthFirstSearch(graph, startingNode) {
FILE: Graphs/BreadthFirstShortestPath.js
function breadthFirstShortestPath (line 11) | function breadthFirstShortestPath(graph, startNode, targetNode) {
FILE: Graphs/ConnectedComponents.js
class GraphUnweightedUndirectedAdjacencyList (line 1) | class GraphUnweightedUndirectedAdjacencyList {
method constructor (line 3) | constructor() {
method addNode (line 7) | addNode(node) {
method addEdge (line 12) | addEdge(node1, node2) {
method DFSComponent (line 24) | DFSComponent(components, node, visited) {
method connectedComponents (line 42) | connectedComponents() {
FILE: Graphs/Density.js
function density (line 6) | function density(numberOfNodes, numberOfEdges, isDirected = false) {
FILE: Graphs/DepthFirstSearchIterative.js
class GraphUnweightedUndirected (line 1) | class GraphUnweightedUndirected {
method constructor (line 3) | constructor() {
method addNode (line 7) | addNode(node) {
method addEdge (line 12) | addEdge(node1, node2) {
method DFSIterative (line 24) | DFSIterative(node, value) {
FILE: Graphs/DepthFirstSearchRecursive.js
class GraphUnweightedUndirected (line 1) | class GraphUnweightedUndirected {
method constructor (line 3) | constructor() {
method addNode (line 7) | addNode(node) {
method addEdge (line 12) | addEdge(node1, node2) {
method DFSRecursive (line 24) | DFSRecursive(node, value, visited = new Set()) {
FILE: Graphs/Dijkstra.js
function createGraph (line 9) | function createGraph(V, E) {
function djikstra (line 23) | function djikstra(graph, V, src) {
FILE: Graphs/DijkstraSmallestPath.js
function solve (line 2) | function solve(graph, s) {
FILE: Graphs/Kosaraju.js
class Kosaraju (line 11) | class Kosaraju {
method constructor (line 12) | constructor(graph) {
method addNode (line 23) | addNode(node) {
method addEdge (line 30) | addEdge(node1, node2) {
method dfsTopoSort (line 42) | dfsTopoSort(node, visited) {
method topoSort (line 50) | topoSort() {
method dfsKosaraju (line 59) | dfsKosaraju(node, visited) {
method kosaraju (line 69) | kosaraju() {
function kosaraju (line 83) | function kosaraju(graph) {
FILE: Graphs/KruskalMST.js
class DisjointSetTreeNode (line 1) | class DisjointSetTreeNode {
method constructor (line 3) | constructor(key) {
class DisjointSetTree (line 10) | class DisjointSetTree {
method constructor (line 12) | constructor() {
method makeSet (line 17) | makeSet(x) {
method findSet (line 22) | findSet(x) {
method union (line 30) | union(x, y) {
method link (line 35) | link(x, y) {
class GraphWeightedUndirectedAdjacencyList (line 48) | class GraphWeightedUndirectedAdjacencyList {
method constructor (line 50) | constructor() {
method addNode (line 55) | addNode(node) {
method addEdge (line 61) | addEdge(node1, node2, weight) {
method KruskalMST (line 73) | KruskalMST() {
FILE: Graphs/LCABinaryLifting.js
class LCABinaryLifting (line 11) | class LCABinaryLifting extends BinaryLifting {
method constructor (line 12) | constructor(root, tree) {
method dfsDepth (line 19) | dfsDepth(node, parent) {
method getLCA (line 29) | getLCA(node1, node2) {
function lcaBinaryLifting (line 51) | function lcaBinaryLifting(root, tree, queries) {
FILE: Graphs/NodeNeighbors.js
class Graph (line 3) | class Graph {
method constructor (line 5) | constructor() {
method addEdge (line 9) | addEdge(node1, node2) {
method nodeNeighbors (line 17) | nodeNeighbors(node) {
FILE: Graphs/PrimMST.js
class GraphWeightedUndirectedAdjacencyList (line 2) | class GraphWeightedUndirectedAdjacencyList {
method constructor (line 4) | constructor() {
method addNode (line 8) | addNode(node) {
method addEdge (line 13) | addEdge(node1, node2, weight) {
method PrimMST (line 25) | PrimMST(start) {
FILE: Hashes/MD5.js
function chunkify (line 36) | function chunkify(array, size) {
function rotateLeft (line 54) | function rotateLeft(bits, turns) {
function u8ToU32 (line 64) | function u8ToU32(u8Array) {
function u32ToU8 (line 85) | function u32ToU8(u32Array) {
function padEnd (line 104) | function padEnd(u8Array, size) {
function preProcess (line 118) | function preProcess(message) {
function MD5 (line 153) | function MD5(message) {
FILE: Hashes/SHA1.js
constant CHAR_SIZE (line 9) | const CHAR_SIZE = 8
function pad (line 21) | function pad(str, bits) {
function chunkify (line 39) | function chunkify(str, size) {
function rotateLeft (line 57) | function rotateLeft(bits, turns) {
function preProcess (line 67) | function preProcess(message) {
function SHA1 (line 98) | function SHA1(message) {
FILE: Hashes/SHA256.js
constant CHAR_SIZE (line 9) | const CHAR_SIZE = 8
function pad (line 35) | function pad(str, bits) {
function chunkify (line 53) | function chunkify(str, size) {
function rotateRight (line 71) | function rotateRight(bits, turns) {
function preProcess (line 81) | function preProcess(message) {
function SHA256 (line 112) | function SHA256(message) {
FILE: Hashes/tests/MD5.test.js
function hexMD5 (line 9) | function hexMD5(message) {
FILE: Maths/AliquotSum.js
function aliquotSum (line 14) | function aliquotSum(input) {
FILE: Maths/CircularArc.js
function circularArcLength (line 12) | function circularArcLength(radius, degrees) {
function circularArcArea (line 24) | function circularArcArea(radius, degrees) {
FILE: Maths/CollatzSequence.js
function collatz (line 16) | function collatz(n) {
FILE: Maths/DecimalExpansion.js
function decExp (line 23) | function decExp(a, b, base = 10, exp = [], d = {}, dlen = 0) {
FILE: Maths/EulerMethod.js
function eulerStep (line 11) | function eulerStep(xCurrent, stepSize, yCurrent, differentialEquation) {
function eulerFull (line 16) | function eulerFull(
FILE: Maths/ExponentialFunction.js
function exponentialFunction (line 9) | function exponentialFunction(power, n) {
FILE: Maths/FareyApproximation.js
function fareyApproximation (line 28) | function fareyApproximation(decimal, repeat = 20) {
FILE: Maths/FindMaxRecursion.js
function findMaxRecursion (line 17) | function findMaxRecursion(arr, left, right) {
FILE: Maths/FriendlyNumbers.js
function abundancyIndex (line 26) | function abundancyIndex(number) {
function sumDivisors (line 30) | function sumDivisors(number) {
FILE: Maths/GetEuclidGCD.js
function CheckInput (line 1) | function CheckInput(a, b) {
function GetEuclidGCD (line 13) | function GetEuclidGCD(a, b) {
function GetEuclidGCDRecursive (line 31) | function GetEuclidGCDRecursive(a, b) {
FILE: Maths/JugglerSequence.js
function jugglerSequence (line 13) | function jugglerSequence(n) {
FILE: Maths/LucasSeries.js
function lucas (line 16) | function lucas(index) {
FILE: Maths/Mandelbrot.js
function getRGBData (line 30) | function getRGBData(
function blackAndWhiteColorMap (line 83) | function blackAndWhiteColorMap(distance) {
function colorCodedColorMap (line 95) | function colorCodedColorMap(distance) {
function getDistance (line 140) | function getDistance(figureX, figureY, maxStep) {
FILE: Maths/MeanAbsoluteDeviation.js
function meanAbsoluteDeviation (line 9) | function meanAbsoluteDeviation(data) {
FILE: Maths/MidpointIntegration.js
function integralEvaluation (line 20) | function integralEvaluation(N, a, b, func) {
FILE: Maths/ModularArithmetic.js
class ModRing (line 10) | class ModRing {
method constructor (line 11) | constructor(MOD) {
FILE: Maths/Polynomial.js
class Polynomial (line 11) | class Polynomial {
method constructor (line 12) | constructor(array) {
method construct (line 21) | construct() {
method display (line 44) | display() {
method evaluate (line 52) | evaluate(value) {
FILE: Maths/ShorsAlgorithm.js
function ShorsAlgorithm (line 25) | function ShorsAlgorithm(num) {
function findP (line 64) | function findP(A, B) {
function isValidP (line 78) | function isValidP(A, B, p) {
function gcd (line 90) | function gcd(A, B) {
FILE: Maths/SieveOfEratosthenes.js
function sieveOfEratosthenes (line 13) | function sieveOfEratosthenes(max) {
FILE: Maths/Signum.js
function signum (line 17) | function signum(input) {
FILE: Maths/SimpsonIntegration.js
function integralEvaluation (line 24) | function integralEvaluation(N, a, b, func) {
FILE: Maths/SquareRoot.js
function sqrt (line 9) | function sqrt(num, precision = 4) {
FILE: Maths/SumOfDigits.js
function sumOfDigitsUsingString (line 12) | function sumOfDigitsUsingString(number) {
function sumOfDigitsUsingLoop (line 25) | function sumOfDigitsUsingLoop(number) {
function sumOfDigitsUsingRecursion (line 40) | function sumOfDigitsUsingRecursion(number) {
FILE: Maths/SumOfGeometricProgression.js
function sumOfGeometricProgression (line 19) | function sumOfGeometricProgression(firstTerm, commonRatio, numOfTerms) {
FILE: Maths/isPalindromeIntegerNumber.js
function isPalindromeIntegerNumber (line 9) | function isPalindromeIntegerNumber(x) {
FILE: Maths/test/EulerMethod.manual-test.js
function plotLine (line 3) | function plotLine(label, points, width, height) {
function exampleEquation1 (line 38) | function exampleEquation1(x, y) {
function exampleEquation2 (line 43) | function exampleEquation2(x, y) {
function exampleEquation3 (line 48) | function exampleEquation3(x, y) {
FILE: Maths/test/WhileLoopFactorial.test.js
function testFactorial (line 3) | function testFactorial(n, expected) {
FILE: Maths/test/ZellersCongruenceAlgorithm.test.js
function testZeller (line 3) | function testZeller(day, month, year, expected) {
FILE: Project-Euler/Problem002.js
constant SQ5 (line 2) | const SQ5 = 5 ** 0.5 // Square root of 5
constant PHI (line 3) | const PHI = (1 + SQ5) / 2 // definition of PHI
FILE: Project-Euler/Problem011.js
function largestProductInAGrid (line 32) | function largestProductInAGrid(arr) {
function get (line 53) | function get(arr, y, x) {
FILE: Project-Euler/Problem013.js
function largeSum (line 5) | function largeSum(bignum) {
FILE: Project-Euler/Problem019.js
function problem19 (line 21) | function problem19() {
FILE: Project-Euler/Problem021.js
function problem21 (line 17) | function problem21(n) {
FILE: Project-Euler/Problem023.js
function sumOfNonAbundantNumbers (line 22) | function sumOfNonAbundantNumbers(n = 28123) {
function isAbundant (line 54) | function isAbundant(number) {
FILE: Project-Euler/Problem025.js
function fibonacciIndex (line 31) | function fibonacciIndex(t = 1000) {
FILE: Project-Euler/Problem028.js
function problem28 (line 20) | function problem28(dim) {
FILE: Project-Euler/Problem035.js
function problem35 (line 14) | function problem35(n) {
FILE: Project-Euler/Problem044.js
function problem44 (line 14) | function problem44(k) {
function isPentagonal (line 40) | function isPentagonal(n) {
FILE: Recursive/FloodFill.js
function isInside (line 23) | function isInside(rgbData, location) {
function checkLocation (line 29) | function checkLocation(rgbData, location) {
function breadthFirstSearch (line 52) | function breadthFirstSearch(
function depthFirstSearch (line 76) | function depthFirstSearch(
function breadthFirstFill (line 96) | function breadthFirstFill(
function depthFirstFill (line 122) | function depthFirstFill(rgbData, location, targetColor, replacementColor) {
FILE: Recursive/KochSnowflake.js
class Vector2 (line 17) | class Vector2 {
method constructor (line 18) | constructor(x, y) {
method add (line 29) | add(vector) {
method subtract (line 41) | subtract(vector) {
method multiply (line 53) | multiply(scalar) {
method rotate (line 65) | rotate(angleInDegrees) {
function iterate (line 84) | function iterate(initialVectors, steps) {
function iterationStep (line 102) | function iterationStep(vectors) {
FILE: Recursive/KochSnowflake.manual-test.js
function getKochSnowflake (line 10) | function getKochSnowflake(canvasWidth = 600, steps = 5) {
function drawToCanvas (line 40) | function drawToCanvas(vectors, canvasWidth, canvasHeight) {
FILE: Recursive/TowerOfHanoi.js
function TowerOfHanoi (line 4) | function TowerOfHanoi(n, from, to, aux, output = []) {
FILE: Recursive/test/FloodFill.test.js
function testBreadthFirst (line 46) | function testBreadthFirst(
function testDepthFirst (line 66) | function testDepthFirst(
function generateTestRgbData (line 82) | function generateTestRgbData() {
FILE: Search/BinarySearch.js
function binarySearchRecursive (line 10) | function binarySearchRecursive(arr, x, low = 0, high = arr.length - 1) {
function binarySearchIterative (line 31) | function binarySearchIterative(arr, x, low = 0, high = arr.length - 1) {
FILE: Search/ExponentialSearch.js
function binarySearch (line 12) | function binarySearch(arr, value, floor, ceiling) {
function exponentialSearch (line 34) | function exponentialSearch(arr, length, value) {
FILE: Search/InterpolationSearch.js
function interpolationSearch (line 12) | function interpolationSearch(arr, key) {
FILE: Search/LinearSearch.js
function SearchArray (line 9) | function SearchArray(searchNum, ar, output = (v) => console.log(v)) {
function Search (line 19) | function Search(theArray, key) {
FILE: Search/QuickSelectSearch.js
function quickSelectSearch (line 14) | function quickSelectSearch(array, k) {
FILE: Search/RabinKarp.js
constant BASE (line 16) | const BASE = 256 // The number of characters in the alphabet
constant MOD (line 17) | const MOD = 997 // A prime number used for the hash function
function rabinKarpSearch (line 19) | function rabinKarpSearch(text, pattern) {
function hash (line 56) | function hash(str, length) {
FILE: Search/SlidingWindow.js
function slidingWindow (line 23) | function slidingWindow(arr, num) {
FILE: Search/StringSearch.js
function makeTable (line 5) | function makeTable(str) {
function stringSearch (line 38) | function stringSearch(str, word) {
FILE: Search/TernarySearch.js
function ternarySearchRecursive (line 14) | function ternarySearchRecursive(arr, key, low = 0, high = arr.length - 1) {
function ternarySearchIterative (line 50) | function ternarySearchIterative(arr, key, low = 0, high = arr.length - 1) {
FILE: Search/UnionFind.js
function UnionFind (line 17) | function UnionFind(n, key) {
FILE: Sliding-Windows/LongestSubarrayWithSumAtMost.js
function longestSubarrayWithSumAtMost (line 8) | function longestSubarrayWithSumAtMost(arr, target) {
FILE: Sliding-Windows/MaxSumSubarrayFixed.js
function maxSumSubarrayFixed (line 9) | function maxSumSubarrayFixed(arr, k) {
FILE: Sorts/BeadSort.js
function beadSort (line 11) | function beadSort(sequence) {
FILE: Sorts/BinaryInsertionSort.js
function binarySearch (line 21) | function binarySearch(array, key, start, end) {
function binaryInsertionSort (line 51) | function binaryInsertionSort(array) {
FILE: Sorts/BogoSort.js
function isSorted (line 4) | function isSorted(array) {
function shuffle (line 17) | function shuffle(array) {
function bogoSort (line 33) | function bogoSort(items) {
FILE: Sorts/BubbleSort.js
function bubbleSort (line 19) | function bubbleSort(items) {
function alternativeBubbleSort (line 46) | function alternativeBubbleSort(arr) {
FILE: Sorts/BucketSort.js
function bucketSort (line 20) | function bucketSort(list, size) {
FILE: Sorts/CocktailShakerSort.js
function cocktailShakerSort (line 11) | function cocktailShakerSort(items) {
FILE: Sorts/CombSort.js
function combSort (line 25) | function combSort(list) {
FILE: Sorts/CycleSort.js
function cycleSort (line 17) | function cycleSort(list) {
FILE: Sorts/DutchNationalFlagSort.js
function dutchNationalFlagSort (line 10) | function dutchNationalFlagSort(nums) {
FILE: Sorts/FlashSort.js
function flashSort (line 9) | function flashSort(arr) {
FILE: Sorts/GnomeSort.js
function gnomeSort (line 6) | function gnomeSort(items) {
FILE: Sorts/HeapSort.js
function heapSort (line 36) | function heapSort(items) {
FILE: Sorts/HeapSortV2.js
function heapRoot (line 5) | function heapRoot(input, i) {
function swap (line 24) | function swap(input, indexA, indexB) {
function heapSort (line 28) | function heapSort(input) {
FILE: Sorts/InsertionSort.js
function insertionSort (line 8) | function insertionSort(unsortedList) {
function insertionSortAlternativeImplementation (line 41) | function insertionSortAlternativeImplementation(array) {
FILE: Sorts/IntroSort.js
function introsort (line 18) | function introsort(array, compare) {
function demo1 (line 250) | function demo1() {
function demo2 (line 282) | function demo2() {
FILE: Sorts/MergeSort.js
function merge (line 18) | function merge(list1, list2) {
function mergeSort (line 40) | function mergeSort(list) {
FILE: Sorts/OddEvenSort.js
function swap (line 10) | function swap(arr, i, j) {
function oddEvenSort (line 16) | function oddEvenSort(arr) {
FILE: Sorts/PancakeSort.js
function flipArray (line 29) | function flipArray(array, startIndex, endIndex) {
function findMax (line 52) | function findMax(array, startIndex, endIndex) {
function pancakeSort (line 70) | function pancakeSort(array) {
FILE: Sorts/PigeonHoleSort.js
function pigeonHoleSort (line 9) | function pigeonHoleSort(arr) {
FILE: Sorts/QuickSort.js
function quickSort (line 8) | function quickSort(items) {
FILE: Sorts/RadixSort.js
function radixSort (line 7) | function radixSort(items, RADIX) {
FILE: Sorts/ShellSort.js
function shellSort (line 6) | function shellSort(items) {
FILE: Sorts/StoogeSort.js
function stoogeSort (line 7) | function stoogeSort(items, leftEnd, rightEnd) {
FILE: Sorts/SwapSort.js
function minSwapsToSort (line 11) | function minSwapsToSort(items) {
FILE: Sorts/TopologicalSort.js
function TopologicalSorter (line 1) | function TopologicalSorter() {
FILE: String/DiceCoefficient.js
function mapBigrams (line 11) | function mapBigrams(string) {
function countCommonBigrams (line 23) | function countCommonBigrams(bigrams, string) {
function diceCoefficient (line 33) | function diceCoefficient(stringA, stringB) {
FILE: String/IsPalindrome.js
function isPalindromeIterative (line 19) | function isPalindromeIterative(x) {
FILE: String/ReverseString.js
function ReverseStringIterative (line 4) | function ReverseStringIterative(string) {
FILE: String/ZFunction.js
function zFunction (line 11) | function zFunction(text) {
FILE: Timing-Functions/IntervalTimer.js
class IntervalTimer (line 8) | class IntervalTimer {
method constructor (line 15) | constructor(interval = 10, callBack = () => {}) {
method startTimer (line 29) | startTimer() {
method resetTimer (line 37) | resetTimer() {
method getElapsedTime (line 46) | getElapsedTime(offset = 0) {
method getRunTime (line 55) | getRunTime() {
FILE: Timing-Functions/ParseDate.js
function checkDate (line 3) | function checkDate(date) {
function parseDate (line 9) | function parseDate(dateString) {
FILE: Trees/BreadthFirstTreeTraversal.js
class Node (line 6) | class Node {
method constructor (line 7) | constructor(data) {
class BinaryTree (line 14) | class BinaryTree {
method constructor (line 15) | constructor() {
method breadthFirstIterative (line 19) | breadthFirstIterative() {
method breadthFirstRecursive (line 37) | breadthFirstRecursive() {
method getHeight (line 47) | getHeight(node) {
method traverseLevel (line 56) | traverseLevel(node, levelRemaining, traversal) {
FILE: Trees/DepthFirstSearch.js
function traverseDFS (line 8) | function traverseDFS(tree, rootValue) {
function searchDFS (line 27) | function searchDFS(tree, value) {
FILE: Trees/FenwickTree.js
class FenwickTree (line 7) | class FenwickTree {
method constructor (line 8) | constructor(feneickArray, array, n) {
method update (line 17) | update(feneickArray, n, index, value) {
method getPrefixSum (line 25) | getPrefixSum(feneickArray, index) {
Condensed preview — 751 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,065K chars).
[
{
"path": ".github/CODEOWNERS",
"chars": 13,
"preview": "* @appgurueu\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.yml",
"chars": 1409,
"preview": "name: Bug report\ndescription: 'Create a report to help us improve'\ntitle: '[BUG]: '\nlabels: ['bug']\nbody:\n - type: mark"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 203,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: Discord community\n url: https://the-algorithms.com/discord/\n "
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.yml",
"chars": 1297,
"preview": "name: Feature request\ndescription: 'Suggest features, propose improvements, discuss new ideas'\ntitle: '[FEATURE]: '\nlabe"
},
{
"path": ".github/ISSUE_TEMPLATE/other.yml",
"chars": 555,
"preview": "name: Other issue\ndescription: Use this for any other issues. Do NOT create blank issues\ntitle: \"[OTHER]: \"\nlabels: [\"aw"
},
{
"path": ".github/dependabot.yml",
"chars": 295,
"preview": "# Keep GitHub Actions up to date with Dependabot...\n# https://docs.github.com/en/code-security/dependabot/working-with-d"
},
{
"path": ".github/pull_request_template.md",
"chars": 1220,
"preview": "[](https://gitpod.io/from-referrer/) [know more](http"
},
{
"path": ".github/stale.yml",
"chars": 848,
"preview": "# Number of days of inactivity before an issue becomes stale (2 weeks)\ndaysUntilStale: 14\n# Number of days of inactivity"
},
{
"path": ".github/workflows/Ci.yml",
"chars": 803,
"preview": "name: Continuous Integration\n\non:\n push:\n branches:\n - master\n pull_request:\n\njobs:\n build:\n name: Code st"
},
{
"path": ".github/workflows/UpdateDirectory.js",
"chars": 1793,
"preview": "import path from 'path'\nimport fs from 'fs'\nimport { globby } from 'globby'\n\nfunction pathPrefix (i) {\n const res = ' "
},
{
"path": ".github/workflows/UpdateDirectory.yml",
"chars": 982,
"preview": "# This GitHub Action updates the DIRECTORY.md file (if needed) when doing a git push\nname: Update Directory\n\non:\n push:"
},
{
"path": ".github/workflows/UploadCoverageReport.yml",
"chars": 1091,
"preview": "---\nname: UploadCoverageReport\n\n'on':\n workflow_dispatch:\n push:\n branches:\n - master\n pull_request:\n\nenv:\n "
},
{
"path": ".gitignore",
"chars": 227,
"preview": "# dependencies\n/node_modules\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\n"
},
{
"path": ".gitpod.yml",
"chars": 180,
"preview": "github:\n prebuilds:\n addBadge: true\n addComment: false\n addCheck: false\n master: true\n branches: true\n "
},
{
"path": ".husky/pre-commit",
"chars": 75,
"preview": "#!/bin/sh\n. \"$(dirname \"$0\")/_/husky.sh\"\n\nnpm run check-style\nnpm run test\n"
},
{
"path": ".prettierignore",
"chars": 21,
"preview": ".github\nDIRECTORY.md\n"
},
{
"path": ".prettierrc",
"chars": 308,
"preview": "{\n \"arrowParens\": \"always\",\n \"bracketSpacing\": true,\n \"endOfLine\": \"lf\",\n \"insertPragma\": false,\n \"printWidth\": 80,"
},
{
"path": "Backtracking/AllCombinationsOfSizeK.js",
"chars": 683,
"preview": "function generateCombinations(n, k) {\n let currentCombination = []\n let allCombinations = [] // will be used for stori"
},
{
"path": "Backtracking/GeneratePermutations.js",
"chars": 851,
"preview": "/*\n * Problem Statement: Generate all distinct permutations of an array (all permutations should be in sorted order);\n *"
},
{
"path": "Backtracking/KnightTour.js",
"chars": 1927,
"preview": "// Wikipedia: https://en.wikipedia.org/wiki/Knight%27s_tour\n\nclass OpenKnightTour {\n constructor(size) {\n // Constru"
},
{
"path": "Backtracking/MColoringProblem.js",
"chars": 1303,
"preview": "/**\n * Colors a graph using up to m colors such that no two adjacent vertices share the same color.\n * @param {number[]["
},
{
"path": "Backtracking/NQueens.js",
"chars": 1464,
"preview": "class NQueens {\n constructor(size) {\n if (size < 0) {\n throw RangeError('Invalid board size')\n }\n this.bo"
},
{
"path": "Backtracking/RatInAMaze.js",
"chars": 3815,
"preview": "/*\n * Problem Statement:\n * - Given a NxN grid, find whether rat in cell [0, 0] can reach the target in cell [N-1, N-1]\n"
},
{
"path": "Backtracking/Sudoku.js",
"chars": 2102,
"preview": "class Sudoku {\n // Sudoku Class to hold the board and related functions\n constructor(board) {\n this.board = board\n "
},
{
"path": "Backtracking/SumOfSubset.js",
"chars": 2136,
"preview": "/*\n *\n * Sum of Subset problem\n *\n * Given an ordered set W of non-negative integers and a value K,\n * determine all "
},
{
"path": "Backtracking/generateParentheses.js",
"chars": 810,
"preview": "/**\n * Problem Statement: Given a number n pairs of parentheses, try to Generate all combinations of valid parentheses;\n"
},
{
"path": "Backtracking/tests/AllCombinationsOfSizeK.test.js",
"chars": 539,
"preview": "import { generateCombinations } from '../AllCombinationsOfSizeK'\n\ndescribe('AllCombinationsOfSizeK', () => {\n it('shoul"
},
{
"path": "Backtracking/tests/GenerateParentheses.test.js",
"chars": 246,
"preview": "import { generateParentheses } from '../generateParentheses'\n\ntest('generate all valid parentheses of input 3', () => {\n"
},
{
"path": "Backtracking/tests/GeneratePermutations.test.js",
"chars": 1175,
"preview": "import { factorial } from '../../Recursive/Factorial'\nimport { permutations } from '../GeneratePermutations'\n\ndescribe('"
},
{
"path": "Backtracking/tests/KnightTour.test.js",
"chars": 760,
"preview": "import { OpenKnightTour } from '../KnightTour'\n\ndescribe('OpenKnightTour', () => {\n it('OpenKnightTour(5)', () => {\n "
},
{
"path": "Backtracking/tests/MColoringProblem.test.js",
"chars": 514,
"preview": "import { mColoring } from '../MColoringProblem'\n\ndescribe('MColoringProblem', () => {\n it('should color a triangle with"
},
{
"path": "Backtracking/tests/NQueens.test.js",
"chars": 555,
"preview": "import { NQueens } from '../NQueens'\n\ndescribe('NQueens', () => {\n it('should return 2 solutions for 4x4 size board', ("
},
{
"path": "Backtracking/tests/RatInAMaze.test.js",
"chars": 2688,
"preview": "import { RatInAMaze } from '../RatInAMaze'\n\ndescribe('RatInAMaze', () => {\n it('should fail for non-arrays', () => {\n "
},
{
"path": "Backtracking/tests/Sudoku.test.js",
"chars": 1456,
"preview": "import { Sudoku } from '../Sudoku'\n\nconst data = [\n [3, 0, 6, 5, 0, 8, 4, 0, 0],\n [5, 2, 0, 0, 0, 0, 0, 0, 0],\n [0, 8"
},
{
"path": "Backtracking/tests/SumOfSubset.test.js",
"chars": 402,
"preview": "import { sumOfSubset } from '../SumOfSubset'\n\ndescribe('SumOfSubset', () => {\n it('should return the subsets that add u"
},
{
"path": "Bit-Manipulation/BinaryCountSetBits.js",
"chars": 664,
"preview": "/*\n author: vivek9patel\n license: GPL-3.0 or later\n\n This script will find number of 1's\n in binary represen"
},
{
"path": "Bit-Manipulation/GenerateSubSets.js",
"chars": 1001,
"preview": "/**\n * @function generateSubSets\n * @param {Array} inputArray\n * @returns {Array}\n * @example [1,2] -> [[],[1],[2],[1,2]"
},
{
"path": "Bit-Manipulation/GrayCodes.js",
"chars": 1502,
"preview": "/**\n * Generates a Gray code sequence for the given number of bits.\n * @param {number} n - The number of bits in the Gra"
},
{
"path": "Bit-Manipulation/IsPowerOfTwo.js",
"chars": 933,
"preview": "/*\n author: @Aayushi-Mittal\n\n This script will check whether the given\n number is a power of two or not.\n\n A"
},
{
"path": "Bit-Manipulation/IsPowerofFour.js",
"chars": 693,
"preview": "/**\n * @author : dev-madhurendra\n * Checks whether the given number is a power of four or not.\n *\n * A number is conside"
},
{
"path": "Bit-Manipulation/LogTwo.js",
"chars": 302,
"preview": "/**\n * https://handwiki.org/wiki/Binary_logarithm\n * Approximate log2 using only bitwise operators\n * @param {number} n\n"
},
{
"path": "Bit-Manipulation/NextPowerOfTwo.js",
"chars": 345,
"preview": "/**\n *\n * This script will find next power of two\n * of given number.\n * More about it:\n * https://www.techiedeli"
},
{
"path": "Bit-Manipulation/SetBit.js",
"chars": 874,
"preview": "/*\n * Setting Bit: https://www.geeksforgeeks.org/set-k-th-bit-given-number/\n *\n * To set any bit we use bitwise OR (|) o"
},
{
"path": "Bit-Manipulation/UniqueElementInAnArray.js",
"chars": 406,
"preview": "/**\n * Finds the unique element in an array where all other elements are repeated twice.\n *\n * @param {number[]} arr - T"
},
{
"path": "Bit-Manipulation/test/BinaryCountSetBits.test.js",
"chars": 988,
"preview": "import { BinaryCountSetBits } from '../BinaryCountSetBits'\n\ntest('check BinaryCountSetBits of 25 is 3', () => {\n const "
},
{
"path": "Bit-Manipulation/test/GenerateSubSets.test.js",
"chars": 851,
"preview": "import { generateSubSets } from '../GenerateSubSets'\n\ndescribe('subSets', () => {\n it('find the subsets', () => {\n e"
},
{
"path": "Bit-Manipulation/test/GrayCodes.test.js",
"chars": 516,
"preview": "import { generateGrayCodes } from '../GrayCodes.js'\n\ndescribe('Gray codes', () => {\n test.each([\n [0, [0b0]],\n [1"
},
{
"path": "Bit-Manipulation/test/IsPowerOfFour.test.js",
"chars": 321,
"preview": "import { isPowerOfFour } from '../IsPowerofFour'\n\ndescribe('IsPowerOfFour', () => {\n it.each([\n [0, false],\n [4, "
},
{
"path": "Bit-Manipulation/test/IsPowerOfTwo.test.js",
"chars": 611,
"preview": "import { IsPowerOfTwo } from '../IsPowerOfTwo'\n\ntest('Check if 0 is a power of 2 or not:', () => {\n const res = IsPower"
},
{
"path": "Bit-Manipulation/test/LogTwo.test.js",
"chars": 162,
"preview": "import { logTwo } from '../LogTwo'\n\nfor (let i = 1; i < 100; i++) {\n test('log2(' + i + ')', () => {\n expect(logTwo("
},
{
"path": "Bit-Manipulation/test/NextPowerOfTwo.test.js",
"chars": 433,
"preview": "import { nextPowerOfTwo } from '../NextPowerOfTwo'\n\ndescribe('NextPowerOfTwo', () => {\n it.each`\n input | result\n"
},
{
"path": "Bit-Manipulation/test/SetBit.test.js",
"chars": 457,
"preview": "import { setBit } from '../SetBit'\n\ntest('Set bit number 0 in 1:', () => {\n const setBitPos = setBit(1, 0)\n expect(set"
},
{
"path": "Bit-Manipulation/test/UniqueElementInAnArray.test.js",
"chars": 314,
"preview": "import { findUniqueElement } from '../UniqueElementInAnArray'\n\ndescribe('UniqueElementInAnArray', () => {\n it.each([\n "
},
{
"path": "CONTRIBUTING.md",
"chars": 6777,
"preview": "# Contributing guidelines\n\n## Before contributing\n\nWelcome to [TheAlgorithms/JavaScript](https://github.com/TheAlgorithm"
},
{
"path": "Cache/LFUCache.js",
"chars": 5841,
"preview": "class CacheNode {\n constructor(key, value, frequency) {\n this.key = key\n this.value = value\n this.frequency = "
},
{
"path": "Cache/LRUCache.js",
"chars": 2753,
"preview": "class LRUCache {\n // LRU Cache to store a given capacity of data\n #capacity\n\n /**\n * @param {number} capacity - the"
},
{
"path": "Cache/Memoize.js",
"chars": 2059,
"preview": "/**\n * @function memoize\n * @description ->\n * From [Wikipedia](https://en.wikipedia.org/wiki/Memoization),\n * memoizati"
},
{
"path": "Cache/test/LFUCache.test.js",
"chars": 2237,
"preview": "import LFUCache from '../LFUCache'\nimport { fibonacciCache } from './cacheTest'\n\ndescribe('Testing LFUCache class', () ="
},
{
"path": "Cache/test/LRUCache.test.js",
"chars": 1791,
"preview": "import LRUCache from '../LRUCache'\nimport { fibonacciCache } from './cacheTest'\n\ndescribe('Testing LRUCache', () => {\n "
},
{
"path": "Cache/test/Memoize.test.js",
"chars": 2415,
"preview": "import { memoize } from '../Memoize'\nimport { union } from './cacheTest'\nimport { fibonacci } from '../../Dynamic-Progra"
},
{
"path": "Cache/test/cacheTest.js",
"chars": 725,
"preview": "/**\n * @function fibonacciCache\n * @description - this is a cached variant of fib number\n * @param {number} n - Real nu"
},
{
"path": "Cellular-Automata/ConwaysGameOfLife.js",
"chars": 2227,
"preview": "/*\nConway's Game of Life\nThe Game of Life is a cellular automaton devised by the British mathematician John Horton Conwa"
},
{
"path": "Cellular-Automata/Elementary.js",
"chars": 7065,
"preview": "/**\n * Author: Jacoby Johnson (cobyj33)\n *\n * Generates generations of Elementary 1D cellular automata\n *\n * Wikipedia: "
},
{
"path": "Cellular-Automata/test/ConwaysGameOfLife.test.js",
"chars": 342,
"preview": "import { newGeneration } from '../ConwaysGameOfLife'\n\ndescribe('newGeneration', () => {\n it('should produce the next ge"
},
{
"path": "Cellular-Automata/test/Elementary.test.js",
"chars": 4379,
"preview": "import { getNextElementaryGeneration } from '../Elementary'\n\ndescribe('Elementary Cellular Automata', () => {\n describe"
},
{
"path": "Ciphers/AffineCipher.js",
"chars": 2901,
"preview": "/**\n * @description - The affine cipher is a type of monoalphabetic substitution cipher, where each letter in an alphabe"
},
{
"path": "Ciphers/Atbash.js",
"chars": 842,
"preview": "/**\n * @function Atbash - Decrypt a Atbash cipher\n * @description - The Atbash cipher is a particular type of monoalphab"
},
{
"path": "Ciphers/CaesarCipher.js",
"chars": 1453,
"preview": "/**\n * @function caesarsCipher\n * @description - In cryptography, a Caesar cipher, also known as Caesar's cipher, the sh"
},
{
"path": "Ciphers/KeyFinder.js",
"chars": 4767,
"preview": "/**\n * Find and retrieve the encryption key automatically.\n * @param {string} str - The input encrypted string.\n * @retu"
},
{
"path": "Ciphers/KeywordShiftedAlphabet.js",
"chars": 2836,
"preview": "/**\n * Keyword shifted alphabet is a simple cipher using a translation table created with a help of a keyword.\n * Keywor"
},
{
"path": "Ciphers/MorseCode.js",
"chars": 1837,
"preview": "/**\n * @author mrmagic2020\n * @description Enciphers a combination of letters, numbers and symbols into morse code.\n * @"
},
{
"path": "Ciphers/ROT13.js",
"chars": 1118,
"preview": "/**\n * @function ROT13\n * @description - ROT13 (\"rotate by 13 places\", sometimes hyphenated ROT-13) is a simple letter s"
},
{
"path": "Ciphers/VigenereCipher.js",
"chars": 2222,
"preview": "/**\n * Check if the Character is letter or not\n * @param {String} str - character to check\n * @return {object} An array "
},
{
"path": "Ciphers/XORCipher.js",
"chars": 649,
"preview": "/**\n * @function XORCipher\n * @description - Encrypt using an XOR cipher\n * The XOR cipher is a type of additive cipher."
},
{
"path": "Ciphers/test/AffineCipher.test.js",
"chars": 1216,
"preview": "import { encrypt, decrypt } from '../AffineCipher'\n\ndescribe('Test Affine Cipher', () => {\n it('Test - 1, Pass invalid "
},
{
"path": "Ciphers/test/Atbash.test.js",
"chars": 607,
"preview": "import Atbash from '../Atbash'\n\ndescribe('Testing Atbash function', () => {\n it('Test - 1, passing a non-string as an a"
},
{
"path": "Ciphers/test/CaesarCipher.test.js",
"chars": 826,
"preview": "import caesarCipher from '../CaesarCipher'\n\ndescribe('Testing the caesarsCipher function', () => {\n it('Test - 1, Testi"
},
{
"path": "Ciphers/test/KeywordShiftedAlphabet.test.js",
"chars": 449,
"preview": "import { encrypt, decrypt } from '../KeywordShiftedAlphabet'\n\ntest('Hello world! === decrypt(encrypt(Hello world!))', ()"
},
{
"path": "Ciphers/test/MorseCode.test.js",
"chars": 719,
"preview": "import { morse } from '../MorseCode'\n\ndescribe('Testing morse function', () => {\n it('should return an enciphered strin"
},
{
"path": "Ciphers/test/ROT13.test.js",
"chars": 773,
"preview": "import ROT13 from '../ROT13'\n\ndescribe('Testing ROT13 function', () => {\n it('Test - 1, passing a non-string as an argu"
},
{
"path": "Ciphers/test/VigenereCipher.test.js",
"chars": 429,
"preview": "import { encrypt, decrypt } from '../VigenereCipher'\n\ntest('Hello world! === decrypt(encrypt(Hello world!))', () => {\n "
},
{
"path": "Ciphers/test/XORCipher.test.js",
"chars": 712,
"preview": "import XORCipher from '../XORCipher'\n\ndescribe('Testing XORCipher function', () => {\n it('Test - 1, passing a non-strin"
},
{
"path": "Compression/RLE.js",
"chars": 893,
"preview": "/*\n * RLE (Run Length Encoding) is a simple form of data compression.\n * The basic idea is to represent repeated success"
},
{
"path": "Compression/test/RLE.test.js",
"chars": 437,
"preview": "import { Compress, Decompress } from '../RLE'\n\ndescribe('Test RLE Compressor/Decompressor', () => {\n it('Test - 1, Pass"
},
{
"path": "Conversions/ArbitraryBase.js",
"chars": 3999,
"preview": "/**\n * Divide two numbers and get the result of floor division and remainder\n * @param {number} dividend\n * @param {numb"
},
{
"path": "Conversions/ArrayBufferToBase64.js",
"chars": 1578,
"preview": "// About base64: https://en.wikipedia.org/wiki/Base64\n\n/**\n * Converts an array of bytes to base64 encoding\n * @param {A"
},
{
"path": "Conversions/Base64ToArrayBuffer.js",
"chars": 1933,
"preview": "// About base64: https://en.wikipedia.org/wiki/Base64\n\n/**\n * Converts a base64 string to an array of bytes\n * @param {s"
},
{
"path": "Conversions/BinaryToDecimal.js",
"chars": 374,
"preview": "export default function binaryToDecimal(binaryString) {\n let decimalNumber = 0\n const binaryDigits = binaryString.spli"
},
{
"path": "Conversions/BinaryToHex.js",
"chars": 1717,
"preview": "const pad = (num, padlen) => {\n const pad = new Array(1 + padlen).join(0)\n return (pad + num).slice(-pad.length)\n}\n\nco"
},
{
"path": "Conversions/DateDayDifference.js",
"chars": 1000,
"preview": "/*\n DateDayDifference Method\n ------------------------\n DateDayDifference method calculates the number of days "
},
{
"path": "Conversions/DateToDay.js",
"chars": 2479,
"preview": "/*\n DateToDay Method\n ----------------\n The DateToDay method takes a date in st"
},
{
"path": "Conversions/DecimalToBinary.js",
"chars": 312,
"preview": "function decimalToBinary(num) {\n const bin = []\n while (num > 0) {\n bin.unshift(num % 2)\n num >>= 1 // basically"
},
{
"path": "Conversions/DecimalToHex.js",
"chars": 454,
"preview": "function intToHex(num) {\n switch (num) {\n case 10:\n return 'A'\n case 11:\n return 'B'\n case 12:\n "
},
{
"path": "Conversions/DecimalToOctal.js",
"chars": 414,
"preview": "function decimalToOctal(num) {\n let oct = 0\n let c = 0\n while (num > 0) {\n const r = num % 8\n oct = oct + r * M"
},
{
"path": "Conversions/DecimalToRoman.js",
"chars": 772,
"preview": "/*\n Decimal To Roman\n\n This algorithm take decimal number and convert to roman numeral according to standard form "
},
{
"path": "Conversions/HexToBinary.js",
"chars": 879,
"preview": "const binLookup = (key) =>\n ({\n 0: '0000',\n 1: '0001',\n 2: '0010',\n 3: '0011',\n 4: '0100',\n 5: '0101'"
},
{
"path": "Conversions/HexToDecimal.js",
"chars": 761,
"preview": "function hexToInt(hexNum) {\n if (!/^[0-9A-F]+$/.test(hexNum)) {\n throw new Error('Invalid hex string.')\n }\n const "
},
{
"path": "Conversions/HexToRGB.js",
"chars": 342,
"preview": "function hexStringToRGB(hexString) {\n let r = hexString.substring(0, 2)\n let g = hexString.substring(2, 4)\n let b = h"
},
{
"path": "Conversions/LengthConversion.js",
"chars": 999,
"preview": "/**\n * Converts a length from one unit to another.\n *\n * @param {number} length - The length to convert.\n * @param {stri"
},
{
"path": "Conversions/LitersToImperialGallons.js",
"chars": 303,
"preview": "/**\n * This function converts liters to imperial gallons\n * @constructor\n * @param {number} liters - Amount of liters to"
},
{
"path": "Conversions/LitersToUSGallons.js",
"chars": 284,
"preview": "/**\n * This function converts liters to US gallons\n * https://en.wikipedia.org/wiki/Gallon\n * @constructor\n * @param {nu"
},
{
"path": "Conversions/LowerCaseConversion.js",
"chars": 1588,
"preview": "/*\n Explanation :- a user gives a String (it can be incomplete uppercase or\n partial uppercase) and then the p"
},
{
"path": "Conversions/MeterToFeetConversion.js",
"chars": 205,
"preview": "// Foot: https://en.wikipedia.org/wiki/Foot_(unit)\nconst feetToMeter = (feet) => {\n return feet * 0.3048\n}\n\nconst meter"
},
{
"path": "Conversions/OctToDecimal.js",
"chars": 291,
"preview": "function octalToDecimal(num) {\n let dec = 0\n let base = 1\n while (num > 0) {\n const r = num % 10\n num = Math.fl"
},
{
"path": "Conversions/OuncesToKilograms.js",
"chars": 277,
"preview": "/**\n * This function converts ounces to kilograms\n * https://en.wikipedia.org/wiki/Ounce\n * @constructor\n * @param {numb"
},
{
"path": "Conversions/RGBToHex.js",
"chars": 385,
"preview": "function RGBToHex(r, g, b) {\n if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number') {\n throw "
},
{
"path": "Conversions/RailwayTimeConversion.js",
"chars": 1497,
"preview": "/*\n The time conversion of normalized time to the railway is a simple algorithm\n because we know that if the time "
},
{
"path": "Conversions/RgbHslConversion.js",
"chars": 2000,
"preview": "/**\n * Given a color in RGB format, convert it to HSL format.\n *\n * For more info: https://www.niwa.nu/2013/05/math-behi"
},
{
"path": "Conversions/RgbHsvConversion.js",
"chars": 4269,
"preview": "/*\n * The RGB color model is an additive color model in which red, green, and blue light are added\n * together in variou"
},
{
"path": "Conversions/RomanToDecimal.js",
"chars": 533,
"preview": "const values = {\n I: 1,\n V: 5,\n X: 10,\n L: 50,\n C: 100,\n D: 500,\n M: 1000\n}\n\nexport function romanToDecimal(roman"
},
{
"path": "Conversions/TemperatureConversion.js",
"chars": 3734,
"preview": "// This files has functions to convert different temperature units\n// Functions take temperature value as a argument and"
},
{
"path": "Conversions/TitleCaseConversion.js",
"chars": 2305,
"preview": "/*\n Problem statement and Explanation : https://www.codeproject.com/Tips/162540/Letter-Case-Conversion-Algorithms-Tit"
},
{
"path": "Conversions/UpperCaseConversion.js",
"chars": 1628,
"preview": "/*\n Explanation :- A user gives a string (it can be incomplete lowercase or\n partially in lowercase) and then "
},
{
"path": "Conversions/test/ArbitraryBase.test.js",
"chars": 1938,
"preview": "import {\n convertArbitraryBase,\n convertArbitraryBaseBigIntVersion\n} from '../ArbitraryBase'\n\ntest('Check the answer o"
},
{
"path": "Conversions/test/ArrayBufferToBase64.test.js",
"chars": 948,
"preview": "import { bufferToBase64 } from '../ArrayBufferToBase64'\nimport { TextEncoder } from 'util'\n\ndescribe('ArrayBufferToBase6"
},
{
"path": "Conversions/test/Base64ToArrayBuffer.test.js",
"chars": 1062,
"preview": "import { base64ToBuffer } from '../Base64ToArrayBuffer'\nimport { TextDecoder } from 'util'\n\ndescribe('Base64ToArrayBuffe"
},
{
"path": "Conversions/test/BinaryToDecimal.test.js",
"chars": 480,
"preview": "import binaryToDecimal from '../BinaryToDecimal'\n\ndescribe('BinaryToDecimal', () => {\n it('expects to return correct de"
},
{
"path": "Conversions/test/BinaryToHex.test.js",
"chars": 657,
"preview": "import binaryToHex from '../BinaryToHex'\n\ndescribe('BinaryToHex', () => {\n it('expects to return correct hexadecimal va"
},
{
"path": "Conversions/test/DateDayDiffernce.test.js",
"chars": 1306,
"preview": "import { DateDayDifference } from '../DateDayDifference'\n\ndescribe('DateDayDifference', () => {\n it.each([\n ['17/08/"
},
{
"path": "Conversions/test/DateToDay.test.js",
"chars": 762,
"preview": "import { DateToDay } from '../DateToDay'\n\ndescribe('DateToDay', () => {\n it.each([\n ['18/02/2001', 'Sunday'],\n ['"
},
{
"path": "Conversions/test/DecimalToBinary.test.js",
"chars": 666,
"preview": "import { decimalToBinary } from '../DecimalToBinary'\n\ntest('The Binary representation of 35 is 100011', () => {\n const "
},
{
"path": "Conversions/test/DecimalToHex.test.js",
"chars": 498,
"preview": "import { decimalToHex } from '../DecimalToHex'\n\ndescribe('DecimalToHex', () => {\n it('expects to return correct hexadec"
},
{
"path": "Conversions/test/DecimalToOctal.test.js",
"chars": 614,
"preview": "import { decimalToOctal } from '../DecimalToOctal'\n\ntest('The Octal representation of 8 is 10', () => {\n const res = de"
},
{
"path": "Conversions/test/DecimalToRoman.test.js",
"chars": 459,
"preview": "import { decimalToRoman } from '../DecimalToRoman'\n\ndescribe('decimalToRoman', () => {\n it('expects to return correct r"
},
{
"path": "Conversions/test/HexToBinary.test.js",
"chars": 1070,
"preview": "import hexToBinary from '../HexToBinary'\n\ndescribe('Testing hexToBinary', () => {\n it('expects throw error in invalid t"
},
{
"path": "Conversions/test/HexToDecimal.test.js",
"chars": 531,
"preview": "import { hexToDecimal } from '../HexToDecimal'\n\ndescribe('Testing HexToDecimal', () => {\n it.each([\n ['0', 0],\n ["
},
{
"path": "Conversions/test/HexToRGB.test.js",
"chars": 546,
"preview": "import { hexStringToRGB } from '../HexToRGB'\n\ntest('The RGB form of Hex String E1E1E1 is {r: 225, g: 225, b: 225}', () ="
},
{
"path": "Conversions/test/LengthConversion.test.js",
"chars": 1685,
"preview": "import { lengthConversion } from '../LengthConversion.js'\n\ndescribe('LengthConversion', () => {\n it.each`\n length | "
},
{
"path": "Conversions/test/LitersToImperialGallons.test.js",
"chars": 194,
"preview": "import litersToImperialGallons from '../LitersToImperialGallons'\n\ntest('Convert 25 liters to imperial gallons', () => {\n"
},
{
"path": "Conversions/test/LitersToUSGallons.test.js",
"chars": 172,
"preview": "import litersToUSGallons from '../LitersToUSGallons'\n\ntest('Convert 50 liters to US gallons', () => {\n expect(parseFloa"
},
{
"path": "Conversions/test/LowerCaseConversion.test.js",
"chars": 726,
"preview": "import { LowerCaseConversion } from '../LowerCaseConversion'\n\ntest('The LowerCaseConversion of ApoLO is apolo', () => {\n"
},
{
"path": "Conversions/test/MeterToFeetConversion.test.js",
"chars": 343,
"preview": "import { meterToFeet, feetToMeter } from '../MeterToFeetConversion'\n\ndescribe('Testing conversion of Meter to Feet', () "
},
{
"path": "Conversions/test/OctToDecimal.test.js",
"chars": 687,
"preview": "import { octalToDecimal } from '../OctToDecimal'\n\ntest('The Decimal representation of Octal number 56 is 46', () => {\n "
},
{
"path": "Conversions/test/OuncesToKilogram.test.js",
"chars": 171,
"preview": "import ouncesToKilograms from '../OuncesToKilograms'\n\ntest('Convert 60 ounces to kilograms', () => {\n expect(parseFloat"
},
{
"path": "Conversions/test/RGBToHex.test.js",
"chars": 583,
"preview": "import { RGBToHex } from '../RGBToHex'\n\ntest('The Hex format of RGB (225, 225, 225) is #ffffff', () => {\n const res = R"
},
{
"path": "Conversions/test/RailwayTimeConversion.test.js",
"chars": 828,
"preview": "import { RailwayTimeConversion } from '../RailwayTimeConversion'\n\ntest('The RailwayTimeConversion of 07:05:45AM is 07:05"
},
{
"path": "Conversions/test/RgbHslConversion.test.js",
"chars": 905,
"preview": "import { rgbToHsl } from '../RgbHslConversion'\ndescribe('RgbHslConversion', () => {\n test.each([\n [\n [215, 19, "
},
{
"path": "Conversions/test/RgbHsvConversion.test.js",
"chars": 1953,
"preview": "import { approximatelyEqualHsv, hsvToRgb, rgbToHsv } from '../RgbHsvConversion'\n\ndescribe('hsvToRgb', () => {\n // Expec"
},
{
"path": "Conversions/test/RomanToDecimal.test.js",
"chars": 316,
"preview": "import { romanToDecimal } from '../RomanToDecimal'\n\ndescribe('romanToDecimal', () => {\n it('XXIIVV', () => {\n expect"
},
{
"path": "Conversions/test/TemperatureConversion.test.js",
"chars": 2882,
"preview": "import * as tc from '../TemperatureConversion.js'\n\ndescribe('Testing Conversion of Celsius to fahrenheit', () => {\n it("
},
{
"path": "Conversions/test/TitleCaseConversion.test.js",
"chars": 2322,
"preview": "import { titleCaseConversion } from '../TitleCaseConversion'\n\ndescribe('Tests for the titleCaseConversion function', () "
},
{
"path": "Conversions/test/UpperCaseConverstion.test.js",
"chars": 1940,
"preview": "import { upperCaseConversion } from '../UpperCaseConversion'\n\ndescribe('Test the upperCaseConversion function', () => {\n"
},
{
"path": "DIRECTORY.md",
"chars": 19632,
"preview": "* **Backtracking**\n * [AllCombinationsOfSizeK](Backtracking/AllCombinationsOfSizeK.js)\n * [generateParentheses](Backtr"
},
{
"path": "Data-Structures/Array/LocalMaximumPoint.js",
"chars": 1400,
"preview": "/**\n * [LocalMaxima](https://www.geeksforgeeks.org/find-indices-of-all-local-maxima-and-local-minima-in-an-array/) is an"
},
{
"path": "Data-Structures/Array/NumberOfLocalMaximumPoints.js",
"chars": 1551,
"preview": "/**\n * [NumberOfLocalMaximumPoints](https://www.geeksforgeeks.org/find-indices-of-all-local-maxima-and-local-minima-in-a"
},
{
"path": "Data-Structures/Array/QuickSelect.js",
"chars": 1619,
"preview": "/**\n * [QuickSelect](https://www.geeksforgeeks.org/quickselect-algorithm/) is an algorithm to find the kth smallest numb"
},
{
"path": "Data-Structures/Array/Reverse.js",
"chars": 512,
"preview": "/** https://www.geeksforgeeks.org/write-a-program-to-Reverse-an-array-or-string/\n * This function will accept an array a"
},
{
"path": "Data-Structures/Array/test/LocalMaximumPoint.test.js",
"chars": 1016,
"preview": "import { LocalMaximumPoint } from '../LocalMaximumPoint'\n\ndescribe('LocalMaximumPoint tests', () => {\n it('test boundar"
},
{
"path": "Data-Structures/Array/test/NumberOfLocalMaximumPoints.test.js",
"chars": 1855,
"preview": "import { NumberOfLocalMaximumPoints } from '../NumberOfLocalMaximumPoints'\n\ndescribe('LocalMaximumPoint tests', () => {\n"
},
{
"path": "Data-Structures/Array/test/QuickSelect.test.js",
"chars": 2310,
"preview": "import { QuickSelect } from '../QuickSelect'\n\ndescribe('QuickSelect tests', () => {\n it('should return the only element"
},
{
"path": "Data-Structures/Array/test/Reverse.test.js",
"chars": 292,
"preview": "import { Reverse } from '../Reverse.js'\n\ndescribe('reverse elements in an array', () => {\n it.each([\n [[], []],\n "
},
{
"path": "Data-Structures/Graph/Graph.js",
"chars": 2323,
"preview": "class Graph {\n constructor() {\n this.adjacencyMap = {}\n }\n\n addVertex(vertex) {\n this.adjacencyMap[vertex] = []"
},
{
"path": "Data-Structures/Graph/Graph2.js",
"chars": 1352,
"preview": "// create a graph class\nclass Graph {\n // defining vertex array and\n // adjacent list\n constructor(noOfVertices) {\n "
},
{
"path": "Data-Structures/Graph/Graph3.js",
"chars": 2298,
"preview": "class Graph {\n constructor() {\n this.adjacencyObject = {}\n }\n\n addVertex(vertex) {\n if (!this.adjacencyObject[v"
},
{
"path": "Data-Structures/Graph/test/Graph2.test.js",
"chars": 940,
"preview": "import { Graph } from '../Graph2'\n\ndescribe('Test Graph2', () => {\n const vertices = ['A', 'B', 'C', 'D', 'E', 'F']\n c"
},
{
"path": "Data-Structures/Graph/test/Graph3.test.js",
"chars": 1759,
"preview": "import { Graph } from '../Graph3'\n\ndescribe('Test Graph3', () => {\n const g = new Graph()\n\n // Add Vertices\n g.addVer"
},
{
"path": "Data-Structures/Heap/BinaryHeap.js",
"chars": 4234,
"preview": "/**\n * BinaryHeap class represents a binary heap data structure that can be configured as a Min Heap or Max Heap.\n *\n * "
},
{
"path": "Data-Structures/Heap/KeyPriorityQueue.js",
"chars": 5329,
"preview": "/**\n * KeyPriorityQueue is a priority queue based on a Minimum Binary Heap.\n *\n * Minimum Binary Heaps are binary trees "
},
{
"path": "Data-Structures/Heap/MinPriorityQueue.js",
"chars": 3481,
"preview": "/* Minimum Priority Queue\n * It is a part of heap data structure\n * A heap is a specific tree based data structure\n * in"
},
{
"path": "Data-Structures/Heap/test/BinaryHeap.test.js",
"chars": 2349,
"preview": "import { BinaryHeap, minHeapComparator } from '../BinaryHeap'\n\ndescribe('BinaryHeap', () => {\n describe('MinHeap', () ="
},
{
"path": "Data-Structures/Heap/test/KeyPriorityQueue.test.js",
"chars": 3586,
"preview": "import { KeyPriorityQueue } from '../KeyPriorityQueue.js'\n\ndescribe('Key Priority Queue', () => {\n describe('Method isE"
},
{
"path": "Data-Structures/Heap/test/MinPriorityQueue.test.js",
"chars": 1625,
"preview": "import { MinPriorityQueue } from '../MinPriorityQueue'\n\ndescribe('MinPriorityQueue', () => {\n const values = [5, 2, 4, "
},
{
"path": "Data-Structures/Linked-List/AddTwoNumbers.js",
"chars": 1465,
"preview": "/**\n * A LinkedList based solution for Add Two Numbers\n *\n */\nimport { Node } from './SinglyLinkedList.js'\n\n/*\nProblem S"
},
{
"path": "Data-Structures/Linked-List/CycleDetection.js",
"chars": 593,
"preview": "/**\n * A LinkedList based solution for Detecting a Cycle in a list.\n * https://en.wikipedia.org/wiki/Cycle_detection\n */"
},
{
"path": "Data-Structures/Linked-List/CycleDetectionII.js",
"chars": 1254,
"preview": "/**\n * A LinkedList based solution for finding the starting node of the cycle in a list.\n * @returns the node where cycl"
},
{
"path": "Data-Structures/Linked-List/DoublyLinkedList.js",
"chars": 4820,
"preview": "class Node {\n constructor(element) {\n this.element = element\n this.next = null\n this.prev = null\n }\n}\n\nclass "
},
{
"path": "Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js",
"chars": 1230,
"preview": "import { LinkedList } from './SinglyLinkedList.js'\n/**\n * A LinkedList-based solution for merging two sorted linked list"
},
{
"path": "Data-Structures/Linked-List/ReverseSinglyLinkedList.js",
"chars": 543,
"preview": "/** A LinkedList based solution to reverse a number\nProblem Statement: Given a number such that each of its digit is sto"
},
{
"path": "Data-Structures/Linked-List/SinglyCircularLinkedList.js",
"chars": 4388,
"preview": "// Methods - size, head, isEmpty, getElementAt, addAtFirst, add, clean, insertAt, remove, removeData, printData, get, cl"
},
{
"path": "Data-Structures/Linked-List/SinglyLinkedList.js",
"chars": 7805,
"preview": "/* SinglyLinkedList!!\n * A linked list is similar to an array, it holds a list of values.\n * However, links in a linked "
},
{
"path": "Data-Structures/Linked-List/test/AddTwoNumbers.test.js",
"chars": 684,
"preview": "import { AddTwoNumbers } from '../AddTwoNumbers.js'\nimport { LinkedList } from '../SinglyLinkedList'\n\ndescribe('AddTwoNu"
},
{
"path": "Data-Structures/Linked-List/test/CycleDetection.test.js",
"chars": 1021,
"preview": "import { detectCycle } from '../CycleDetection'\nimport { Node } from '../SinglyLinkedList'\n\ndescribe('Detect Cycle', () "
},
{
"path": "Data-Structures/Linked-List/test/CycleDetectionII.test.js",
"chars": 993,
"preview": "import { findCycleStart } from '../CycleDetectionII'\nimport { Node } from '../SinglyLinkedList'\n\ndescribe('Detect Cycle'"
},
{
"path": "Data-Structures/Linked-List/test/DoublyLinkedList.test.js",
"chars": 2686,
"preview": "import { DoubleLinkedList } from '../DoublyLinkedList'\n\ndescribe('DoubleLinkedList', () => {\n it('Check append', () => "
},
{
"path": "Data-Structures/Linked-List/test/MergeTwoSortedLinkedLists.test.js",
"chars": 1050,
"preview": "import { expect } from 'vitest'\nimport { mergeLinkedLists } from '../MergeTwoSortedLinkedLists.js'\nimport { LinkedList }"
},
{
"path": "Data-Structures/Linked-List/test/ReverseSinglyLinkedList.test.js",
"chars": 567,
"preview": "import { ReverseSinglyLinkedList } from '../ReverseSinglyLinkedList'\nimport { Node } from '../SinglyLinkedList'\ndescribe"
},
{
"path": "Data-Structures/Linked-List/test/SinglyCircularLinkedList.test.js",
"chars": 3867,
"preview": "import { SinglyCircularLinkedList } from '../SinglyCircularLinkedList'\n\ndescribe('SinglyCircularLinkedList', () => {\n l"
},
{
"path": "Data-Structures/Linked-List/test/SinglyLinkedList.test.js",
"chars": 6833,
"preview": "import { LinkedList } from '../SinglyLinkedList'\n\ndescribe('SinglyLinkedList', () => {\n it('Check addLast', () => {\n "
},
{
"path": "Data-Structures/Queue/CircularQueue.js",
"chars": 2077,
"preview": "// Circular Queues offer a quick to store FIFO data with a maximum size.\n// Conserves memory as we only store up to our "
},
{
"path": "Data-Structures/Queue/Queue.js",
"chars": 2126,
"preview": "/* Queue\n * A Queue is a data structure that allows you to add an element to the end of\n * a list and remove the item at"
},
{
"path": "Data-Structures/Queue/QueueUsing2Stacks.js",
"chars": 823,
"preview": "// implementation of Queue using 2 stacks\n// contribution made by hamza chabchoub for a university project\n\nclass Queue "
},
{
"path": "Data-Structures/Queue/test/Queue.test.js",
"chars": 1051,
"preview": "import Queue from '../Queue'\n\ndescribe('Testing the Queue DS', () => {\n const queue = new Queue()\n\n it('Testing enqueu"
},
{
"path": "Data-Structures/Queue/test/QueueUsing2Stacks.test.js",
"chars": 316,
"preview": "import { Queue } from '../QueueUsing2Stacks'\n\ndescribe('QueueUsing2Stacks', () => {\n const queue = new Queue()\n\n it('C"
},
{
"path": "Data-Structures/Stack/EvaluateExpression.js",
"chars": 1779,
"preview": "/**\n * Evaluate a numeric operations string in postfix notation using a stack.\n * Supports basic arithmetic operations: "
},
{
"path": "Data-Structures/Stack/Stack.js",
"chars": 1241,
"preview": "/* Stack!!\n * A stack is exactly what it sounds like. An element gets added to the top of\n * the stack and only the elem"
},
{
"path": "Data-Structures/Stack/StackES6.js",
"chars": 1472,
"preview": "/* Stack data-structure. It's work is based on the LIFO method (last-IN-first-OUT).\n * It means that elements added to t"
},
{
"path": "Data-Structures/Stack/test/EvaluateExpression.test.js",
"chars": 718,
"preview": "import { evaluatePostfixExpression } from '../EvaluateExpression.js'\n\ndescribe('evaluatePostfixExpression', () => {\n it"
},
{
"path": "Data-Structures/Tree/AVLTree.js",
"chars": 7212,
"preview": "/**\n * Adelson-Velsky and Landis Tree\n * [Wikipedia](https://en.wikipedia.org/wiki/AVL_tree)\n * [A video lecture](http:/"
},
{
"path": "Data-Structures/Tree/BinarySearchTree.js",
"chars": 3714,
"preview": "/* Binary Search Tree!!\n *\n * Nodes that will go on the Binary Tree.\n * They consist of the data in them, the node to th"
},
{
"path": "Data-Structures/Tree/SegmentTree.js",
"chars": 2794,
"preview": "/**\n * Segment Tree\n * concept : [Wikipedia](https://en.wikipedia.org/wiki/Segment_tree)\n * inspired by : https://www.ge"
},
{
"path": "Data-Structures/Tree/Trie.js",
"chars": 3428,
"preview": "class TrieNode {\n constructor(key, parent) {\n this.key = key\n this.count = 0\n this.children = Object.create(nu"
},
{
"path": "Data-Structures/Tree/test/AVLTree.test.js",
"chars": 2001,
"preview": "import { AVLTree } from '../AVLTree'\n\ndescribe('AVLTree Implementation: ', () => {\n const avlTree = new AVLTree()\n con"
},
{
"path": "Data-Structures/Tree/test/BinarySearchTree.test.js",
"chars": 1607,
"preview": "import { Tree } from '../BinarySearchTree.js'\n\ndescribe('Binary Search Tree', () => {\n let tree\n\n beforeEach(() => {\n "
},
{
"path": "Data-Structures/Tree/test/SegmentTree.test.js",
"chars": 359,
"preview": "import { SegmentTree } from '../SegmentTree'\n\ndescribe('SegmentTree sum test', () => {\n const a = [1, 2, 3, 4, 5, 6, 7,"
},
{
"path": "Data-Structures/Vectors/Vector2.js",
"chars": 3361,
"preview": "/**\n * In mathematics and physics, a vector is an element of a vector space.\n *\n * The Vector2-class implements 2-dimens"
},
{
"path": "Data-Structures/Vectors/test/Vector2.test.js",
"chars": 3952,
"preview": "import { Vector2 } from '../Vector2.js'\n\ndescribe('Vector2', () => {\n describe('#equalsExactly', () => {\n it('should"
},
{
"path": "Dynamic-Programming/Abbreviation.js",
"chars": 2062,
"preview": "/**\n * @description\n * Given two strings, `source` and `target`, determine if it's possible to make `source` equal\n * to"
},
{
"path": "Dynamic-Programming/CatalanNumbers.js",
"chars": 735,
"preview": "/*\n * Author: IcarusTheFly (https://github.com/IcarusTheFly)\n * Catalan Numbers explanation can be found in the followin"
},
{
"path": "Dynamic-Programming/ClimbingStairs.js",
"chars": 592,
"preview": "/**\n * @function ClimbStairs\n * @description You are climbing a stair case. It takes n steps to reach to the top.Each ti"
},
{
"path": "Dynamic-Programming/CoinChange.js",
"chars": 898,
"preview": "/**\n * @params {Array} coins\n * @params {Number} amount\n */\nexport const change = (coins, amount) => {\n // Create and i"
}
]
// ... and 551 more files (download for full content)
About this extraction
This page contains the full source code of the TheAlgorithms/JavaScript GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 751 files (962.4 KB), approximately 314.0k tokens, and a symbol index with 618 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.