├── .github ├── CODEOWNERS ├── pull_request_template.md ├── stale.yml └── workflows │ ├── Ci.yml │ ├── UpdateDirectory.mjs │ └── UpdateDirectory.yml ├── .gitignore ├── .gitpod.yml ├── .husky └── pre-commit ├── .prettierrc ├── Backtracking ├── AllCombinationsOfSizeK.js ├── GeneratePermutations.js ├── KnightTour.js ├── NQueen.js ├── RatInAMaze.js ├── Sudoku.js ├── SumOfSubset.js └── tests │ ├── AllCombinationsOfSizeK.test.js │ ├── GeneratePermutations.test.js │ ├── KnightTour.test.js │ ├── NQueen.test.js │ ├── RatInAMaze.test.js │ ├── Sudoku.test.js │ └── SumOfSubset.test.js ├── Bit-Manipulation ├── BinaryCountSetBits.js ├── IsPowerOfTwo.js ├── NextPowerOfTwo.js ├── SetBit.js └── test │ ├── BinaryCountSetBits.test.js │ ├── IsPowerOfTwo.test.js │ ├── NextPowerOfTwo.test.js │ └── SetBit.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 └── test │ └── ConwaysGameOfLife.test.js ├── Ciphers ├── Atbash.js ├── CaesarsCipher.js ├── KeyFinder.js ├── KeywordShiftedAlphabet.js ├── ROT13.js ├── VigenereCipher.js ├── XORCipher.js └── test │ ├── Atbash.test.js │ ├── CaesarsCipher.test.js │ ├── KeywordShiftedAlphabet.test.js │ ├── ROT13.test.js │ ├── VigenereCipher.test.js │ └── XORCipher.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 ├── LowerCaseConversion.js ├── MeterToFeetConversion.js ├── OctToDecimal.js ├── RGBToHex.js ├── RailwayTimeConversion.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 │ ├── HexToRGB.test.js │ ├── LowerCaseConversion.test.js │ ├── MeterToFeetConversion.test.js │ ├── OctToDecimal.test.js │ ├── RGBToHex.test.js │ ├── RailwayTimeConversion.test.js │ ├── RgbHsvConversion.test.js │ ├── RomanToDecimal.test.js │ ├── TemperatureConversion.test.js │ ├── TitleCaseConversion.test.js │ └── UpperCaseConverstion.test.js ├── DIRECTORY.md ├── Data-Structures ├── Array │ ├── LocalMaximomPoint.js │ ├── NumberOfLocalMaximumPoints.js │ ├── QuickSelect.js │ └── test │ │ ├── LocalMaximomPoint.test.js │ │ ├── NumberOfLocalMaximumPoints.test.js │ │ └── QuickSelect.test.js ├── Graph │ ├── Graph.js │ ├── Graph2.js │ ├── Graph3.js │ └── test │ │ ├── Graph2.test.js │ │ └── Graph3.test.js ├── Heap │ ├── MaxHeap.js │ ├── MinHeap.js │ ├── MinPriorityQueue.js │ └── test │ │ ├── MinHeap.test.js │ │ └── MinPriorityQueue.test.js ├── Linked-List │ ├── AddTwoNumbers.js │ ├── CycleDetection.js │ ├── DoublyLinkedList.js │ ├── RotateListRight.js │ ├── SinglyCircularLinkedList.js │ ├── SinglyLinkedList.js │ └── test │ │ ├── AddTwoNumbers.test.js │ │ ├── DoublyLinkedList.test.js │ │ ├── SinglyCircularLinkedList.test.js │ │ └── SinglyLinkedList.test.js ├── Queue │ ├── CircularQueue.js │ ├── Queue.js │ ├── QueueUsing2Stacks.js │ └── test │ │ ├── Queue.test.js │ │ └── QueueUsing2Stacks.test.js ├── Stack │ ├── Stack.js │ └── StackES6.js ├── Tree │ ├── AVLTree.js │ ├── BinarySearchTree.js │ ├── Trie.js │ └── test │ │ └── AVLTree.test.js └── Vectors │ ├── Vector2.js │ └── test │ └── Vector2.test.js ├── Dynamic-Programming ├── ClimbingStairs.js ├── CoinChange.js ├── EditDistance.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 │ ├── LongestSubstringWithoutRepeatingCharacters.js │ ├── PermutationinString.js │ └── test │ │ ├── LongestSubstringWithoutRepeatingCharacters.test.js │ │ └── PermutationinString.test.js ├── SudokuSolver.js ├── TrappingRainWater.js ├── TribonacciNumber.js ├── ZeroOneKnapsack.js └── tests │ ├── ClimbingStairs.test.js │ ├── CoinChange.test.js │ ├── FibonacciNumber.test.js │ ├── KadaneAlgo.test.js │ ├── LongestCommonSubsequence.test.js │ ├── LongestPalindromicSubsequence.test.js │ ├── LongestValidParentheses.test.js │ ├── MaxProductOfThree.test.js │ ├── RodCutting.test.js │ ├── SieveOfEratosthenes.test.js │ ├── TrappingRainWater.test.js │ └── TribonacciNumber.test.js ├── Geometry ├── ConvexHullGraham.js └── Test │ └── ConvexHullGraham.test.js ├── Graphs ├── BellmanFord.js ├── BreadthFirstSearch.js ├── BreadthFirstShortestPath.js ├── ConnectedComponents.js ├── Density.js ├── DepthFirstSearchIterative.js ├── DepthFirstSearchRecursive.js ├── Dijkstra.js ├── DijkstraSmallestPath.js ├── FloydWarshall.js ├── KruskalMST.js ├── NodeNeighbors.js ├── NumberOfIslands.js ├── PrimMST.js └── test │ ├── BellmanFord.test.js │ ├── BreadthFirstSearch.test.js │ └── BreadthFirstShortestPath.test.js ├── Hashes ├── SHA1.js └── SHA256.js ├── LICENSE ├── Maths ├── Abs.js ├── AliquotSum.js ├── Area.js ├── ArithmeticGeometricMean.js ├── ArmstrongNumber.js ├── AverageMean.js ├── AverageMedian.js ├── BinaryConvert.js ├── BinaryExponentiationIterative.js ├── BinaryExponentiationRecursive.js ├── BisectionMethod.js ├── CheckKishnamurthyNumber.js ├── CoPrimeCheck.js ├── CollatzSequence.js ├── Coordinate.js ├── DecimalExpansion.js ├── DecimalIsolate.js ├── DegreeToRadian.js ├── EulerMethod.js ├── EulersTotient.js ├── EulersTotientFunction.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 ├── GetEuclidGCD.js ├── GridGet.js ├── IsDivisible.js ├── IsEven.js ├── IsOdd.js ├── IsPronic.js ├── LeapYear.js ├── LinearSieve.js ├── LucasSeries.js ├── Mandelbrot.js ├── MatrixExponentiationRecursive.js ├── MatrixMultiplication.js ├── MeanSquareError.js ├── MidpointIntegration.js ├── ModularBinaryExponentiationRecursive.js ├── NumberOfDigits.js ├── Palindrome.js ├── PascalTriangle.js ├── PerfectCube.js ├── PerfectNumber.js ├── PerfectSquare.js ├── PermutationAndCombination.js ├── PiApproximationMonteCarlo.js ├── Polynomial.js ├── Pow.js ├── PowLogarithmic.js ├── PrimeCheck.js ├── PrimeFactors.js ├── RadianToDegree.js ├── ReverseNumber.js ├── ReversePolishNotation.js ├── SieveOfEratosthenes.js ├── SimpsonIntegration.js ├── Softmax.js ├── SquareRoot.js ├── SumOfDigits.js ├── SumOfGeometricProgression.js ├── TwinPrime.js ├── Volume.js ├── WhileLoopFactorial.js ├── ZellersCongruenceAlgorithm.js └── test │ ├── Abs.test.js │ ├── AliquotSum.test.js │ ├── Area.test.js │ ├── ArithmeticGeometricMean.test.js │ ├── ArmstrongNumber.test.js │ ├── AverageMean.test.js │ ├── AverageMedian.test.js │ ├── BInaryConvert.test.js │ ├── BinaryExponentiationIterative.test.js │ ├── BinaryExponentiationRecursive.test.js │ ├── BisectionMethod.test.js │ ├── CollatzSequence.test.js │ ├── Coordinate.test.js │ ├── DecimalExpansion.test.js │ ├── DegreeToRadian.test.js │ ├── EulerMethod.manual-test.js │ ├── EulerMethod.test.js │ ├── EulersTotient.test.js │ ├── EulersTotientFunction.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 │ ├── IsDivisible.test.js │ ├── IsEven.test.js │ ├── IsOdd.test.js │ ├── IsPronic.test.js │ ├── LeapYear.test.js │ ├── LinearSieve.test.js │ ├── LucasSeries.test.js │ ├── Mandelbrot.manual-test.js │ ├── Mandelbrot.test.js │ ├── MeanSquareError.test.js │ ├── MidpointIntegration.test.js │ ├── ModularBinaryExponentiationRecursive.test.js │ ├── NumberOfDigits.test.js │ ├── Palindrome.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 │ ├── RadianToDegree.test.js │ ├── ReversePolishNotation.test.js │ ├── SieveOfEratosthenes.test.js │ ├── SimpsonIntegration.test.js │ ├── Softmax.test.js │ ├── SquareRoot.test.js │ ├── SumOfDigits.test.js │ ├── SumOfGeometricProgression.test.js │ ├── TwinPrime.test.js │ ├── Volume.test.js │ ├── WhileLoopFactorial.test.js │ └── ZellersCongruenceAlgorithm.test.js ├── Navigation ├── Haversine.js └── test │ └── Haversine.test.js ├── Project-Euler ├── Problem001.js ├── Problem002.js ├── Problem003.js ├── Problem004.js ├── Problem005.js ├── Problem006.js ├── Problem008.js ├── Problem009.js ├── Problem010.js ├── Problem012.js ├── Problem014.js ├── Problem015.js ├── Problem016.js ├── Problem018.js ├── Problem020.js ├── Problem023.js ├── Problem025.js └── test │ ├── Problem008.test.js │ ├── Problem010.test.js │ ├── Problem012.test.js │ ├── Problem016.test.js │ ├── Problem018.test.js │ ├── Problem020.test.js │ ├── Problem023.test.js │ └── Problem025.test.js ├── README.md ├── Recursive ├── BinaryEquivalent.js ├── BinarySearch.js ├── EucledianGCD.js ├── Factorial.js ├── FibonacciNumberRecursive.js ├── FloodFill.js ├── KochSnowflake.js ├── KochSnowflake.manual-test.js ├── Palindrome.js ├── SubsequenceRecursive.js ├── TowerOfHanoi.js └── test │ ├── BinarySearch.test.js │ ├── Factorial.test.js │ ├── FibonacciNumberRecursive.test.js │ ├── FloodFill.test.js │ ├── KochSnowflake.test.js │ └── palindrome.test.js ├── Search ├── BinarySearch.js ├── ExponentialSearch.js ├── FibonacciSearch.js ├── InterpolationSearch.js ├── JumpSearch.js ├── LinearSearch.js ├── QuickSelectSearch.js ├── SlidingWindow.js ├── StringSearch.js ├── TernarySearch.js ├── UnionFind.js └── test │ ├── BinarySearch.test.js │ ├── ExponentialSearch.test.js │ ├── FibonacciSearch.test.js │ ├── SlidingWindow.test.js │ ├── TernarySearch.test.js │ ├── UnionFind.test.js │ └── jumpSearch.test.js ├── Sorts ├── AlphaNumericalSort.js ├── BeadSort.js ├── BogoSort.js ├── BubbleSort.js ├── BucketSort.js ├── CocktailShakerSort.js ├── CombSort.js ├── CountingSort.js ├── CycleSort.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 ├── TimSort.js ├── TopologicalSort.js └── test │ ├── AlphaNumericalSort.test.js │ ├── BeadSort.test.js │ ├── BogoSort.test.js │ ├── BubbleSort.test.js │ ├── BucketSort.test.js │ ├── CocktailShakerSort.test.js │ ├── CombSort.test.js │ ├── CountingSort.test.js │ ├── CycleSort.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 │ └── 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 ├── CountVowels.js ├── CreatePermutations.js ├── DiceCoefficient.js ├── FormatPhoneNumber.js ├── GenerateGUID.js ├── HammingDistance.js ├── KMPPatternSearching.js ├── LevenshteinDistance.js ├── Lower.js ├── MaxCharacter.js ├── MaxWord.js ├── PatternMatching.js ├── PermutateString.js ├── ReverseString.js ├── ReverseWords.js ├── ScrambleStrings.js ├── Upper.js ├── ValidateCreditCard.js ├── ValidateEmail.js ├── ValidateUrl.js └── test │ ├── AlphaNumericPalindrome.test.js │ ├── AlternativeStringArrange.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 │ ├── CountVowels.test.js │ ├── CreatePermutations.test.js │ ├── DiceCoefficient.test.js │ ├── FormatPhoneNumber.test.js │ ├── HammingDistance.test.js │ ├── KMPPatternSearching.test.js │ ├── LevenshteinDistance.test.js │ ├── Lower.test.js │ ├── MaxCharacter.test.js │ ├── MaxWord.test.js │ ├── PatternMatching.test.js │ ├── PermutateString.test.js │ ├── ReverseString.test.js │ ├── ReverseWords.test.js │ ├── ScrambleStrings.test.js │ ├── Upper.test.js │ ├── ValidateCreditCard.test.js │ ├── ValidateEmail.test.js │ └── ValidateUrl.test.js ├── Timing-Functions ├── GetMonthDays.js ├── IntervalTimer.js └── test │ └── GetMonthDays.test.js ├── Trees ├── BreadthFirstTreeTraversal.js ├── DepthFirstSearch.js ├── FenwickTree.js └── test │ ├── BreadthFirstTreeTraversal.test.js │ └── FenwickTree.test.js ├── babel.config.cjs ├── package-lock.json └── package.json /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @raklaptudirm @appgurueu 2 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale (2 weeks) 2 | daysUntilStale: 14 3 | # Number of days of inactivity before a stale issue is closed (a week) 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - bug 8 | - help wanted 9 | - OK to merge 10 | # Label to use when marking an issue as stale 11 | staleLabel: stale 12 | # Comment to post when marking an issue as stale. Set to `false` to disable 13 | markComment: > 14 | This issue has been automatically marked as stale because it has not had 15 | recent activity. It will be closed if no further activity occurs. Thank you 16 | for your contributions. 17 | # Comment to post when closing a stale issue. Set to `false` to disable 18 | closeComment: > 19 | Please reopen this issue once you commit the changes requested or 20 | make improvements on the code. Thank you for your contributions. 21 | -------------------------------------------------------------------------------- /.github/workflows/Ci.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | name: Code style and tests 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - uses: actions/setup-node@v2 16 | with: 17 | node-version: "16.x" 18 | cache: npm 19 | 20 | - name: 📦 Install dependencies 21 | run: npm ci 22 | 23 | - name: 🧪 Run tests 24 | run: npm test 25 | 26 | - name: 💄 Code style 27 | run: npm run style 28 | 29 | codespell: 30 | name: Check for spelling errors 31 | runs-on: ubuntu-latest 32 | steps: 33 | - uses: actions/checkout@v2 34 | - uses: codespell-project/actions-codespell@master 35 | with: 36 | # file types to ignore 37 | skip: "*.json,*.yml,DIRECTORY.md" 38 | ignore_words_list: "ba,esy,yse" 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # misc 5 | .DS_Store 6 | .env.local 7 | .env.development.local 8 | .env.test.local 9 | .env.production.local 10 | 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # intelliJ workspace folder 16 | .idea 17 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: npm install 3 | 4 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run style 5 | npm run test 6 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "bracketSpacing": true, 4 | "endOfLine": "lf", 5 | "insertPragma": false, 6 | "printWidth": 80, 7 | "proseWrap": "preserve", 8 | "quoteProps": "as-needed", 9 | "requirePragma": false, 10 | "semi": false, 11 | "singleQuote": true, 12 | "tabWidth": 2, 13 | "trailingComma": "none", 14 | "useTabs": false 15 | } 16 | -------------------------------------------------------------------------------- /Backtracking/GeneratePermutations.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem Statement: Generate all distinct permutations of a an array (all permutations should be in sorted order); 3 | * 4 | * What is permutations? 5 | * - Permutation means possible arrangements in a set (here it is an array); 6 | * 7 | * Reference to know more about permutations: 8 | * - https://www.britannica.com/science/permutation 9 | * 10 | */ 11 | 12 | const swap = (arr, i, j) => { 13 | const newArray = [...arr]; 14 | 15 | [newArray[i], newArray[j]] = [newArray[j], newArray[i]] // Swapping elements ES6 way 16 | 17 | return newArray 18 | } 19 | 20 | const permutations = arr => { 21 | const P = [] 22 | const permute = (arr, low, high) => { 23 | if (low === high) { 24 | P.push([...arr]) 25 | return P 26 | } 27 | for (let i = low; i <= high; i++) { 28 | arr = swap(arr, low, i) 29 | permute(arr, low + 1, high) 30 | } 31 | return P 32 | } 33 | return permute(arr, 0, arr.length - 1) 34 | } 35 | 36 | export { permutations } 37 | -------------------------------------------------------------------------------- /Backtracking/tests/AllCombinationsOfSizeK.test.js: -------------------------------------------------------------------------------- 1 | import { Combinations } from '../AllCombinationsOfSizeK' 2 | 3 | describe('AllCombinationsOfSizeK', () => { 4 | it('should return 3x2 matrix solution for n = 3 and k = 2', () => { 5 | const test1 = new Combinations(3, 2) 6 | expect(test1.findCombinations()).toEqual([[1, 2], [1, 3], [2, 3]]) 7 | }) 8 | 9 | it('should return 6x2 matrix solution for n = 4 and k = 2', () => { 10 | const test2 = new Combinations(4, 2) 11 | expect(test2.findCombinations()).toEqual([[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /Backtracking/tests/GeneratePermutations.test.js: -------------------------------------------------------------------------------- 1 | import { permutations } from '../GeneratePermutations' 2 | 3 | describe('Permutations', () => { 4 | it('Permutations of [1, 2, 3]', () => { 5 | expect(permutations([1, 2, 3])).toEqual([ 6 | [1, 2, 3], 7 | [1, 3, 2], 8 | [2, 1, 3], 9 | [2, 3, 1], 10 | [3, 1, 2], 11 | [3, 2, 1] 12 | ]) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Backtracking/tests/KnightTour.test.js: -------------------------------------------------------------------------------- 1 | import { OpenKnightTour } from '../KnightTour' 2 | 3 | describe('OpenKnightTour', () => { 4 | it('OpenKnightTour(5)', () => { 5 | const KT = new OpenKnightTour(5) 6 | expect(KT.board).toEqual([ 7 | [0, 0, 0, 0, 0], 8 | [0, 0, 0, 0, 0], 9 | [0, 0, 0, 0, 0], 10 | [0, 0, 0, 0, 0], 11 | [0, 0, 0, 0, 0] 12 | ]) 13 | 14 | KT.solve() 15 | expect(KT.board).toEqual([ 16 | [19, 4, 15, 10, 25], 17 | [14, 9, 18, 5, 16], 18 | [1, 20, 3, 24, 11], 19 | [8, 13, 22, 17, 6], 20 | [21, 2, 7, 12, 23] 21 | ]) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /Backtracking/tests/NQueen.test.js: -------------------------------------------------------------------------------- 1 | import { NQueen } from '../NQueen' 2 | 3 | describe('NQueen', () => { 4 | it('should return 2 solutions for 4x4 size board', () => { 5 | const _4Queen = new NQueen(4) 6 | _4Queen.solve() 7 | expect(_4Queen.solutionCount).toEqual(2) 8 | }) 9 | 10 | it('should return 92 solutions for 8x8 size board', () => { 11 | const _8Queen = new NQueen(8) 12 | _8Queen.solve() 13 | expect(_8Queen.solutionCount).toEqual(92) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Backtracking/tests/SumOfSubset.test.js: -------------------------------------------------------------------------------- 1 | import { sumOfSubset } from '../SumOfSubset' 2 | 3 | describe('SumOfSubset', () => { 4 | it('should return the subsets that add up to the given number', () => { 5 | // W = [2, 5, 7, 8, 12, 16, 23, 40] 6 | // K = 25 7 | 8 | const nums = [2, 5, 7, 8, 12, 16, 23, 40] 9 | 10 | const subsets = sumOfSubset(nums, [], 0, 0, 25) 11 | 12 | expect(subsets).toEqual([ 13 | [2, 7, 16], 14 | [2, 23], 15 | [5, 8, 12] 16 | ]) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Bit-Manipulation/BinaryCountSetBits.js: -------------------------------------------------------------------------------- 1 | /* 2 | author: vivek9patel 3 | license: GPL-3.0 or later 4 | 5 | This script will find number of 1's 6 | in binary representation of given number 7 | 8 | */ 9 | 10 | function BinaryCountSetBits (a) { 11 | 'use strict' 12 | // convert number into binary representation and return number of set bits in binary representation 13 | return a.toString(2).split('1').length - 1 14 | } 15 | 16 | export { BinaryCountSetBits } 17 | -------------------------------------------------------------------------------- /Bit-Manipulation/NextPowerOfTwo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * This script will find next power of two 4 | * of given number. 5 | * More about it: 6 | * https://www.techiedelight.com/round-next-highest-power-2/ 7 | * 8 | */ 9 | 10 | export const nextPowerOfTwo = (n) => { 11 | if (n > 0 && (n & (n - 1)) === 0) return n 12 | let result = 1 13 | while (n > 0) { 14 | result = result << 1 15 | n = n >> 1 16 | } 17 | return result 18 | } 19 | -------------------------------------------------------------------------------- /Bit-Manipulation/SetBit.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Setting Bit: https://www.geeksforgeeks.org/set-k-th-bit-given-number/ 3 | * 4 | * To set any bit we use bitwise OR (|) operator. 5 | * 6 | * Bitwise OR (|) compares the bits of the 32 7 | * bit binary representations of the number and 8 | * returns a number after comparing each bit. 9 | * 10 | * 0 | 0 -> 0 11 | * 0 | 1 -> 1 12 | * 1 | 0 -> 1 13 | * 1 | 1 -> 1 14 | * 15 | * In-order to set kth bit of a number (where k is the position where bit is to be changed) 16 | * we need to shift 1 k times to its left and then perform bitwise OR operation with the 17 | * number and result of left shift performed just before. 18 | * 19 | * References: 20 | * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR 21 | */ 22 | 23 | /** 24 | * @param {number} number 25 | * @param {number} bitPosition - zero based. 26 | * @return {number} 27 | */ 28 | 29 | export const setBit = (number, bitPosition) => { 30 | return number | (1 << bitPosition) 31 | } 32 | -------------------------------------------------------------------------------- /Bit-Manipulation/test/BinaryCountSetBits.test.js: -------------------------------------------------------------------------------- 1 | import { BinaryCountSetBits } from '../BinaryCountSetBits' 2 | 3 | test('check BinaryCountSetBits of 25 is 3', () => { 4 | const res = BinaryCountSetBits(25) 5 | expect(res).toBe(3) 6 | }) 7 | test('check BinaryCountSetBits of 36 is 2', () => { 8 | const res = BinaryCountSetBits(36) 9 | expect(res).toBe(2) 10 | }) 11 | test('check BinaryCountSetBits of 16 is 1', () => { 12 | const res = BinaryCountSetBits(16) 13 | expect(res).toBe(1) 14 | }) 15 | test('check BinaryCountSetBits of 58 is 4', () => { 16 | const res = BinaryCountSetBits(58) 17 | expect(res).toBe(4) 18 | }) 19 | test('check BinaryCountSetBits of 4294967295 is 32', () => { 20 | const res = BinaryCountSetBits(4294967295) 21 | expect(res).toBe(32) 22 | }) 23 | test('check BinaryCountSetBits of 0 is 0', () => { 24 | const res = BinaryCountSetBits(0) 25 | expect(res).toBe(0) 26 | }) 27 | -------------------------------------------------------------------------------- /Bit-Manipulation/test/IsPowerOfTwo.test.js: -------------------------------------------------------------------------------- 1 | import { IsPowerOfTwo } from '../IsPowerOfTwo' 2 | 3 | test('Check if 0 is a power of 2 or not:', () => { 4 | const res = IsPowerOfTwo(0) 5 | expect(res).toBe(false) 6 | }) 7 | 8 | test('Check if 1 is a power of 2 or not:', () => { 9 | const res = IsPowerOfTwo(1) 10 | expect(res).toBe(true) 11 | }) 12 | 13 | test('Check if 4 is a power of 2 or not:', () => { 14 | const res = IsPowerOfTwo(4) 15 | expect(res).toBe(true) 16 | }) 17 | 18 | test('Check if 1024 is a power of 2 or not:', () => { 19 | const res = IsPowerOfTwo(1024) 20 | expect(res).toBe(true) 21 | }) 22 | 23 | test('Check if 1025 is a power of 2 or not:', () => { 24 | const res = IsPowerOfTwo(1025) 25 | expect(res).toBe(false) 26 | }) 27 | -------------------------------------------------------------------------------- /Bit-Manipulation/test/NextPowerOfTwo.test.js: -------------------------------------------------------------------------------- 1 | import { nextPowerOfTwo } from '../NextPowerOfTwo' 2 | 3 | describe('NextPowerOfTwo', () => { 4 | it.each` 5 | input | result 6 | ${0} | ${1} 7 | ${1} | ${1} 8 | ${2} | ${2} 9 | ${3} | ${4} 10 | ${5} | ${8} 11 | ${125} | ${128} 12 | ${1024} | ${1024} 13 | ${10000} | ${16384} 14 | `('returns $result when is given $input', ({ input, result }) => { 15 | const res = nextPowerOfTwo(input) 16 | expect(res).toBe(result) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Bit-Manipulation/test/SetBit.test.js: -------------------------------------------------------------------------------- 1 | import { setBit } from '../SetBit' 2 | 3 | test('Set bit number 0 in 1:', () => { 4 | const setBitPos = setBit(1, 0) 5 | expect(setBitPos).toBe(1) 6 | }) 7 | 8 | test('Set bit number 0 in 2:', () => { 9 | const setBitPos = setBit(2, 0) 10 | expect(setBitPos).toBe(3) 11 | }) 12 | 13 | test('Set bit number 1 in 10:', () => { 14 | const setBitPos = setBit(10, 1) 15 | expect(setBitPos).toBe(10) 16 | }) 17 | 18 | test('Set bit number 2 in 10:', () => { 19 | const setBitPos = setBit(10, 2) 20 | expect(setBitPos).toBe(14) 21 | }) 22 | -------------------------------------------------------------------------------- /Cache/test/cacheTest.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function fibonacciCache 3 | * @description - this is a cached variant of fib number 4 | * @param {number} n - Real number (n > -1) 5 | * @param {Object} cache 6 | * @returns {number} 7 | */ 8 | export const fibonacciCache = (n, cache = null) => { 9 | if (cache) { 10 | const value = cache.get(n) 11 | 12 | if (value !== null) { 13 | return value 14 | } 15 | } 16 | 17 | if (n === 1 || n === 2) { 18 | return 1 19 | } 20 | 21 | const result = fibonacciCache(n - 1, cache) + fibonacciCache(n - 2, cache) 22 | 23 | cache && cache.set(n, result) 24 | 25 | return result 26 | } 27 | 28 | /** 29 | * @title implementation of union function 30 | * @param {Set} sets 31 | * @return {new Set} 32 | */ 33 | export const union = (...sets) => { 34 | return new Set( 35 | sets.reduce((flatArray, set) => [...flatArray, ...set], []) 36 | ) 37 | } 38 | -------------------------------------------------------------------------------- /Cellular-Automata/test/ConwaysGameOfLife.test.js: -------------------------------------------------------------------------------- 1 | import { newGeneration } from '../ConwaysGameOfLife' 2 | 3 | describe('newGeneration', () => { 4 | it('should produce the next generation according to the rules', () => { 5 | expect(newGeneration([[0, 1, 0], [0, 1, 0], [0, 1, 0]])) 6 | .toEqual([[0, 0, 0], [1, 1, 1], [0, 0, 0]]) 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /Ciphers/Atbash.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function Atbash - Decrypt a Atbash cipher 3 | * @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. 4 | * @param {string} str - string to be decrypted/encrypt 5 | * @return {string} decrypted/encrypted string 6 | * @see - [wiki](https://en.wikipedia.org/wiki/Atbash) 7 | */ 8 | const Atbash = (str) => { 9 | if (typeof str !== 'string') { 10 | throw new TypeError('Argument should be string') 11 | } 12 | 13 | return str.replace(/[a-z]/gi, (char) => { 14 | const charCode = char.charCodeAt() 15 | 16 | if (/[A-Z]/.test(char)) { 17 | return String.fromCharCode(90 + 65 - charCode) 18 | } 19 | 20 | return String.fromCharCode(122 + 97 - charCode) 21 | }) 22 | } 23 | 24 | export default Atbash 25 | -------------------------------------------------------------------------------- /Ciphers/XORCipher.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function XORCipher 3 | * @description - Encrypt using an XOR cipher 4 | * The XOR cipher is a type of additive cipher. 5 | * Each character is bitwise XORed with the key. 6 | * We loop through the input string, XORing each 7 | * character with the key. 8 | * @param {string} str - string to be encrypted 9 | * @param {number} key - key for encryption 10 | * @return {string} encrypted string 11 | */ 12 | const XORCipher = (str, key) => { 13 | if (typeof str !== 'string' || !Number.isInteger(key)) { 14 | throw new TypeError('Arguments type are invalid') 15 | } 16 | 17 | return str.replace( 18 | /./g, (char) => String.fromCharCode(char.charCodeAt() ^ key) 19 | ) 20 | } 21 | 22 | export default XORCipher 23 | -------------------------------------------------------------------------------- /Ciphers/test/Atbash.test.js: -------------------------------------------------------------------------------- 1 | import Atbash from '../Atbash' 2 | 3 | describe('Testing Atbash function', () => { 4 | it('Test - 1, passing a non-string as an argument', () => { 5 | expect(() => Atbash(0x345)).toThrow() 6 | expect(() => Atbash(123)).toThrow() 7 | expect(() => Atbash(123n)).toThrow() 8 | expect(() => Atbash(false)).toThrow() 9 | expect(() => Atbash({})).toThrow() 10 | expect(() => Atbash([])).toThrow() 11 | }) 12 | 13 | it('Test - 2, passing a string as an argument', () => { 14 | const clearText = 'The quick brown fox jumps over the lazy dog' 15 | const cryptText = Atbash(clearText) 16 | expect(Atbash(cryptText)).toBe(clearText) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Ciphers/test/CaesarsCipher.test.js: -------------------------------------------------------------------------------- 1 | import caesarsCipher from '../CaesarsCipher' 2 | 3 | describe('Testing the caesarsCipher function', () => { 4 | it('Test - 1, Testing for invalid types', () => { 5 | expect(() => caesarsCipher(false, 3)).toThrow() 6 | expect(() => caesarsCipher('false', -1)).toThrow() 7 | expect(() => caesarsCipher('true', null)).toThrow() 8 | }) 9 | 10 | it('Test - 2, Testing for valid string and rotation', () => { 11 | expect(caesarsCipher('middle-Outz', 2)).toBe('okffng-Qwvb') 12 | expect(caesarsCipher('abcdefghijklmnopqrstuvwxyz', 3)).toBe('defghijklmnopqrstuvwxyzabc') 13 | expect(caesarsCipher('Always-Look-on-the-Bright-Side-of-Life', 5)).toBe('Fqbfdx-Qttp-ts-ymj-Gwnlmy-Xnij-tk-Qnkj') 14 | expect(caesarsCipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG', 23)).toBe('QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD') 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Ciphers/test/KeywordShiftedAlphabet.test.js: -------------------------------------------------------------------------------- 1 | import { encrypt, decrypt } from '../KeywordShiftedAlphabet' 2 | 3 | test('Hello world! === dcrypt(encrypt(Hello world!))', () => { 4 | const word = 'Hello world!' 5 | const result = decrypt('keyword', encrypt('keyword', word)) 6 | expect(result).toMatch(word) 7 | }) 8 | 9 | test('The Algorithms === dcrypt(encrypt(The Algorithms))', () => { 10 | const word = 'The Algorithms' 11 | const result = decrypt('keyword', encrypt('keyword', word)) 12 | expect(result).toMatch(word) 13 | }) 14 | -------------------------------------------------------------------------------- /Ciphers/test/ROT13.test.js: -------------------------------------------------------------------------------- 1 | import ROT13 from '../ROT13' 2 | 3 | describe('Testing ROT13 function', () => { 4 | it('Test - 1, passing a non-string as an argument', () => { 5 | expect(() => ROT13(0x345)).toThrow() 6 | expect(() => ROT13(123)).toThrow() 7 | expect(() => ROT13(123n)).toThrow() 8 | expect(() => ROT13(false)).toThrow() 9 | expect(() => ROT13({})).toThrow() 10 | expect(() => ROT13([])).toThrow() 11 | }) 12 | 13 | it('Test - 2, passing a string as an argument', () => { 14 | expect(ROT13('Uryyb Jbeyq')).toBe('Hello World') 15 | expect(ROT13('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')).toBe('NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm') 16 | expect(ROT13('The quick brown fox jumps over the lazy dog')).toBe('Gur dhvpx oebja sbk whzcf bire gur ynml qbt') 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Ciphers/test/VigenereCipher.test.js: -------------------------------------------------------------------------------- 1 | import { encrypt, decrypt } from '../VigenereCipher' 2 | 3 | test('Hello world! === dcrypt(encrypt(Hello world!))', () => { 4 | const word = 'Hello world!' 5 | const result = decrypt(encrypt(word, 'code'), 'code') 6 | expect(result).toMatch(word) 7 | }) 8 | 9 | test('The Algorithms === dcrypt(encrypt(The Algorithms))', () => { 10 | const word = 'The Algorithms' 11 | const result = decrypt(encrypt(word, 'code'), 'code') 12 | expect(result).toMatch(word) 13 | }) 14 | -------------------------------------------------------------------------------- /Ciphers/test/XORCipher.test.js: -------------------------------------------------------------------------------- 1 | import XORCipher from '../XORCipher' 2 | 3 | describe('Testing XORCipher function', () => { 4 | it('Test - 1, passing a non-string as an argument', () => { 5 | expect(() => XORCipher(false, 0x345)).toThrow() 6 | expect(() => XORCipher(true, 123)).toThrow() 7 | expect(() => XORCipher(1n, 123n)).toThrow() 8 | expect(() => XORCipher(false, 0.34)).toThrow() 9 | expect(() => XORCipher({})).toThrow() 10 | expect(() => XORCipher([])).toThrow() 11 | }) 12 | 13 | it('Test - 2, passing a string & number as an argument', () => { 14 | // NB: Node REPL might not output the null char '\x00' (charcode 0) 15 | expect(XORCipher('test string', 32)).toBe('TEST\x00STRING') 16 | expect(XORCipher('TEST\x00STRING', 32)).toBe('test string') 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Conversions/BinaryToDecimal.js: -------------------------------------------------------------------------------- 1 | export default function binaryToDecimal (binaryString) { 2 | let decimalNumber = 0 3 | const binaryDigits = binaryString.split('').reverse() // Splits the binary number into reversed single digits 4 | binaryDigits.forEach((binaryDigit, index) => { 5 | decimalNumber += binaryDigit * (Math.pow(2, index)) // Summation of all the decimal converted digits 6 | }) 7 | return decimalNumber 8 | } 9 | -------------------------------------------------------------------------------- /Conversions/DecimalToBinary.js: -------------------------------------------------------------------------------- 1 | function decimalToBinary (num) { 2 | const bin = [] 3 | while (num > 0) { 4 | bin.unshift(num % 2) 5 | num >>= 1 // basically /= 2 without remainder if any 6 | } 7 | return bin.join('') 8 | } 9 | 10 | export { decimalToBinary } 11 | 12 | // > decimalToBinary(2) 13 | // '10' 14 | 15 | // > decimalToBinary(7) 16 | // '111' 17 | 18 | // > decimalToBinary(35) 19 | // '100011' 20 | -------------------------------------------------------------------------------- /Conversions/DecimalToHex.js: -------------------------------------------------------------------------------- 1 | function intToHex (num) { 2 | switch (num) { 3 | case 10: return 'A' 4 | case 11: return 'B' 5 | case 12: return 'C' 6 | case 13: return 'D' 7 | case 14: return 'E' 8 | case 15: return 'F' 9 | } 10 | return num 11 | } 12 | 13 | function decimalToHex (num) { 14 | const hexOut = [] 15 | while (num > 15) { 16 | hexOut.unshift(intToHex(num % 16)) 17 | num = Math.floor(num / 16) 18 | } 19 | return intToHex(num) + hexOut.join('') 20 | } 21 | 22 | export { decimalToHex } 23 | -------------------------------------------------------------------------------- /Conversions/DecimalToOctal.js: -------------------------------------------------------------------------------- 1 | function decimalToOctal (num) { 2 | let oct = 0 3 | let c = 0 4 | while (num > 0) { 5 | const r = num % 8 6 | oct = oct + (r * Math.pow(10, c++)) 7 | num = Math.floor(num / 8) // basically /= 8 without remainder if any 8 | } 9 | return oct 10 | } 11 | 12 | export { decimalToOctal } 13 | 14 | // > decimalToOctal(2) 15 | // 2 16 | 17 | // > decimalToOctal(8) 18 | // 10 19 | 20 | // > decimalToOctal(65) 21 | // 101 22 | 23 | // > decimalToOctal(216) 24 | // 330 25 | 26 | // > decimalToOctal(512) 27 | // 1000 28 | -------------------------------------------------------------------------------- /Conversions/DecimalToRoman.js: -------------------------------------------------------------------------------- 1 | /* 2 | Decimal To Roman 3 | 4 | This algorithm take decimal number and convert to roman numeral according to standard form (https://en.wikipedia.org/wiki/Roman_numerals#Description) 5 | 6 | Algorithm & Explanation : https://www.rapidtables.com/convert/number/how-number-to-roman-numerals.html 7 | */ 8 | 9 | const values = { 10 | M: 1000, 11 | CM: 900, 12 | D: 500, 13 | CD: 400, 14 | C: 100, 15 | XC: 90, 16 | L: 50, 17 | XL: 40, 18 | X: 10, 19 | IX: 9, 20 | V: 5, 21 | IV: 4, 22 | I: 1 23 | } 24 | 25 | const orders = [ 26 | 'M', 27 | 'CM', 28 | 'D', 29 | 'CD', 30 | 'C', 31 | 'XC', 32 | 'L', 33 | 'XL', 34 | 'X', 35 | 'IX', 36 | 'V', 37 | 'IV', 38 | 'I' 39 | ] 40 | 41 | function decimalToRoman (num) { 42 | let roman = '' 43 | for (const symbol of orders) { 44 | while (num >= values[symbol]) { 45 | roman += symbol 46 | num -= values[symbol] 47 | } 48 | } 49 | return roman 50 | } 51 | 52 | export { decimalToRoman } 53 | -------------------------------------------------------------------------------- /Conversions/HexToDecimal.js: -------------------------------------------------------------------------------- 1 | function hexToInt (hexNum) { 2 | const numArr = hexNum.split('') // converts number to array 3 | return numArr.map((item, index) => { 4 | switch (item) { 5 | case 'A': return 10 6 | case 'B': return 11 7 | case 'C': return 12 8 | case 'D': return 13 9 | case 'E': return 14 10 | case 'F': return 15 11 | default: return parseInt(item) 12 | } 13 | }) 14 | } 15 | 16 | function hexToDecimal (hexNum) { 17 | const intItemsArr = hexToInt(hexNum) 18 | return intItemsArr.reduce((accumulator, current, index) => { 19 | return accumulator + (current * Math.pow(16, (intItemsArr.length - (1 + index)))) 20 | }, 0) 21 | } 22 | 23 | export { hexToInt, hexToDecimal } 24 | -------------------------------------------------------------------------------- /Conversions/HexToRGB.js: -------------------------------------------------------------------------------- 1 | function hexStringToRGB (hexString) { 2 | let r = hexString.substring(0, 2) 3 | let g = hexString.substring(2, 4) 4 | let b = hexString.substring(4, 6) 5 | 6 | r = parseInt(r, 16) 7 | g = parseInt(g, 16) 8 | b = parseInt(b, 16) 9 | const obj = { r, g, b } 10 | 11 | return obj 12 | } 13 | 14 | export { hexStringToRGB } 15 | 16 | // > hexStringToRGB('ffffff') 17 | // { r: 255, g: 255, b: 255 } 18 | -------------------------------------------------------------------------------- /Conversions/MeterToFeetConversion.js: -------------------------------------------------------------------------------- 1 | // Foot: https://en.wikipedia.org/wiki/Foot_(unit) 2 | const feetToMeter = (feet) => { 3 | return feet * 0.3048 4 | } 5 | 6 | const meterToFeet = (meter) => { 7 | return meter / 0.3048 8 | } 9 | 10 | export { feetToMeter, meterToFeet } 11 | -------------------------------------------------------------------------------- /Conversions/OctToDecimal.js: -------------------------------------------------------------------------------- 1 | function octalToDecimal (num) { 2 | let dec = 0 3 | let base = 1 4 | while (num > 0) { 5 | const r = num % 10 6 | num = Math.floor(num / 10) 7 | dec = dec + (r * base) 8 | base = base * 8 9 | } 10 | return dec 11 | } 12 | 13 | export { octalToDecimal } 14 | 15 | // > octalToDecimal(56) 16 | // 46 17 | 18 | // > octalToDecimal(2365) 19 | // 1269 20 | -------------------------------------------------------------------------------- /Conversions/RGBToHex.js: -------------------------------------------------------------------------------- 1 | function RGBToHex (r, g, b) { 2 | if ( 3 | typeof r !== 'number' || 4 | typeof g !== 'number' || 5 | typeof b !== 'number' 6 | ) { 7 | throw new TypeError('argument is not a Number') 8 | } 9 | 10 | const toHex = n => (n || '0').toString(16).padStart(2, '0') 11 | 12 | return `#${toHex(r)}${toHex(g)}${toHex(b)}` 13 | } 14 | 15 | export { RGBToHex } 16 | 17 | // > RGBToHex(255, 255, 255) 18 | // '#ffffff' 19 | 20 | // > RGBToHex(255, 99, 71) 21 | // '#ff6347' 22 | -------------------------------------------------------------------------------- /Conversions/RomanToDecimal.js: -------------------------------------------------------------------------------- 1 | const values = { 2 | I: 1, 3 | V: 5, 4 | X: 10, 5 | L: 50, 6 | C: 100, 7 | D: 500, 8 | M: 1000 9 | } 10 | 11 | export function romanToDecimal (romanNumber) { 12 | let prev = ' ' 13 | 14 | let sum = 0 15 | 16 | let newPrev = 0 17 | for (let i = romanNumber.length - 1; i >= 0; i--) { 18 | const c = romanNumber.charAt(i) 19 | 20 | if (prev !== ' ') { 21 | newPrev = values[prev] > newPrev ? values[prev] : newPrev 22 | } 23 | 24 | const currentNum = values[c] 25 | if (currentNum >= newPrev) { 26 | sum += currentNum 27 | } else { 28 | sum -= currentNum 29 | } 30 | 31 | prev = c 32 | } 33 | return sum 34 | } 35 | -------------------------------------------------------------------------------- /Conversions/test/BinaryToDecimal.test.js: -------------------------------------------------------------------------------- 1 | import binaryToDecimal from '../BinaryToDecimal' 2 | 3 | describe('BinaryToDecimal', () => { 4 | it('expects to return correct decimal value', () => { 5 | expect(binaryToDecimal('1000')).toBe(8) 6 | }) 7 | 8 | it('expects to return correct hexadecimal value for more than one hex digit', () => { 9 | expect(binaryToDecimal('01101000')).toBe(104) 10 | }) 11 | 12 | it('expects to return correct hexadecimal value for padding-required binary', () => { 13 | expect(binaryToDecimal('1000101')).toBe(69) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Conversions/test/BinaryToHex.test.js: -------------------------------------------------------------------------------- 1 | import binaryToHex from '../BinaryToHex' 2 | 3 | describe('BinaryToHex', () => { 4 | it('expects to return correct hexadecimal value', () => { 5 | expect(binaryToHex('1000')).toBe('8') 6 | }) 7 | 8 | it('expects to return correct hexadecimal value for more than one hex digit', () => { 9 | expect(binaryToHex('11101010')).toBe('EA') 10 | }) 11 | 12 | it('expects to return correct hexadecimal value for padding-required binary', () => { 13 | expect(binaryToHex('1001101')).toBe('4D') 14 | }) 15 | 16 | it('expects to return correct hexadecimal value, matching (num).toString(16)', () => { 17 | expect(binaryToHex('1111')).toBe(parseInt('1111', 2).toString(16).toUpperCase()) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Conversions/test/DateDayDiffernce.test.js: -------------------------------------------------------------------------------- 1 | import { DateDayDifference } from '../DateDayDifference' 2 | 3 | test('The difference between 17/08/2002 & 10/10/2020 is 6630', () => { 4 | const res = DateDayDifference('17/08/2002', '10/10/2020') 5 | expect(res).toBe(6630) 6 | }) 7 | 8 | test('The difference between 18/02/2001 & 16/03/2022 is 7696', () => { 9 | const res = DateDayDifference('18/02/2001', '16/03/2022') 10 | expect(res).toBe(7696) 11 | }) 12 | 13 | test('The difference between 11/11/2011 & 12/12/2012 is 398', () => { 14 | const res = DateDayDifference('11/11/2011', '12/12/2012') 15 | expect(res).toBe(398) 16 | }) 17 | 18 | test('The difference between 01/01/2001 & 16/03/2011 is 3727', () => { 19 | const res = DateDayDifference('01/01/2001', '16/03/2011') 20 | expect(res).toBe(3727) 21 | }) 22 | -------------------------------------------------------------------------------- /Conversions/test/DateToDay.test.js: -------------------------------------------------------------------------------- 1 | import { DateToDay } from '../DateToDay' 2 | 3 | test('The date 18/02/2001 is Monday', () => { 4 | const res = DateToDay('18/02/2001') 5 | expect(res).toBe('Monday') 6 | }) 7 | 8 | test('The date 18/12/2020 is Friday', () => { 9 | const res = DateToDay('18/12/2020') 10 | expect(res).toBe('Friday') 11 | }) 12 | 13 | test('The date 12/12/2012 is Wednesday', () => { 14 | const res = DateToDay('12/12/2012') 15 | expect(res).toBe('Wednesday') 16 | }) 17 | test('The date 01/01/2001 is Friday', () => { 18 | const res = DateToDay('01/01/2001') 19 | expect(res).toBe('Friday') 20 | }) 21 | -------------------------------------------------------------------------------- /Conversions/test/DecimalToBinary.test.js: -------------------------------------------------------------------------------- 1 | import { decimalToBinary } from '../DecimalToBinary' 2 | 3 | test('The Binary representation of 35 is 100011', () => { 4 | const res = decimalToBinary(35) 5 | expect(res).toBe('100011') 6 | }) 7 | 8 | test('The Binary representation of 1 is 1', () => { 9 | const res = decimalToBinary(1) 10 | expect(res).toBe('1') 11 | }) 12 | 13 | test('The Binary representation of 1000 is 1111101000', () => { 14 | const res = decimalToBinary(1000) 15 | expect(res).toBe('1111101000') 16 | }) 17 | 18 | test('The Binary representation of 2 is 10', () => { 19 | const res = decimalToBinary(2) 20 | expect(res).toBe('10') 21 | }) 22 | 23 | test('The Binary representation of 17 is 10001', () => { 24 | const res = decimalToBinary(17) 25 | expect(res).toBe('10001') 26 | }) 27 | -------------------------------------------------------------------------------- /Conversions/test/DecimalToHex.test.js: -------------------------------------------------------------------------------- 1 | import { decimalToHex } from '../DecimalToHex' 2 | 3 | describe('DecimalToHex', () => { 4 | it('expects to return correct hexadecimal value', () => { 5 | expect(decimalToHex(255)).toBe('FF') 6 | }) 7 | 8 | it('expects to return correct hexadecimal value, matching (num).toString(16)', () => { 9 | expect(decimalToHex(32768)).toBe((32768).toString(16).toUpperCase()) 10 | }) 11 | 12 | it('expects to not handle negative numbers', () => { 13 | expect(decimalToHex(-32768)).not.toBe((-32768).toString(16).toUpperCase()) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Conversions/test/DecimalToOctal.test.js: -------------------------------------------------------------------------------- 1 | import { decimalToOctal } from '../DecimalToOctal' 2 | 3 | test('The Octal representation of 8 is 10', () => { 4 | const res = decimalToOctal(8) 5 | expect(res).toBe(10) 6 | }) 7 | 8 | test('The Octal representation of 1 is 1', () => { 9 | const res = decimalToOctal(1) 10 | expect(res).toBe(1) 11 | }) 12 | 13 | test('The Octal representation of 0 is 0', () => { 14 | const res = decimalToOctal(0) 15 | expect(res).toBe(0) 16 | }) 17 | 18 | test('The Octal representation of 100 is 144', () => { 19 | const res = decimalToOctal(100) 20 | expect(res).toBe(144) 21 | }) 22 | 23 | test('The Octal representation of 111 is 157', () => { 24 | const res = decimalToOctal(111) 25 | expect(res).toBe(157) 26 | }) 27 | -------------------------------------------------------------------------------- /Conversions/test/DecimalToRoman.test.js: -------------------------------------------------------------------------------- 1 | import { decimalToRoman } from '../DecimalToRoman' 2 | 3 | describe('decimalToRoman', () => { 4 | it('expects to return correct roman numeral of given number', () => { 5 | expect(decimalToRoman(34)).toBe('XXXIV') 6 | }) 7 | it('expects to return correct roman numeral of given number', () => { 8 | expect(decimalToRoman(28)).toBe('XXVIII') 9 | }) 10 | it('expects to return correct roman numeral of given number', () => { 11 | expect(decimalToRoman(2021)).toBe('MMXXI') 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /Conversions/test/HexToRGB.test.js: -------------------------------------------------------------------------------- 1 | import { hexStringToRGB } from '../HexToRGB' 2 | 3 | test('The RGB form of Hex String E1E1E1 is {r: 225, g: 225, b: 225}', () => { 4 | const res = hexStringToRGB('E1E1E1') 5 | expect(res).toEqual({ r: 225, g: 225, b: 225 }) 6 | }) 7 | 8 | test('The RGB form of Hex String 000000 is {r: 0, g: 0, b: 0}', () => { 9 | const res = hexStringToRGB('000000') 10 | expect(res).toEqual({ r: 0, g: 0, b: 0 }) 11 | }) 12 | 13 | test('The RGB form of Hex String 6CE1CD is {r: 108, g: 225, b: 205}', () => { 14 | const res = hexStringToRGB('6CE1CD') 15 | expect(res).toEqual({ r: 108, g: 225, b: 205 }) 16 | }) 17 | -------------------------------------------------------------------------------- /Conversions/test/LowerCaseConversion.test.js: -------------------------------------------------------------------------------- 1 | import { LowerCaseConversion } from '../LowerCaseConversion' 2 | 3 | test('The LowerCaseConversion of ApoLO is apolo', () => { 4 | const res = LowerCaseConversion('ApoLO') 5 | expect(res).toBe('apolo') 6 | }) 7 | 8 | test('The LowerCaseConversion of WEB is web', () => { 9 | const res = LowerCaseConversion('WEB') 10 | expect(res).toBe('web') 11 | }) 12 | 13 | test('The LowerCaseConversion of EaRTh is earth', () => { 14 | const res = LowerCaseConversion('EaRTh') 15 | expect(res).toBe('earth') 16 | }) 17 | 18 | test('The LowerCaseConversion of TiGER is tiger', () => { 19 | const res = LowerCaseConversion('TiGER') 20 | expect(res).toBe('tiger') 21 | }) 22 | 23 | test('The LowerCaseConversion of Cricket is cricket', () => { 24 | const res = LowerCaseConversion('Cricket') 25 | expect(res).toBe('cricket') 26 | }) 27 | -------------------------------------------------------------------------------- /Conversions/test/MeterToFeetConversion.test.js: -------------------------------------------------------------------------------- 1 | import { meterToFeet, feetToMeter } from '../MeterToFeetConversion' 2 | 3 | describe('Testing conversion of Meter to Feet', () => { 4 | it('with feet value', () => { 5 | expect(meterToFeet(30.48)).toBe(100) 6 | }) 7 | }) 8 | 9 | describe('Testing conversion of Feet to Meter', () => { 10 | it('with feet value', () => { 11 | expect(feetToMeter(10)).toBe(3.048) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /Conversions/test/OctToDecimal.test.js: -------------------------------------------------------------------------------- 1 | import { octalToDecimal } from '../OctToDecimal' 2 | 3 | test('The Decimal representation of Octal number 56 is 46', () => { 4 | const res = octalToDecimal(56) 5 | expect(res).toBe(46) 6 | }) 7 | 8 | test('The Decimal representation of Octal number 99 is 81', () => { 9 | const res = octalToDecimal(99) 10 | expect(res).toBe(81) 11 | }) 12 | 13 | test('The Decimal representation of Octal number 17 is 15', () => { 14 | const res = octalToDecimal(17) 15 | expect(res).toBe(15) 16 | }) 17 | 18 | test('The Decimal representation of Octal number 100 is 64', () => { 19 | const res = octalToDecimal(100) 20 | expect(res).toBe(64) 21 | }) 22 | 23 | test('The Decimal representation of Octal number 0 is 0', () => { 24 | const res = octalToDecimal(0) 25 | expect(res).toBe(0) 26 | }) 27 | -------------------------------------------------------------------------------- /Conversions/test/RGBToHex.test.js: -------------------------------------------------------------------------------- 1 | import { RGBToHex } from '../RGBToHex' 2 | 3 | test('The Hex format of RGB (225, 225, 225) is #ffffff', () => { 4 | const res = RGBToHex(255, 255, 255) 5 | expect(res).toBe('#ffffff') 6 | }) 7 | 8 | test('The Hex format of RGB (190, 108, 217) is #be6cd9', () => { 9 | const res = RGBToHex(190, 108, 217) 10 | expect(res).toBe('#be6cd9') 11 | }) 12 | 13 | test('The Hex format of RGB (255, 99, 71) is #ff6347', () => { 14 | const res = RGBToHex(255, 99, 71) 15 | expect(res).toBe('#ff6347') 16 | }) 17 | 18 | test('The Hex format of RGB (100, 108, 217) is #646cd9', () => { 19 | const res = RGBToHex(100, 108, 217) 20 | expect(res).toBe('#646cd9') 21 | }) 22 | -------------------------------------------------------------------------------- /Conversions/test/RailwayTimeConversion.test.js: -------------------------------------------------------------------------------- 1 | import { RailwayTimeConversion } from '../RailwayTimeConversion' 2 | 3 | test('The RailwayTimeConversion of 07:05:45AM is 07:05:45', () => { 4 | const res = RailwayTimeConversion('07:05:45AM') 5 | expect(res).toEqual('07:05:45') 6 | }) 7 | 8 | test('The RailwayTimeConversion of 07:05:45PM is 19:05:45', () => { 9 | const res = RailwayTimeConversion('07:05:45PM') 10 | expect(res).toEqual('19:05:45') 11 | }) 12 | 13 | test('The RailwayTimeConversion of 10:20:00AM is 10:20:00', () => { 14 | const res = RailwayTimeConversion('10:20:00AM') 15 | expect(res).toEqual('10:20:00') 16 | }) 17 | 18 | test('The RailwayTimeConversion of 11:20:00PM is 23:20:00', () => { 19 | const res = RailwayTimeConversion('11:20:00PM') 20 | expect(res).toEqual('23:20:00') 21 | }) 22 | -------------------------------------------------------------------------------- /Conversions/test/RomanToDecimal.test.js: -------------------------------------------------------------------------------- 1 | import { romanToDecimal } from '../RomanToDecimal' 2 | 3 | describe('romanToDecimal', () => { 4 | it('XXIIVV', () => { 5 | expect(romanToDecimal('XXIIVV')).toBe(28) 6 | }) 7 | 8 | it('MDCCCIV', () => { 9 | expect(romanToDecimal('MDCCCIV')).toBe(1804) 10 | }) 11 | 12 | it('XXIVI', () => { 13 | expect(romanToDecimal('XXIVI')).toBe(25) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Data-Structures/Linked-List/CycleDetection.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A LinkedList based solution for Detect a Cycle in a list 3 | * https://en.wikipedia.org/wiki/Cycle_detection 4 | */ 5 | 6 | function main () { 7 | /* 8 | Problem Statement: 9 | Given head, the head of a linked list, determine if the linked list has a cycle in it. 10 | 11 | Note: 12 | * While Solving the problem in given link below, don't use main() function. 13 | * Just use only the code inside main() function. 14 | * The purpose of using main() function here is to avoid global variables. 15 | 16 | Link for the Problem: https://leetcode.com/problems/linked-list-cycle/ 17 | */ 18 | const head = '' // Reference to head is given in the problem. So please ignore this line 19 | let fast = head 20 | let slow = head 21 | 22 | while (fast != null && fast.next != null && slow != null) { 23 | fast = fast.next.next 24 | slow = slow.next 25 | if (fast === slow) { 26 | return true 27 | } 28 | } 29 | return false 30 | } 31 | 32 | main() 33 | -------------------------------------------------------------------------------- /Data-Structures/Linked-List/test/AddTwoNumbers.test.js: -------------------------------------------------------------------------------- 1 | import { AddTwoNumbers } from '../AddTwoNumbers.js' 2 | import { LinkedList } from '../SinglyLinkedList' 3 | 4 | describe('AddTwoNumbers', () => { 5 | it('Check Sum Of Two Linked List', () => { 6 | const list1 = new LinkedList() 7 | list1.addFirst(2) 8 | list1.addLast(4) 9 | list1.addLast(3) 10 | 11 | const list2 = new LinkedList() 12 | list2.addFirst(5) 13 | list2.addLast(6) 14 | list2.addLast(4) 15 | 16 | const expected = new LinkedList() 17 | expected.addFirst(7) 18 | expected.addLast(0) 19 | expected.addLast(8) 20 | 21 | const addTwoLinkedList = new AddTwoNumbers() 22 | addTwoLinkedList.solution(list1.headNode, list2.headNode) 23 | 24 | expect(addTwoLinkedList.solutionToArray()).toEqual(expected.get()) 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /Data-Structures/Queue/test/QueueUsing2Stacks.test.js: -------------------------------------------------------------------------------- 1 | import { Queue } from '../QueueUsing2Stacks' 2 | 3 | describe('QueueUsing2Stacks', () => { 4 | const queue = new Queue() 5 | 6 | it('Check enqueue/dequeue', () => { 7 | queue.enqueue(1) 8 | queue.enqueue(2) 9 | queue.enqueue(8) 10 | queue.enqueue(9) 11 | 12 | expect(queue.dequeue()).toBe(1) 13 | expect(queue.dequeue()).toBe(2) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Data-Structures/Tree/test/AVLTree.test.js: -------------------------------------------------------------------------------- 1 | import { AVLTree } from '../AVLTree' 2 | 3 | describe('AVLTree Implementation: ', () => { 4 | const avlTree = new AVLTree() 5 | const dataList = [] 6 | const demoData = [1, 4, 6, 22, 7, 99, 4, 66, 77, 98] 7 | 8 | beforeAll(() => { 9 | demoData.forEach(item => { 10 | if (avlTree.add(item)) { 11 | dataList.push(item) 12 | } 13 | }) 14 | }) 15 | 16 | it('checks if element is inserted properly', () => { 17 | expect(dataList.length).toEqual(avlTree.size) 18 | }) 19 | 20 | it('search if inserted element is present', () => { 21 | demoData.forEach(data => { 22 | expect(avlTree.find(data)).toBeTruthy() 23 | }) 24 | }) 25 | 26 | it('deletes the inserted element', () => { 27 | const deleteElement = dataList[3] 28 | expect(avlTree.remove(deleteElement)).toBeTruthy() 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /Dynamic-Programming/ClimbingStairs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function ClimbStairs 3 | * @description You are climbing a stair case. It takes n steps to reach to the top.Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? 4 | * @param {Integer} n - The input integer 5 | * @return {Integer} distinct ways can you climb to the top. 6 | * @see [Climb_Stairs](https://www.geeksforgeeks.org/count-ways-reach-nth-stair/) 7 | */ 8 | 9 | const climbStairs = (n) => { 10 | let prev = 0 11 | let cur = 1 12 | let temp 13 | 14 | for (let i = 0; i < n; i++) { 15 | temp = prev 16 | prev = cur 17 | cur += temp 18 | } 19 | return cur 20 | } 21 | 22 | export { climbStairs } 23 | -------------------------------------------------------------------------------- /Dynamic-Programming/FibonacciNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function fibonacci 3 | * @description Fibonacci is the sum of previous two fibonacci numbers. 4 | * @param {Integer} N - The input integer 5 | * @return {Integer} fibonacci of N. 6 | * @see [Fibonacci_Numbers](https://en.wikipedia.org/wiki/Fibonacci_number) 7 | */ 8 | const fibonacci = (N) => { 9 | if (!Number.isInteger(N)) { 10 | throw new TypeError('Input should be integer') 11 | } 12 | 13 | // memoize the last two numbers 14 | let firstNumber = 0 15 | let secondNumber = 1 16 | 17 | for (let i = 1; i < N; i++) { 18 | const sumOfNumbers = firstNumber + secondNumber 19 | // update last two numbers 20 | firstNumber = secondNumber 21 | secondNumber = sumOfNumbers 22 | } 23 | 24 | return N ? secondNumber : firstNumber 25 | } 26 | 27 | export { fibonacci } 28 | -------------------------------------------------------------------------------- /Dynamic-Programming/LongestIncreasingSubsequence.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A Dynamic Programming based solution for calculating Longest Increasing Subsequence 3 | * https://en.wikipedia.org/wiki/Longest_increasing_subsequence 4 | */ 5 | 6 | // Return the length of the Longest Increasing Subsequence, given array x 7 | function longestIncreasingSubsequence (x) { 8 | const length = x.length 9 | const dp = Array(length).fill(1) 10 | 11 | let res = 1 12 | 13 | for (let i = 0; i < length; i++) { 14 | for (let j = 0; j < i; j++) { 15 | if (x[i] > x[j]) { 16 | dp[i] = Math.max(dp[i], 1 + dp[j]) 17 | if (dp[i] > res) { 18 | res = dp[i] 19 | } 20 | } 21 | } 22 | } 23 | 24 | return res 25 | } 26 | 27 | export { longestIncreasingSubsequence } 28 | -------------------------------------------------------------------------------- /Dynamic-Programming/LongestPalindromicSubsequence.js: -------------------------------------------------------------------------------- 1 | /* 2 | LeetCode -> https://leetcode.com/problems/longest-palindromic-subsequence/ 3 | 4 | Given a string s, find the longest palindromic subsequence's length in s. 5 | You may assume that the maximum length of s is 1000. 6 | 7 | */ 8 | 9 | export const longestPalindromeSubsequence = function (s) { 10 | const n = s.length 11 | 12 | const dp = new Array(n).fill(0).map(item => new Array(n).fill(0).map(item => 0)) 13 | 14 | // fill predefined for single character 15 | for (let i = 0; i < n; i++) { 16 | dp[i][i] = 1 17 | } 18 | 19 | for (let i = 1; i < n; i++) { 20 | for (let j = 0; j < n - i; j++) { 21 | const col = j + i 22 | if (s[j] === s[col]) { 23 | dp[j][col] = 2 + dp[j + 1][col - 1] 24 | } else { 25 | dp[j][col] = Math.max(dp[j][col - 1], dp[j + 1][col]) 26 | } 27 | } 28 | } 29 | 30 | return dp[0][n - 1] 31 | } 32 | -------------------------------------------------------------------------------- /Dynamic-Programming/LongestValidParentheses.js: -------------------------------------------------------------------------------- 1 | /* 2 | LeetCode -> https://leetcode.com/problems/longest-valid-parentheses/ 3 | 4 | Given a string containing just the characters '(' and ')', 5 | find the length of the longest valid (well-formed) parentheses substring. 6 | */ 7 | 8 | export const longestValidParentheses = (s) => { 9 | const n = s.length 10 | const stack = [] 11 | 12 | // storing results 13 | const res = new Array(n).fill(-Infinity) 14 | 15 | for (let i = 0; i < n; i++) { 16 | const bracket = s[i] 17 | 18 | if (bracket === ')' && s[stack[stack.length - 1]] === '(') { 19 | res[i] = 1 20 | res[stack[stack.length - 1]] = 1 21 | stack.pop() 22 | } else { 23 | stack.push(i) 24 | } 25 | } 26 | 27 | // summing all adjacent valid 28 | for (let i = 1; i < n; i++) { 29 | res[i] = Math.max(res[i], res[i] + res[i - 1]) 30 | } 31 | 32 | // adding 0 if there are none so it will return 0 instead of -Infinity 33 | res.push(0) 34 | return Math.max(...res) 35 | } 36 | -------------------------------------------------------------------------------- /Dynamic-Programming/MaxNonAdjacentSum.js: -------------------------------------------------------------------------------- 1 | function maximumNonAdjacentSum (nums) { 2 | /* 3 | * Find the maximum non-adjacent sum of the integers in the nums input list 4 | * :param nums: Array of Numbers 5 | * :return: The maximum non-adjacent sum 6 | */ 7 | 8 | if (nums.length < 0) return 0 9 | 10 | let maxIncluding = nums[0] 11 | let maxExcluding = 0 12 | 13 | for (const num of nums.slice(1)) { 14 | const temp = maxIncluding 15 | maxIncluding = maxExcluding + num 16 | maxExcluding = Math.max(temp, maxExcluding) 17 | } 18 | 19 | return Math.max(maxExcluding, maxIncluding) 20 | } 21 | 22 | // Example 23 | 24 | // maximumNonAdjacentSum([1, 2, 3])) 25 | // maximumNonAdjacentSum([1, 5, 3, 7, 2, 2, 6])) 26 | // maximumNonAdjacentSum([-1, -5, -3, -7, -2, -2, -6])) 27 | // maximumNonAdjacentSum([499, 500, -3, -7, -2, -2, -6])) 28 | 29 | export { maximumNonAdjacentSum } 30 | -------------------------------------------------------------------------------- /Dynamic-Programming/NumberOfSubsetEqualToGivenSum.js: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array of non-negative integers and a value sum, 3 | determine the total number of the subset with sum 4 | equal to the given sum. 5 | */ 6 | /* 7 | Given solution is O(n*sum) Time complexity and O(sum) Space complexity 8 | */ 9 | function NumberOfSubsetSum (array, sum) { 10 | const dp = [] // create an dp array where dp[i] denote number of subset with sum equal to i 11 | for (let i = 1; i <= sum; i++) { 12 | dp[i] = 0 13 | } 14 | dp[0] = 1 // since sum equal to 0 is always possible with no element in subset 15 | 16 | for (let i = 0; i < array.length; i++) { 17 | for (let j = sum; j >= array[i]; j--) { 18 | if (j - array[i] >= 0) { 19 | dp[j] += dp[j - array[i]] 20 | } 21 | } 22 | } 23 | return dp[sum] 24 | } 25 | 26 | // example 27 | 28 | // const array = [1, 1, 2, 2, 3, 1, 1] 29 | // const sum = 4 30 | // const result = NumberOfSubsetSum(array, sum) 31 | 32 | export { NumberOfSubsetSum } 33 | -------------------------------------------------------------------------------- /Dynamic-Programming/RodCutting.js: -------------------------------------------------------------------------------- 1 | /* 2 | * You are given a rod of 'n' length and an array of prices associated with all the lengths less than 'n'. 3 | * Find the maximum profit possible by cutting the rod and selling the pieces. 4 | */ 5 | 6 | export function rodCut (prices, n) { 7 | const memo = new Array(n + 1) 8 | memo[0] = 0 9 | 10 | for (let i = 1; i <= n; i++) { 11 | let maxVal = Number.MIN_VALUE 12 | for (let j = 0; j < i; j++) { maxVal = Math.max(maxVal, prices[j] + memo[i - j - 1]) } 13 | memo[i] = maxVal 14 | } 15 | 16 | return memo[n] 17 | } 18 | -------------------------------------------------------------------------------- /Dynamic-Programming/Sliding-Window/test/LongestSubstringWithoutRepeatingCharacters.test.js: -------------------------------------------------------------------------------- 1 | import { LongestSubstringWithoutRepeatingCharacters } from '../LongestSubstringWithoutRepeatingCharacters.js' 2 | 3 | describe('LongestSubstringWithoutRepeatingCharacters', () => { 4 | it('should return longest substring without repeating characters', () => { 5 | expect(LongestSubstringWithoutRepeatingCharacters('abcabcbb')).toEqual(3) 6 | expect(LongestSubstringWithoutRepeatingCharacters('bbbbb')).toEqual(1) 7 | expect(LongestSubstringWithoutRepeatingCharacters('pwwkew')).toEqual(3) 8 | expect(LongestSubstringWithoutRepeatingCharacters('a')).toEqual(1) 9 | expect(LongestSubstringWithoutRepeatingCharacters('')).toEqual(0) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Dynamic-Programming/Sliding-Window/test/PermutationinString.test.js: -------------------------------------------------------------------------------- 1 | import { PermutationinString } from '../PermutationinString.js' 2 | 3 | describe('PermutationinString', () => { 4 | it("should return true if one of s1's permutations is the substring of s2", () => { 5 | expect(PermutationinString('ab', 'eidbaooo')).toEqual(true) 6 | expect(PermutationinString('abc', 'bcab')).toEqual(true) 7 | expect(PermutationinString('ab', 'eidboaoo')).toEqual(false) 8 | expect(PermutationinString('abc', '')).toEqual(false) 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /Dynamic-Programming/TribonacciNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function Tribonacci 3 | * @description Tribonacci is the sum of previous three tribonacci numbers. 4 | * @param {Integer} n - The input integer 5 | * @return {Integer} tribonacci of n. 6 | * @see [Tribonacci_Numbers](https://www.geeksforgeeks.org/tribonacci-numbers/) 7 | */ 8 | const tribonacci = (n) => { 9 | // creating array to store previous tribonacci numbers 10 | const dp = new Array(n + 1) 11 | dp[0] = 0 12 | dp[1] = 1 13 | dp[2] = 1 14 | for (let i = 3; i <= n; i++) { 15 | dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3] 16 | } 17 | return dp[n] 18 | } 19 | 20 | export { tribonacci } 21 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/ClimbingStairs.test.js: -------------------------------------------------------------------------------- 1 | import { climbStairs } from '../ClimbingStairs' 2 | 3 | describe('ClimbingStairs', () => { 4 | it('climbStairs of 0', () => { 5 | expect(climbStairs(0)).toBe(1) 6 | }) 7 | 8 | it('climbStairs of 1', () => { 9 | expect(climbStairs(1)).toBe(1) 10 | }) 11 | 12 | it('climbStairs of 10', () => { 13 | expect(climbStairs(10)).toBe(89) 14 | }) 15 | 16 | it('climbStairs of 15', () => { 17 | expect(climbStairs(15)).toBe(987) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/FibonacciNumber.test.js: -------------------------------------------------------------------------------- 1 | import { fibonacci } from '../FibonacciNumber' 2 | 3 | describe('Testing FibonacciNumber', () => { 4 | it('Testing for invalid type', () => { 5 | expect(() => fibonacci('0')).toThrowError() 6 | expect(() => fibonacci('12')).toThrowError() 7 | expect(() => fibonacci(true)).toThrowError() 8 | }) 9 | 10 | it('fibonacci of 0', () => { 11 | expect(fibonacci(0)).toBe(0) 12 | }) 13 | 14 | it('fibonacci of 1', () => { 15 | expect(fibonacci(1)).toBe(1) 16 | }) 17 | 18 | it('fibonacci of 10', () => { 19 | expect(fibonacci(10)).toBe(55) 20 | }) 21 | 22 | it('fibonacci of 25', () => { 23 | expect(fibonacci(25)).toBe(75025) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/KadaneAlgo.test.js: -------------------------------------------------------------------------------- 1 | import { kadaneAlgo } from '../KadaneAlgo' 2 | test('it is being checked that 15 is the answer to the corresponding array input', () => { 3 | expect(kadaneAlgo([1, 2, 3, 4, 5])).toBe(15) 4 | }) 5 | 6 | test('it is being checked that 5 is the answer to the corresponding array input', () => { 7 | expect(kadaneAlgo([-1, -2, -3, -4, 5])).toBe(5) 8 | }) 9 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/LongestPalindromicSubsequence.test.js: -------------------------------------------------------------------------------- 1 | import { longestPalindromeSubsequence } from '../LongestPalindromicSubsequence' 2 | 3 | describe('LongestPalindromicSubsequence', () => { 4 | it('expects to return 1 as longest palindromic subsequence', () => { 5 | expect(longestPalindromeSubsequence('abcdefgh')).toBe(1) 6 | }) 7 | 8 | it('expects to return 4 as longest palindromic subsequence', () => { 9 | expect(longestPalindromeSubsequence('bbbab')).toBe(4) 10 | }) 11 | 12 | it('expects to return 2 as longest palindromic subsequence', () => { 13 | expect(longestPalindromeSubsequence('cbbd')).toBe(2) 14 | }) 15 | 16 | it('expects to return 7 as longest palindromic subsequence', () => { 17 | expect(longestPalindromeSubsequence('racexyzcxar')).toBe(7) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/LongestValidParentheses.test.js: -------------------------------------------------------------------------------- 1 | import { longestValidParentheses } from '../LongestValidParentheses' 2 | 3 | describe('longestValidParentheses', () => { 4 | it('expects to return 0 as longest valid parentheses substring', () => { 5 | expect(longestValidParentheses('')).toBe(0) 6 | }) 7 | 8 | it('expects to return 2 as longest valid parentheses substring', () => { 9 | expect(longestValidParentheses('(()')).toBe(2) 10 | }) 11 | 12 | it('expects to return 2 as longest valid parentheses substring', () => { 13 | expect(longestValidParentheses(')()())')).toBe(4) 14 | }) 15 | 16 | it('expects to return 2 as longest valid parentheses substring', () => { 17 | expect(longestValidParentheses('(((')).toBe(0) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/MaxProductOfThree.test.js: -------------------------------------------------------------------------------- 1 | import { maxProductOfThree } from '../MaxProductOfThree' 2 | 3 | describe('MaxProductOfThree', () => { 4 | it('expects to throw error for array with only 2 numbers', () => { 5 | expect(() => { 6 | maxProductOfThree([1, 3]) 7 | }).toThrow('Triplet cannot exist with the given array') 8 | }) 9 | 10 | it('expects to return 300 as the maximum product', () => { 11 | expect(maxProductOfThree([10, 6, 5, 3, 1, -10])).toBe(300) 12 | }) 13 | 14 | it('expects to return 300 as the maximum product', () => { 15 | expect(maxProductOfThree([10, -6, 5, 3, 1, -10])).toBe(600) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/RodCutting.test.js: -------------------------------------------------------------------------------- 1 | import { rodCut } from '../RodCutting' 2 | 3 | test('Test Case 1', () => { 4 | expect(rodCut([1, 5, 8, 9, 10, 17, 17, 20], 8)).toBe(22) 5 | }) 6 | 7 | test('Test Case 2', () => { 8 | expect(rodCut([1, 5, 4, 2, 1, 11, 19, 12], 8)).toBe(20) 9 | }) 10 | 11 | test('Test Case 3', () => { 12 | expect(rodCut([1, 2, 1], 3)).toBe(3) 13 | }) 14 | 15 | test('Test Case 4', () => { 16 | expect(rodCut([5, 4, 3, 2, 1], 5)).toBe(25) 17 | }) 18 | 19 | test('Test Case 5', () => { 20 | expect(rodCut([3, 5, 8, 8, 10, 16, 14, 19], 8)).toBe(24) 21 | }) 22 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/SieveOfEratosthenes.test.js: -------------------------------------------------------------------------------- 1 | import { sieveOfEratosthenes } from '../SieveOfEratosthenes' 2 | 3 | describe('SieveOfEratosthenes', () => { 4 | it('Primes till 0', () => { 5 | expect(sieveOfEratosthenes(0)).toEqual([]) 6 | }) 7 | 8 | it('Primes till 1', () => { 9 | expect(sieveOfEratosthenes(1)).toEqual([]) 10 | }) 11 | 12 | it('Primes till 10', () => { 13 | expect(sieveOfEratosthenes(10)).toEqual([2, 3, 5, 7]) 14 | }) 15 | 16 | it('Primes till 23', () => { 17 | expect(sieveOfEratosthenes(23)).toEqual([2, 3, 5, 7, 11, 13, 17, 19, 23]) 18 | }) 19 | 20 | it('Primes till 70', () => { 21 | expect(sieveOfEratosthenes(70)).toEqual([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67]) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/TrappingRainWater.test.js: -------------------------------------------------------------------------------- 1 | import { trap } from '../TrappingRainWater' 2 | 3 | describe('TrappingRainWater', () => { 4 | it('expects 6 units of rain water are being trapped', () => { 5 | expect(trap([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1])).toBe(6) 6 | }) 7 | 8 | it('expects 9 units of rain water are being trapped', () => { 9 | expect(trap([4, 2, 0, 3, 2, 5])).toBe(9) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Dynamic-Programming/tests/TribonacciNumber.test.js: -------------------------------------------------------------------------------- 1 | import { tribonacci } from '../TribonacciNumber' 2 | 3 | describe('TribonacciNumber', () => { 4 | it('tribonacci of 0', () => { 5 | expect(tribonacci(0)).toBe(0) 6 | }) 7 | 8 | it('tribonacci of 1', () => { 9 | expect(tribonacci(1)).toBe(1) 10 | }) 11 | 12 | it('tribonacci of 2', () => { 13 | expect(tribonacci(2)).toBe(1) 14 | }) 15 | 16 | it('tribonacci of 10', () => { 17 | expect(tribonacci(10)).toBe(149) 18 | }) 19 | 20 | it('tribonacci of 25', () => { 21 | expect(tribonacci(25)).toBe(1389537) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /Graphs/Density.js: -------------------------------------------------------------------------------- 1 | /* 2 | The density of a network is a measure of how many edges exist proportional to 3 | how many edges would exist in a complete network (where all possible edges). 4 | https://networkx.org/documentation/networkx-1.9/reference/generated/networkx.classes.function.density.html 5 | */ 6 | function density (numberOfNodes, numberOfEdges, isDirected = false) { 7 | const multi = isDirected ? 1 : 2 8 | return (multi * numberOfEdges) / (numberOfNodes * (numberOfNodes - 1)) 9 | } 10 | 11 | export { density } 12 | -------------------------------------------------------------------------------- /Graphs/test/BellmanFord.test.js: -------------------------------------------------------------------------------- 1 | import { BellmanFord } from '../BellmanFord.js' 2 | 3 | test('Test Case 1', () => { 4 | const V = 5 5 | const E = 8 6 | const destination = 3 7 | const graph = [[0, 1, -1], [0, 2, 4], 8 | [1, 2, 3], [1, 3, 2], 9 | [1, 4, 2], [3, 2, 5], 10 | [3, 1, 1], [4, 3, -3]] 11 | const dist = BellmanFord(graph, V, E, 0, destination) 12 | expect(dist).toBe(-2) 13 | }) 14 | test('Test Case 2', () => { 15 | const V = 6 16 | const E = 9 17 | const destination = 4 18 | const graph = [[0, 1, 3], [0, 3, 6], 19 | [0, 5, -1], [1, 2, -3], 20 | [1, 4, -2], [5, 2, 5], 21 | [2, 3, 1], [4, 3, 5], [5, 4, 2]] 22 | const dist = BellmanFord(graph, V, E, 0, destination) 23 | expect(dist).toBe(1) 24 | }) 25 | test('Test Case 3', () => { 26 | const V = 4 27 | const E = 5 28 | const destination = 1 29 | const graph = [[0, 3, -1], [0, 2, 4], 30 | [3, 2, 2], [3, 1, 5], 31 | [2, 1, -1]] 32 | const dist = BellmanFord(graph, V, E, 0, destination) 33 | expect(dist).toBe(0) 34 | }) 35 | -------------------------------------------------------------------------------- /Graphs/test/BreadthFirstSearch.test.js: -------------------------------------------------------------------------------- 1 | import { breadthFirstSearch } from '../BreadthFirstSearch' 2 | 3 | describe('BreadthFirstSearch', () => { 4 | const graph = { 5 | A: ['B', 'D'], 6 | B: ['E'], 7 | C: ['D'], 8 | D: ['A'], 9 | E: ['D'], 10 | F: ['G'], 11 | G: [] 12 | } 13 | /* 14 | A <-> B 15 | ʌ | 16 | | | 17 | v v 18 | C --> D <-- E 19 | 20 | F --> G 21 | */ 22 | 23 | it('should return the visited nodes', () => { 24 | expect(Array.from(breadthFirstSearch(graph, 'C'))).toEqual(['C', 'D', 'A', 'B', 'E']) 25 | expect(Array.from(breadthFirstSearch(graph, 'A'))).toEqual(['A', 'B', 'D', 'E']) 26 | expect(Array.from(breadthFirstSearch(graph, 'F'))).toEqual(['F', 'G']) 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /Graphs/test/BreadthFirstShortestPath.test.js: -------------------------------------------------------------------------------- 1 | import { breadthFirstShortestPath } from '../BreadthFirstShortestPath' 2 | 3 | describe('BreadthFirstShortestPath', () => { 4 | const graph = { 5 | A: ['B', 'D'], 6 | B: ['E'], 7 | C: ['D'], 8 | D: ['A'], 9 | E: ['D'], 10 | F: ['G'], 11 | G: [] 12 | } 13 | /* 14 | A <-> B 15 | ʌ | 16 | | | 17 | v v 18 | C --> D <-- E 19 | 20 | F --> G 21 | */ 22 | 23 | it('should return the visited nodes', () => { 24 | expect(breadthFirstShortestPath(graph, 'C', 'E')).toEqual(['C', 'D', 'A', 'B', 'E']) 25 | expect(breadthFirstShortestPath(graph, 'E', 'B')).toEqual(['E', 'D', 'A', 'B']) 26 | expect(breadthFirstShortestPath(graph, 'F', 'G')).toEqual(['F', 'G']) 27 | expect(breadthFirstShortestPath(graph, 'A', 'G')).toEqual([]) 28 | }) 29 | }) 30 | -------------------------------------------------------------------------------- /Maths/Abs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function abs 3 | * @description This script will find the absolute value of a number. 4 | * @param {number} num - The input integer 5 | * @return {number} - Absolute number of num. 6 | * @see https://en.wikipedia.org/wiki/Absolute_value 7 | * @example abs(-10) = 10 8 | * @example abs(50) = 50 9 | * @example abs(0) = 0 10 | */ 11 | 12 | const abs = (num) => { 13 | const validNumber = +num // converted to number, also can use - Number(num) 14 | 15 | if (Number.isNaN(validNumber)) { 16 | throw new TypeError('Argument is NaN - Not a Number') 17 | } 18 | 19 | return validNumber < 0 ? -validNumber : validNumber // if number is less then zero mean negative then it converted to positive. i.e -> n = -2 = -(-2) = 2 20 | } 21 | 22 | export { abs } 23 | -------------------------------------------------------------------------------- /Maths/ArmstrongNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: dephraiim 3 | * License: GPL-3.0 or later 4 | * 5 | * An Armstrong number is equal to the sum of its own digits each raised to the power of the number of digits. 6 | * For example, 370 is an Armstrong number because 3*3*3 + 7*7*7 + 0*0*0 = 370. 7 | * An Armstrong number is often called Narcissistic number. 8 | * 9 | */ 10 | 11 | const armstrongNumber = (num) => { 12 | if (num < 0 || typeof num !== 'number') return false 13 | 14 | let newSum = 0 15 | 16 | const numArr = num.toString().split('') 17 | numArr.forEach((num) => { 18 | newSum += parseInt(num) ** numArr.length 19 | }) 20 | 21 | return newSum === num 22 | } 23 | 24 | export { armstrongNumber } 25 | -------------------------------------------------------------------------------- /Maths/AverageMean.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function mean 3 | * @description This script will find the mean value of a array of numbers. 4 | * @param {Integer[]} nums - Array of integer 5 | * @return {Integer} - mean of nums. 6 | * @see [Mean](https://en.wikipedia.org/wiki/Mean) 7 | * @example mean([1, 2, 4, 5]) = 3 8 | * @example mean([10, 40, 100, 20]) = 42.5 9 | */ 10 | 11 | const mean = (nums) => { 12 | if (!Array.isArray(nums)) { 13 | throw new TypeError('Invalid Input') 14 | } 15 | 16 | // This loop sums all values in the 'nums' array using forEach loop 17 | const sum = nums.reduce((sum, cur) => sum + cur, 0) 18 | 19 | // Divide sum by the length of the 'nums' array. 20 | return sum / nums.length 21 | } 22 | 23 | export { mean } 24 | -------------------------------------------------------------------------------- /Maths/AverageMedian.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Median: https://en.wikipedia.org/wiki/Median 3 | * 4 | * function averageMedian 5 | * to find the median value of an array of numbers 6 | * the numbers in an array will be sorted in ascending order by the function sortNumbers 7 | * if the length of the array is even number, the median value will be the average of the two middle numbers 8 | * else if the length of the array is odd number, the median value will be the middle number in the array 9 | */ 10 | 11 | const averageMedian = (sourceArrayOfNumbers) => { 12 | let numbers = [...sourceArrayOfNumbers] 13 | let median = 0 14 | const numLength = numbers.length 15 | numbers = numbers.sort(sortNumbers) 16 | 17 | if (numLength % 2 === 0) { 18 | median = (numbers[numLength / 2 - 1] + numbers[numLength / 2]) / 2 19 | } else { 20 | median = numbers[(numLength - 1) / 2] 21 | } 22 | 23 | return median 24 | } 25 | 26 | const sortNumbers = (num1, num2) => { 27 | return num1 - num2 28 | } 29 | 30 | export { averageMedian } 31 | -------------------------------------------------------------------------------- /Maths/BinaryConvert.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function BinaryConvert 3 | * @description Convert the decimal to binary. 4 | * @param {Integer} num - The input integer 5 | * @return {Integer} - Binary of num. 6 | * @see [BinaryConvert](https://www.programiz.com/javascript/examples/decimal-binary) 7 | * @example BinaryConvert(12) = 1100 8 | * @example BinaryConvert(12 + 2) = 1110 9 | */ 10 | 11 | const BinaryConvert = (num) => { 12 | let power = 1 13 | let binary = 0 14 | 15 | while (num) { 16 | const rem = num % 2 17 | num = Math.floor(num / 2) 18 | binary = rem * power + binary 19 | power *= 10 20 | } 21 | 22 | return binary 23 | } 24 | 25 | export { BinaryConvert } 26 | -------------------------------------------------------------------------------- /Maths/BinaryExponentiationIterative.js: -------------------------------------------------------------------------------- 1 | // To calculate x^n i.e. exponent(x, n) in O(log n) time in iterative way 2 | // n is an integer and n >= 0 3 | 4 | // Explanation: https://en.wikipedia.org/wiki/Exponentiation_by_squaring 5 | 6 | // Examples: 7 | // 2^3 = 8 8 | // 5^0 = 1 9 | 10 | // Uses the fact that 11 | // exponent(x, n) 12 | // = exponent(x*x, floor(n/2)) ; if n is odd 13 | // = x*exponent(x*x, floor(n/2)) ; if n is even 14 | const exponent = (x, n) => { 15 | let answer = 1 16 | while (n > 0) { 17 | if (n % 2 !== 0) answer *= x 18 | n = Math.floor(n / 2) 19 | if (n > 0) x *= x 20 | } 21 | return answer 22 | } 23 | 24 | export { exponent } 25 | -------------------------------------------------------------------------------- /Maths/BinaryExponentiationRecursive.js: -------------------------------------------------------------------------------- 1 | /* 2 | Modified from: 3 | https://github.com/TheAlgorithms/Python/blob/master/maths/binary_exponentiation.py 4 | 5 | Explanation: 6 | https://en.wikipedia.org/wiki/Exponentiation_by_squaring 7 | */ 8 | 9 | export const binaryExponentiation = (a, n) => { 10 | // input: a: int, n: int 11 | // returns: a^n: int 12 | if (n === 0) { 13 | return 1 14 | } else if (n % 2 === 1) { 15 | return binaryExponentiation(a, n - 1) * a 16 | } else { 17 | const b = binaryExponentiation(a, n / 2) 18 | return b * b 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Maths/CollatzSequence.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function collatz 3 | * @description Applies the Collatz Sequence on a specified number. 4 | * The Collatz Sequence states that every natural number will always fall in a 1, 2, 4 loop when iterated under the following function: 5 | * If the number is even, divide by 2, and if its odd, multiply it by 3 and add 1. 6 | * 7 | * @parama {Integer} n The number to apply the Collatz Sequence to. 8 | * 9 | * @return An array of steps and the final result.. 10 | * 11 | * @see [Collatz Conjecture](https://en.wikipedia.org/wiki/Collatz_conjecture) 12 | * 13 | * @example collatz(1) = { result: 1, steps: [] } 14 | * @example collatz(5) = { result: 1, steps: [16, 8, 4, 2, 1] } 15 | */ 16 | export function collatz (n) { 17 | const steps = [] 18 | 19 | while (n !== 1) { 20 | if (n % 2 === 0) { 21 | n = n / 2 22 | } else { 23 | n = 3 * n + 1 24 | } 25 | 26 | steps.push(n) 27 | } 28 | 29 | return { result: n, steps: steps } 30 | } 31 | -------------------------------------------------------------------------------- /Maths/Coordinate.js: -------------------------------------------------------------------------------- 1 | /* 2 | Calculate the mathematical properties involving coordinates 3 | Calculate the Distance Between 2 Points on a 2 Dimensional Plane 4 | Example: coorDistance(2,2,14,11) will return 15 5 | Wikipedia reference: https://en.wikipedia.org/wiki/Geographical_distance#Flat-surface_formulae 6 | */ 7 | const euclideanDistance = (longitude1, latitude1, longitude2, latitude2) => { 8 | const width = longitude2 - longitude1 9 | const height = latitude2 - latitude1 10 | return (Math.sqrt(width * width + height * height)) 11 | } 12 | 13 | const manhattanDistance = (longitude1, latitude1, longitude2, latitude2) => { 14 | const width = Math.abs(longitude2 - longitude1) 15 | const height = Math.abs(latitude2 - latitude1) 16 | return width + height 17 | } 18 | 19 | export { euclideanDistance, manhattanDistance } 20 | -------------------------------------------------------------------------------- /Maths/DecimalIsolate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * function isolates the decimal part of a number. 3 | * Take the number and subtract it from the floored number. 4 | * Return the result. 5 | */ 6 | 7 | export const decimalIsolate = (number) => { 8 | const answer = parseFloat((number + '').replace(/^[-\d]+./, '.')) 9 | return isNaN(answer) === true ? 0 : answer 10 | } 11 | -------------------------------------------------------------------------------- /Maths/DegreeToRadian.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Radian : https://en.wikipedia.org/wiki/Radian 3 | * Degree : https://en.wikipedia.org/wiki/Degree_(angle) 4 | * 5 | * Angle in Radian = ( Angle in Degree ) x ( pi / 180 ) 6 | * 7 | * Example : 8 | * Question : Convert 90 degree to radian 9 | * So, Angle in Degree = 90 10 | * 11 | * Solution : 12 | * Angle in Radian = ( 90 ) x ( pi / 180 ) = pi / 2 13 | * 14 | * So, 90 degree is equal to pi / 2 radian 15 | */ 16 | 17 | /** 18 | * @param {number} degree 19 | * @return {number} 20 | */ 21 | export const degreeToRadian = (degree) => { 22 | return degree * (Math.PI / 180) 23 | } 24 | -------------------------------------------------------------------------------- /Maths/EulersTotient.js: -------------------------------------------------------------------------------- 1 | /* 2 | Source: 3 | https://en.wikipedia.org/wiki/Euler%27s_totient_function 4 | 5 | EulersTotient(n) = n * product(1 - 1/p for all prime p dividing n) 6 | 7 | Complexity: 8 | O(sqrt(n)) 9 | */ 10 | 11 | export const EulersTotient = (n) => { 12 | // input: n: int 13 | // output: phi(n): count of numbers b/w 1 and n that are coprime to n 14 | let res = n 15 | for (let i = 2; i * i <= n; i++) { 16 | if (n % i === 0) { 17 | while (n % i === 0) { 18 | n = Math.floor(n / i) 19 | } 20 | // i is a prime diving n, multiply res by 1 - 1/i 21 | // res = res * (1 - 1/i) = res - (res / i) 22 | res = res - Math.floor(res / i) 23 | } 24 | } 25 | if (n > 1) { 26 | res = res - Math.floor(res / n) 27 | } 28 | return res 29 | } 30 | -------------------------------------------------------------------------------- /Maths/Factors.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: dephraiim 3 | * License: GPL-3.0 or later 4 | * 5 | * More on Factors: 6 | * https://www.mathsisfun.com/definitions/factor.html 7 | * 8 | */ 9 | 10 | const factorsOfANumber = (number = 0) => { 11 | return Array.from(Array(number + 1).keys()).filter( 12 | (num) => number % num === 0 13 | ) 14 | } 15 | 16 | export { factorsOfANumber } 17 | -------------------------------------------------------------------------------- /Maths/FindHcf.js: -------------------------------------------------------------------------------- 1 | /* 2 | author: redfly1 3 | More about HCF: 4 | https://en.wikipedia.org/wiki/Greatest_common_divisor 5 | */ 6 | 7 | const findHCF = (x, y) => { 8 | // If the input numbers are less than 1 return an error message. 9 | if (x < 1 || y < 1) { 10 | return 'Please enter values greater than zero.' 11 | } 12 | 13 | // If the input numbers are not integers return an error message. 14 | if (x !== Math.round(x) || y !== Math.round(y)) { 15 | return 'Please enter whole numbers.' 16 | } 17 | 18 | // Now apply Euclid's algorithm to the two numbers. 19 | while (Math.max(x, y) % Math.min(x, y) !== 0) { 20 | if (x > y) { 21 | x %= y 22 | } else { 23 | y %= x 24 | } 25 | } 26 | 27 | // When the while loop finishes the minimum of x and y is the HCF. 28 | return Math.min(x, y) 29 | } 30 | 31 | export { findHCF } 32 | -------------------------------------------------------------------------------- /Maths/FindLcm.js: -------------------------------------------------------------------------------- 1 | /* 2 | author: PatOnTheBack 3 | license: GPL-3.0 or later 4 | 5 | Modified from: 6 | https://github.com/TheAlgorithms/Python/blob/master/maths/findLcm.py 7 | 8 | More about LCM: 9 | https://en.wikipedia.org/wiki/Least_common_multiple 10 | */ 11 | 12 | 'use strict' 13 | 14 | // Find the LCM of two numbers. 15 | const findLcm = (num1, num2) => { 16 | // If the input numbers are less than 1 return an error message. 17 | if (num1 < 1 || num2 < 1) { 18 | return 'Please enter values greater than zero.' 19 | } 20 | 21 | // If the input numbers are not integers return an error message. 22 | if (num1 !== Math.round(num1) || num2 !== Math.round(num2)) { 23 | return 'Please enter whole numbers.' 24 | } 25 | 26 | // Get the larger number between the two 27 | const maxNum = Math.max(num1, num2) 28 | let lcm = maxNum 29 | 30 | while (true) { 31 | if (lcm % num1 === 0 && lcm % num2 === 0) return lcm 32 | lcm += maxNum 33 | } 34 | } 35 | 36 | export { findLcm } 37 | -------------------------------------------------------------------------------- /Maths/FindMin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function FindMin 3 | * @description Function to find the minimum number given in an array of integers. 4 | * @param {Integer[]} nums - Array of Integers 5 | * @return {Integer} - The minimum number of the array. 6 | */ 7 | 8 | const findMin = (...nums) => { 9 | if (nums.length === 0) { 10 | throw new TypeError('Array is empty') 11 | } 12 | 13 | let min = nums[0] 14 | for (let i = 1; i < nums.length; i++) { 15 | if (nums[i] < min) { 16 | min = nums[i] 17 | } 18 | } 19 | 20 | return min 21 | } 22 | 23 | export { findMin } 24 | -------------------------------------------------------------------------------- /Maths/FindMinIterator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function FindMinIterator 3 | * @description Function to find the minimum number given in an array. 4 | */ 5 | 6 | const FindMinIterator = (_iterable, _selector = undefined) => { 7 | let min 8 | 9 | const iterator = _iterable[Symbol.iterator]() 10 | if (!_selector) { 11 | let current = iterator.next() 12 | if (current.done) { return undefined } 13 | min = current.value 14 | 15 | current = iterator.next() 16 | while (!current.done) { 17 | const x = current.value 18 | if (x < min) { min = x } 19 | current = iterator.next() 20 | } 21 | } else { 22 | let current = iterator.next() 23 | if (current.done) { return undefined } 24 | min = _selector(current.value) 25 | 26 | current = iterator.next() 27 | while (!current.done) { 28 | const x = _selector(current.value) 29 | if (x < min) { min = x } 30 | current = iterator.next() 31 | } 32 | } 33 | return min 34 | } 35 | 36 | export { FindMinIterator } 37 | -------------------------------------------------------------------------------- /Maths/IsDivisible.js: -------------------------------------------------------------------------------- 1 | // Checks if a number is divisible by another number. 2 | 3 | export const isDivisible = (num1, num2) => { 4 | if (!Number.isFinite(num1) || !Number.isFinite(num2)) { 5 | throw new TypeError('Expected a number') 6 | } 7 | if (num2 === 0) { 8 | return false 9 | } 10 | return num1 % num2 === 0 11 | } 12 | 13 | // isDivisible(10, 5) // returns true 14 | // isDivisible(123498175, 5) // returns true 15 | // isDivisible(99, 5) // returns false 16 | -------------------------------------------------------------------------------- /Maths/IsPronic.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Akshay Dubey (https://github.com/itsAkshayDubey) 3 | * Pronic Number: https://en.wikipedia.org/wiki/Pronic_number 4 | * function to check if number is pronic. 5 | * return true if number is pronic. 6 | * else false 7 | */ 8 | 9 | /** 10 | * @function isPronic 11 | * @description -> Checking if number is pronic using product of two consecutive numbers 12 | * If number is a product of two consecutive numbers, then it is pronic 13 | * therefore, the function will return true 14 | * 15 | * If number is not a product of two consecutive numbers, then it is not pronic 16 | * therefore, the function will return false 17 | * @param {number} number 18 | * @returns {boolean} 19 | */ 20 | 21 | export const isPronic = (number) => { 22 | if (number === 0) { 23 | return true 24 | } 25 | const sqrt = Math.sqrt(number) 26 | return sqrt % 1 !== 0 && Math.ceil(sqrt) * Math.floor(sqrt) === number 27 | } 28 | -------------------------------------------------------------------------------- /Maths/LeapYear.js: -------------------------------------------------------------------------------- 1 | /** 2 | * isLeapYear :: Number -> Boolean 3 | * 4 | * Check if a year is a leap year or not. A leap year is a year which has 366 days. 5 | * For the extra +1 day the February month contains 29 days instead of 28 days. 6 | * 7 | * The logic behind the leap year is- 8 | * 1. If the year is divisible by 400 then it is a leap year. 9 | * 2. If it is not divisible by 400 but divisible by 100 then it is not a leap year. 10 | * 3. If the year is not divisible by both 400 and 100 but divisible by 4 then a leap year. 11 | * 4. Other cases except the describing ones are not a leap year. 12 | * 13 | * @param {number} year 14 | * @returns {boolean} true if this is a leap year, false otherwise. 15 | */ 16 | export const isLeapYear = (year) => { 17 | if (year % 400 === 0) return true 18 | if (year % 100 === 0) return false 19 | if (year % 4 === 0) return true 20 | 21 | return false 22 | } 23 | -------------------------------------------------------------------------------- /Maths/LinearSieve.js: -------------------------------------------------------------------------------- 1 | const LinearSieve = (n) => { 2 | /* 3 | * Calculates prime numbers till a number n 4 | * Time Complexity: O(n) 5 | * Explanation: https://cp-algorithms.com/algebra/prime-sieve-linear.html 6 | * :param n: Number up to which to calculate primes 7 | * :return: A list containing only primes 8 | */ 9 | const isnPrime = new Array(n + 1) 10 | isnPrime[0] = isnPrime[1] = true 11 | const primes = [] 12 | for (let i = 2; i <= n; i++) { 13 | if (!isnPrime[i]) primes.push(i) 14 | for (const p of primes) { 15 | const k = i * p 16 | if (k > n) break 17 | isnPrime[k] = true 18 | if (i % p === 0) break 19 | } 20 | } 21 | return primes 22 | } 23 | 24 | export { LinearSieve } 25 | -------------------------------------------------------------------------------- /Maths/LucasSeries.js: -------------------------------------------------------------------------------- 1 | /* 2 | Program to get the Nth Lucas Number 3 | Article on Lucas Number: https://en.wikipedia.org/wiki/Lucas_number 4 | Examples: 5 | > loopLucas(1) 6 | 1 7 | > loopLucas(20) 8 | 15127 9 | > loopLucas(100) 10 | 792070839848372100000 11 | */ 12 | 13 | /** 14 | * @param {Number} index The position of the number you want to get from the Lucas Series 15 | */ 16 | function lucas (index) { 17 | // index can't be negative 18 | if (index < 0) throw new TypeError('Index cannot be Negative') 19 | 20 | // index can't be a decimal 21 | if (Math.floor(index) !== index) throw new TypeError('Index cannot be a Decimal') 22 | 23 | let a = 2 24 | let b = 1 25 | for (let i = 0; i < index; i++) { 26 | const temp = a + b 27 | a = b 28 | b = temp 29 | } 30 | return a 31 | } 32 | 33 | export { lucas } 34 | -------------------------------------------------------------------------------- /Maths/MeanSquareError.js: -------------------------------------------------------------------------------- 1 | // Wikipedia: https://en.wikipedia.org/wiki/Mean_squared_error 2 | 3 | const meanSquaredError = (predicted, expected) => { 4 | if (!Array.isArray(predicted) || !Array.isArray(expected)) { 5 | throw new TypeError('Argument must be an Array') 6 | } 7 | 8 | if (predicted.length !== expected.length) { 9 | throw new TypeError('The two lists must be of equal length') 10 | } 11 | 12 | let err = 0 13 | 14 | for (let i = 0; i < expected.length; i++) { 15 | err += (expected[i] - predicted[i]) ** 2 16 | } 17 | 18 | return err / expected.length 19 | } 20 | 21 | export { meanSquaredError } 22 | -------------------------------------------------------------------------------- /Maths/ModularBinaryExponentiationRecursive.js: -------------------------------------------------------------------------------- 1 | /* 2 | Modified from: 3 | https://github.com/TheAlgorithms/Python/blob/master/maths/binary_exp_mod.py 4 | 5 | Explanation: 6 | https://en.wikipedia.org/wiki/Exponentiation_by_squaring 7 | */ 8 | 9 | const modularBinaryExponentiation = (a, n, m) => { 10 | // input: a: int, n: int, m: int 11 | // returns: (a^n) % m: int 12 | if (n === 0) { 13 | return 1 14 | } else if (n % 2 === 1) { 15 | return (modularBinaryExponentiation(a, n - 1, m) * a) % m 16 | } else { 17 | const b = modularBinaryExponentiation(a, n / 2, m) 18 | return (b * b) % m 19 | } 20 | } 21 | 22 | export { modularBinaryExponentiation } 23 | -------------------------------------------------------------------------------- /Maths/NumberOfDigits.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: dephraiim 4 | * License: GPL-3.0 or later 5 | * 6 | * Returns the number of digits of a given integer 7 | * 8 | */ 9 | 10 | const numberOfDigit = (n) => Math.abs(n).toString().length 11 | 12 | export { numberOfDigit } 13 | -------------------------------------------------------------------------------- /Maths/PascalTriangle.js: -------------------------------------------------------------------------------- 1 | const addRow = (triangle) => { 2 | const previous = triangle[triangle.length - 1] 3 | const newRow = [1] 4 | for (let i = 0; i < previous.length - 1; i++) { 5 | const current = previous[i] 6 | const next = previous[i + 1] 7 | newRow.push(current + next) 8 | } 9 | newRow.push(1) 10 | return triangle.push(newRow) 11 | } 12 | 13 | const generate = (numRows) => { 14 | const triangle = [[1], [1, 1]] 15 | 16 | if (numRows === 0) { 17 | return [] 18 | } else if (numRows === 1) { 19 | return [[1]] 20 | } else if (numRows === 2) { 21 | return [[1], [1, 1]] 22 | } else { 23 | for (let i = 2; i < numRows; i++) { 24 | addRow(triangle) 25 | } 26 | } 27 | return triangle 28 | } 29 | 30 | export { generate } 31 | -------------------------------------------------------------------------------- /Maths/PerfectCube.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: dephraiim 3 | * License: GPL-3.0 or later 4 | * 5 | */ 6 | 7 | const perfectCube = (num) => Math.round(num ** (1 / 3)) ** 3 === num 8 | 9 | export { perfectCube } 10 | -------------------------------------------------------------------------------- /Maths/PerfectNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: dephraiim 3 | * License: GPL-3.0 or later 4 | * 5 | * == Perfect Number == 6 | * In number theory, a perfect number is a positive integer that is equal to the sum of 7 | * its positive divisors(factors), excluding the number itself. 8 | * For example: 6 ==> divisors[1, 2, 3, 6] 9 | * Excluding 6, the sum(divisors) is 1 + 2 + 3 = 6 10 | * So, 6 is a Perfect Number 11 | * Other examples of Perfect Numbers: 28, 486, ... 12 | * 13 | * More on Perfect Number: 14 | * https://en.wikipedia.org/wiki/Perfect_number 15 | * 16 | */ 17 | 18 | const factorsExcludingNumber = (n) => { 19 | return [...Array(n).keys()].filter((num) => n % num === 0) 20 | } 21 | 22 | const perfectNumber = (n) => { 23 | const factorSum = factorsExcludingNumber(n).reduce((num, initialValue) => { 24 | return num + initialValue 25 | }, 0) 26 | 27 | return factorSum === n 28 | } 29 | 30 | export { perfectNumber } 31 | -------------------------------------------------------------------------------- /Maths/PerfectSquare.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: dephraiim 3 | * License: GPL-3.0 or later 4 | * 5 | */ 6 | 7 | const perfectSquare = (num) => Math.sqrt(num) ** 2 === num 8 | 9 | export { perfectSquare } 10 | -------------------------------------------------------------------------------- /Maths/PiApproximationMonteCarlo.js: -------------------------------------------------------------------------------- 1 | // Wikipedia: https://en.wikipedia.org/wiki/Monte_Carlo_method 2 | // Video Explanation: https://www.youtube.com/watch?v=ELetCV_wX_c 3 | 4 | const piEstimation = (iterations = 100000) => { 5 | let circleCounter = 0 6 | 7 | for (let i = 0; i < iterations; i++) { 8 | // generating random points and checking if it lies within a circle of radius 1 9 | const x = Math.random() 10 | const y = Math.random() 11 | const radius = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) 12 | 13 | if (radius < 1) circleCounter += 1 14 | } 15 | 16 | // fomula for pi = (ratio of number inside circle and total iteration) x 4 17 | const pi = (circleCounter / iterations) * 4 18 | return pi 19 | } 20 | 21 | export { piEstimation } 22 | -------------------------------------------------------------------------------- /Maths/PrimeCheck.js: -------------------------------------------------------------------------------- 1 | /* 2 | Modified from: 3 | https://github.com/TheAlgorithms/Python/blob/master/maths/prime_check.py 4 | 5 | Complexity: 6 | O(sqrt(n)) 7 | */ 8 | 9 | const PrimeCheck = (n) => { 10 | // input: n: int 11 | // output: boolean 12 | if (n === 1) return false 13 | if (n === 0) return false 14 | if (n === 2) return true 15 | if (n % 2 === 0) return false 16 | 17 | for (let i = 3; i * i <= n; i += 2) { 18 | if (n % i === 0) { 19 | return false 20 | } 21 | } 22 | return true 23 | } 24 | 25 | export { PrimeCheck } 26 | -------------------------------------------------------------------------------- /Maths/PrimeFactors.js: -------------------------------------------------------------------------------- 1 | /* 2 | Modified from: 3 | https://github.com/TheAlgorithms/Python/blob/master/maths/prime_factors.py 4 | */ 5 | 6 | export const PrimeFactors = (n) => { 7 | // input: n: int 8 | // output: primeFactors: Array of all prime factors of n 9 | const primeFactors = [] 10 | for (let i = 2; i * i <= n; i++) { 11 | while (n % i === 0) { 12 | primeFactors.push(i) 13 | n = Math.floor(n / i) 14 | } 15 | } 16 | if (n > 1) { 17 | primeFactors.push(n) 18 | } 19 | return primeFactors 20 | } 21 | -------------------------------------------------------------------------------- /Maths/RadianToDegree.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Radian : https://en.wikipedia.org/wiki/Radian 3 | * Degree : https://en.wikipedia.org/wiki/Degree_(angle) 4 | * 5 | * Angle in Degree = ( Angle in Radian ) x ( 180 / pi ) 6 | * 7 | * Example : 8 | * Question : Convert pi / 2 degree to radian 9 | * So, Angle in Radian = pi / 2 10 | * 11 | * Solution : 12 | * Angle in Degree = ( pi / 2 ) x ( 180 / pi ) = 90 13 | * 14 | * So, pi / 2 radian is equal to 90 degree 15 | */ 16 | 17 | /** 18 | * @param {number} radian 19 | * @return {number} 20 | */ 21 | export const radianToDegree = (radian) => { 22 | return radian * (180 / Math.PI) 23 | } 24 | -------------------------------------------------------------------------------- /Maths/ReversePolishNotation.js: -------------------------------------------------------------------------------- 1 | // Wikipedia: https://en.wikipedia.org/wiki/Reverse_Polish_notation 2 | 3 | const calcRPN = (expression) => { 4 | const operators = { 5 | '+': (a, b) => a + b, 6 | '-': (a, b) => a - b, 7 | '*': (a, b) => a * b, 8 | '/': (a, b) => b / a 9 | } 10 | 11 | const tokens = expression.split(' ') 12 | 13 | const stack = [] 14 | 15 | tokens.forEach((token) => { 16 | const operator = operators[token] 17 | 18 | if (typeof operator === 'function') { 19 | const a = stack.pop() 20 | const b = stack.pop() 21 | 22 | const result = operator(a, b) 23 | 24 | stack.push(result) 25 | } else { 26 | stack.push(parseFloat(token)) 27 | } 28 | }) 29 | 30 | return stack.pop() 31 | } 32 | 33 | export { calcRPN } 34 | -------------------------------------------------------------------------------- /Maths/SieveOfEratosthenes.js: -------------------------------------------------------------------------------- 1 | const sieveOfEratosthenes = (n) => { 2 | /* 3 | * Calculates prime numbers till a number n 4 | * :param n: Number up to which to calculate primes 5 | * :return: A boolean list containing only primes 6 | */ 7 | const primes = new Array(n + 1) 8 | primes.fill(true) // set all as true initially 9 | primes[0] = primes[1] = false // Handling case for 0 and 1 10 | const sqrtn = Math.ceil(Math.sqrt(n)) 11 | for (let i = 2; i <= sqrtn; i++) { 12 | if (primes[i]) { 13 | for (let j = i * i; j <= n; j += i) { 14 | /* 15 | Optimization. 16 | Let j start from i * i, not 2 * i, because smaller multiples of i have been marked false. 17 | 18 | For example, let i = 4. 19 | We do not have to check from 8(4 * 2) to 12(4 * 3) 20 | because they have been already marked false when i=2 and i=3. 21 | */ 22 | primes[j] = false 23 | } 24 | } 25 | } 26 | return primes 27 | } 28 | 29 | export { sieveOfEratosthenes } 30 | -------------------------------------------------------------------------------- /Maths/Softmax.js: -------------------------------------------------------------------------------- 1 | // Wikipedia: https://en.wikipedia.org/wiki/Softmax_function 2 | 3 | const Softmax = (inputs) => { 4 | const eulerExpOfAllInputs = inputs.map(input => Math.exp(input)) 5 | const sumOfEulerExpOfAllInputs = eulerExpOfAllInputs.reduce((a, b) => a + b) 6 | 7 | return inputs.map((input) => { 8 | const eulerExpInputs = Math.exp(input) 9 | return eulerExpInputs / sumOfEulerExpOfAllInputs 10 | }) 11 | } 12 | 13 | export { Softmax } 14 | -------------------------------------------------------------------------------- /Maths/SquareRoot.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Rak Laptudirm 3 | * 4 | * https://en.wikipedia.org/wiki/Newton%27s_method 5 | * 6 | * Finding the square root of a number using Newton's method. 7 | */ 8 | 9 | function sqrt (num, precision = 4) { 10 | if (!Number.isFinite(num)) { throw new TypeError(`Expected a number, received ${typeof num}`) } 11 | if (!Number.isFinite(precision)) { throw new TypeError(`Expected a number, received ${typeof precision}`) } 12 | let sqrt = 1 13 | for (let i = 0; i < precision; i++) { 14 | sqrt -= (sqrt * sqrt - num) / (2 * sqrt) 15 | } 16 | return sqrt 17 | } 18 | 19 | export { sqrt } 20 | -------------------------------------------------------------------------------- /Maths/TwinPrime.js: -------------------------------------------------------------------------------- 1 | import { PrimeCheck } from './PrimeCheck' 2 | 3 | /** 4 | * @function twinPrime 5 | * Gets the 'twin prime' of a prime number. 6 | * 7 | * @param {Integer} n The number to find the twin prime of. 8 | * @returns {Integer} Either the twin, or -1 if n or n + 2 is not prime. 9 | * 10 | * @see https://en.wikipedia.org/wiki/Twin_prime 11 | * 12 | * @example twinPrime(5) = 7 13 | * @example twinPrime(4) = -1 14 | */ 15 | function twinPrime (n) { 16 | const prime = PrimeCheck(n) 17 | 18 | if (!prime) { 19 | return -1 20 | } 21 | 22 | if (!PrimeCheck(n + 2)) { 23 | return -1 24 | } 25 | 26 | return n + 2 27 | } 28 | 29 | export { twinPrime } 30 | -------------------------------------------------------------------------------- /Maths/WhileLoopFactorial.js: -------------------------------------------------------------------------------- 1 | /* 2 | author: Theepag, optimised by merelymyself 3 | */ 4 | export const factorialize = (num) => { 5 | // Step 1. Handles cases where num is 0 or 1, by returning 1. 6 | let result = 1 7 | // Step 2. WHILE loop 8 | while (num > 1) { 9 | result *= num // or result = result * num; 10 | num-- // decrement 1 at each iteration 11 | } 12 | // Step 3. Return the factorial 13 | return result 14 | } 15 | -------------------------------------------------------------------------------- /Maths/ZellersCongruenceAlgorithm.js: -------------------------------------------------------------------------------- 1 | // Zeller's Congruence Algorithm finds the day of the week from the Gregorian Date. Wikipedia: https://en.wikipedia.org/wiki/Zeller%27s_congruence 2 | export const zellersCongruenceAlgorithm = (day, month, year) => { 3 | if (typeof day !== 'number' || typeof month !== 'number' || typeof year !== 'number') { 4 | throw new TypeError('Arguments are not all numbers.') 5 | } 6 | const q = day 7 | let m = month 8 | let y = year 9 | if (month < 3) { 10 | m += 12 11 | y -= 1 12 | } 13 | day = 14 | (q + Math.floor(26 * (m + 1) / 10) + (y % 100) + Math.floor((y % 100) / 4) + Math.floor(Math.floor(y / 100) / 4) + (5 * Math.floor(y / 100))) % 15 | 7 16 | const days = [ 17 | 'Saturday', 18 | 'Sunday', 19 | 'Monday', 20 | 'Tuesday', 21 | 'Wednesday', 22 | 'Thursday', 23 | 'Friday' 24 | ] 25 | return days[day] 26 | } 27 | -------------------------------------------------------------------------------- /Maths/test/AliquotSum.test.js: -------------------------------------------------------------------------------- 1 | import { aliquotSum } from '../AliquotSum' 2 | 3 | describe('Aliquot Sum of a Number', () => { 4 | it('Aliquot Sum of 6', () => { 5 | expect(aliquotSum(6)).toBe(6) 6 | }) 7 | 8 | it('Aliquot Sum of 1', () => { 9 | expect(aliquotSum(1)).toBe(0) 10 | }) 11 | 12 | it('Aliquot Sum of 28', () => { 13 | expect(aliquotSum(28)).toBe(28) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Maths/test/ArmstrongNumber.test.js: -------------------------------------------------------------------------------- 1 | import { armstrongNumber } from '../ArmstrongNumber' 2 | 3 | describe('ArmstrongNumber', () => { 4 | it('should return true for an armstrong number', () => { 5 | expect(armstrongNumber(371)).toBeTruthy() 6 | }) 7 | 8 | it('should return false for a non-armstrong number', () => { 9 | expect(armstrongNumber(300)).toBeFalsy() 10 | }) 11 | it('should return false for negative values', () => { 12 | expect(armstrongNumber(-2)).toBeFalsy() 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Maths/test/AverageMean.test.js: -------------------------------------------------------------------------------- 1 | import { mean } from '../AverageMean' 2 | 3 | describe('Tests for average mean', () => { 4 | it('should be a function', () => { 5 | expect(typeof mean).toEqual('function') 6 | }) 7 | 8 | it('should throw error for invalid input', () => { 9 | expect(() => mean(123)).toThrow() 10 | }) 11 | 12 | it('should return the mean of an array of numbers', () => { 13 | const meanFunction = mean([1, 2, 4, 5]) 14 | expect(meanFunction).toBe(3) 15 | }) 16 | 17 | it('should return the mean of an array of numbers', () => { 18 | const meanFunction = mean([10, 40, 100, 20]) 19 | expect(meanFunction).toBe(42.5) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /Maths/test/AverageMedian.test.js: -------------------------------------------------------------------------------- 1 | import { averageMedian } from '../AverageMedian' 2 | 3 | test('should return the median of an array of numbers:', () => { 4 | const medianValue = averageMedian([1, 2, 6, 4, 5]) 5 | expect(medianValue).toBe(4) 6 | }) 7 | 8 | test('should return the median of an array of numbers:', () => { 9 | const medianValue = averageMedian([8, 9, 1, 2, 5, 10, 11]) 10 | expect(medianValue).toBe(8) 11 | }) 12 | 13 | test('should return the median of an array of numbers:', () => { 14 | const medianValue = averageMedian([15, 18, 3, 9, 13, 5]) 15 | expect(medianValue).toBe(11) 16 | }) 17 | 18 | test('should return the median of an array of numbers:', () => { 19 | const medianValue = averageMedian([1, 2, 3, 4, 6, 8]) 20 | expect(medianValue).toBe(3.5) 21 | }) 22 | -------------------------------------------------------------------------------- /Maths/test/BInaryConvert.test.js: -------------------------------------------------------------------------------- 1 | import { BinaryConvert } from '../BinaryConvert' 2 | 3 | describe('BinaryConvert', () => { 4 | it('should return the correct value', () => { 5 | expect(BinaryConvert(4)).toBe(100) 6 | }) 7 | it('should return the correct value', () => { 8 | expect(BinaryConvert(12)).toBe(1100) 9 | }) 10 | it('should return the correct value of the sum from two number', () => { 11 | expect(BinaryConvert(12 + 2)).toBe(1110) 12 | }) 13 | it('should return the correct value of the subtract from two number', () => { 14 | expect(BinaryConvert(245 - 56)).toBe(10111101) 15 | }) 16 | it('should return the correct value', () => { 17 | expect(BinaryConvert(254)).toBe(11111110) 18 | }) 19 | it('should return the correct value', () => { 20 | expect(BinaryConvert(63483)).toBe(1111011111111011) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /Maths/test/BinaryExponentiationIterative.test.js: -------------------------------------------------------------------------------- 1 | import { exponent } from '../BinaryExponentiationIterative' 2 | 3 | describe('exponent', () => { 4 | it('should return 1 when power is 0', () => { 5 | expect(exponent(5, 0)).toBe(1) 6 | }) 7 | 8 | it('should return 0 when base is 0', () => { 9 | expect(exponent(0, 7)).toBe(0) 10 | }) 11 | 12 | it('should return the value of a base raised to a power', () => { 13 | expect(exponent(3, 5)).toBe(243) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Maths/test/BinaryExponentiationRecursive.test.js: -------------------------------------------------------------------------------- 1 | import { binaryExponentiation } from '../BinaryExponentiationRecursive' 2 | 3 | describe('BinaryExponentiationRecursive', () => { 4 | it('should calculate 2 to the power of 10 correctly', () => { 5 | expect(binaryExponentiation(2, 10)).toBe(1024) 6 | }) 7 | 8 | it('should calculate 3 to the power of 9 correctly', () => { 9 | expect(binaryExponentiation(3, 9)).toBe(19683) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/BisectionMethod.test.js: -------------------------------------------------------------------------------- 1 | import { findRoot } from '../BisectionMethod' 2 | 3 | test('Equation f(x) = x^2 - 3*x + 2 = 0, has root x = 1 in [a, b] = [0, 1.5]', () => { 4 | const root = findRoot(0, 1.5, (x) => { return Math.pow(x, 2) - 3 * x + 2 }, 8) 5 | expect(root).toBe(0.9990234375) 6 | }) 7 | 8 | test('Equation f(x) = ln(x) + sqrt(x) + π*x^2 = 0, has root x = 0.36247037 in [a, b] = [0, 10]', () => { 9 | const root = findRoot(0, 10, (x) => { return Math.log(x) + Math.sqrt(x) + Math.PI * Math.pow(x, 2) }, 32) 10 | expect(Number(Number(root).toPrecision(8))).toBe(0.36247037) 11 | }) 12 | 13 | test('Equation f(x) = sqrt(x) + e^(2*x) - 8*x = 0, has root x = 0.93945851 in [a, b] = [0.5, 100]', () => { 14 | const root = findRoot(0.5, 100, (x) => { return Math.exp(2 * x) + Math.sqrt(x) - 8 * x }, 32) 15 | expect(Number(Number(root).toPrecision(8))).toBe(0.93945851) 16 | }) 17 | -------------------------------------------------------------------------------- /Maths/test/CollatzSequence.test.js: -------------------------------------------------------------------------------- 1 | import { collatz } from '../CollatzSequence' 2 | 3 | describe('The Collatz Sequence', () => { 4 | it('Should be 1', () => { 5 | expect(collatz(1)).toStrictEqual({ result: 1, steps: [] }) 6 | expect(collatz(5)).toStrictEqual({ result: 1, steps: [16, 8, 4, 2, 1] }) 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /Maths/test/DegreeToRadian.test.js: -------------------------------------------------------------------------------- 1 | import { degreeToRadian } from '../DegreeToRadian' 2 | 3 | test('should convert degree to radian:', () => { 4 | const radianEqual = degreeToRadian(0) 5 | expect(radianEqual).toBe(0) 6 | }) 7 | 8 | test('should convert degree to radian:', () => { 9 | const radianEqual = degreeToRadian(45) 10 | expect(radianEqual).toBe(Math.PI / 4) 11 | }) 12 | 13 | test('should convert degree to radian:', () => { 14 | const radianEqual = degreeToRadian(90) 15 | expect(radianEqual).toBe(Math.PI / 2) 16 | }) 17 | 18 | test('should convert degree to radian:', () => { 19 | const radianEqual = degreeToRadian(180) 20 | expect(radianEqual).toBe(Math.PI) 21 | }) 22 | -------------------------------------------------------------------------------- /Maths/test/EulerMethod.test.js: -------------------------------------------------------------------------------- 1 | import { eulerFull, eulerStep } from '../EulerMethod' 2 | 3 | describe('eulerStep', () => { 4 | it('should calculate the next y value correctly', () => { 5 | expect(eulerStep(0, 0.1, 0, function (x, y) { return x })).toBe(0) 6 | expect(eulerStep(2, 1, 1, function (x, y) { return x * x })).toBe(5) 7 | }) 8 | }) 9 | 10 | describe('eulerFull', () => { 11 | it('should return all the points found', () => { 12 | expect(eulerFull(0, 3, 1, 0, function (x, y) { return x })) 13 | .toEqual([{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 1 }, { x: 3, y: 3 }]) 14 | 15 | expect(eulerFull(3, 4, 0.5, 1, function (x, y) { return x * x })) 16 | .toEqual([{ x: 3, y: 1 }, { x: 3.5, y: 5.5 }, { x: 4, y: 11.625 }]) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Maths/test/EulersTotient.test.js: -------------------------------------------------------------------------------- 1 | import { EulersTotient } from '../EulersTotient' 2 | 3 | describe('EulersTotient', () => { 4 | it('should return 6 as 1, 2, 4, 5, 7, and 8 are coprime to 9', () => { 5 | expect(EulersTotient(9)).toBe(6) 6 | }) 7 | 8 | it('should return 4 as 1, 3, 7, and 9 are coprime to 10', () => { 9 | expect(EulersTotient(10)).toBe(4) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/EulersTotientFunction.test.js: -------------------------------------------------------------------------------- 1 | import { eulersTotientFunction } from '../EulersTotientFunction' 2 | 3 | describe('eulersTotientFunction', () => { 4 | it('is a function', () => { 5 | expect(typeof eulersTotientFunction).toEqual('function') 6 | }) 7 | it('should return the phi of a given number', () => { 8 | const phiOfNumber = eulersTotientFunction(10) 9 | expect(phiOfNumber).toBe(4) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/ExtendedEuclideanGCD.test.js: -------------------------------------------------------------------------------- 1 | import { extendedEuclideanGCD } from '../ExtendedEuclideanGCD' 2 | 3 | describe('extendedEuclideanGCD', () => { 4 | it('should return valid values in order for positive arguments', () => { 5 | expect(extendedEuclideanGCD(240, 46)).toMatchObject([2, -9, 47]) 6 | expect(extendedEuclideanGCD(46, 240)).toMatchObject([2, 47, -9]) 7 | }) 8 | it('should give error on non-positive arguments', () => { 9 | expect(() => extendedEuclideanGCD(0, 240)).toThrowError(new TypeError('Must be positive numbers')) 10 | expect(() => extendedEuclideanGCD(46, -240)).toThrowError(new TypeError('Must be positive numbers')) 11 | }) 12 | it('should give error on non-numeric arguments', () => { 13 | expect(() => extendedEuclideanGCD('240', 46)).toThrowError(new TypeError('Not a Number')) 14 | expect(() => extendedEuclideanGCD([240, 46])).toThrowError(new TypeError('Not a Number')) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Maths/test/Factors.test.js: -------------------------------------------------------------------------------- 1 | import { factorsOfANumber } from '../Factors' 2 | 3 | describe('Factors', () => { 4 | factorsOfANumber(50).forEach((num) => { 5 | it(`${num} is a factor of 50`, () => { 6 | const isFactor = 50 % num === 0 7 | expect(isFactor).toBeTruthy() 8 | }) 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /Maths/test/FareyApproximation.test.js: -------------------------------------------------------------------------------- 1 | import { fareyApproximation } from '../FareyApproximation' 2 | 3 | describe('fareyApproximation', () => { 4 | it('Return Farey Approximation of 0.7538385', () => { 5 | const approx = fareyApproximation(0.7538385) 6 | expect(approx).toStrictEqual({ numerator: 52, denominator: 69 }) 7 | }) 8 | 9 | it('Return Farey Approximation of 0.23584936', () => { 10 | const approx = fareyApproximation(0.23584936) 11 | expect(approx).toStrictEqual({ numerator: 196, denominator: 831 }) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /Maths/test/FermatPrimalityTest.test.js: -------------------------------------------------------------------------------- 1 | import { fermatPrimeCheck, modularExponentiation } from '../FermatPrimalityTest' 2 | 3 | describe('modularExponentiation', () => { 4 | it('should give the correct output for all exponentiations', () => { 5 | expect(modularExponentiation(38, 220, 221)).toBe(1) 6 | expect(modularExponentiation(24, 220, 221)).toBe(81) 7 | }) 8 | }) 9 | 10 | describe('fermatPrimeCheck', () => { 11 | it('should give the correct output for prime and composite numbers', () => { 12 | expect(fermatPrimeCheck(2, 35)).toBe(true) 13 | expect(fermatPrimeCheck(10, 30)).toBe(false) 14 | expect(fermatPrimeCheck(94286167)).toBe(true) 15 | expect(fermatPrimeCheck(83165867)).toBe(true) 16 | expect(fermatPrimeCheck(13268774)).toBe(false) 17 | expect(fermatPrimeCheck(13233852)).toBe(false) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Maths/test/FindHcf.test.js: -------------------------------------------------------------------------------- 1 | import { findHCF } from '../FindHcf' 2 | 3 | describe('findHCF', () => { 4 | it('should throw a statement for values less than 1', () => { 5 | expect(findHCF(0, 0)).toBe('Please enter values greater than zero.') 6 | }) 7 | 8 | it('should throw a statement for one value less than 1', () => { 9 | expect(findHCF(0, 1)).toBe('Please enter values greater than zero.') 10 | expect(findHCF(1, 0)).toBe('Please enter values greater than zero.') 11 | }) 12 | 13 | it('should return an error for values non-integer values', () => { 14 | expect(findHCF(2.24, 4.35)).toBe('Please enter whole numbers.') 15 | }) 16 | 17 | it('should return the HCF of two given integers', () => { 18 | expect(findHCF(27, 36)).toBe(9) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /Maths/test/FindLcm.test.js: -------------------------------------------------------------------------------- 1 | import { findLcm } from '../FindLcm' 2 | 3 | describe('findLcm', () => { 4 | it('should throw a statement for values less than 1', () => { 5 | expect(findLcm(0, 0)).toBe('Please enter values greater than zero.') 6 | }) 7 | 8 | it('should throw a statement for one value less than 1', () => { 9 | expect(findLcm(1, 0)).toBe('Please enter values greater than zero.') 10 | expect(findLcm(0, 1)).toBe('Please enter values greater than zero.') 11 | }) 12 | 13 | it('should return an error for values non-integer values', () => { 14 | expect(findLcm(4.564, 7.39)).toBe('Please enter whole numbers.') 15 | }) 16 | 17 | it('should return the LCM of two given integers', () => { 18 | expect(findLcm(27, 36)).toBe(108) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /Maths/test/FindMin.test.js: -------------------------------------------------------------------------------- 1 | import { findMin } from '../FindMin' 2 | 3 | describe('FindMin', () => { 4 | test('Should return the minimum number in the array', () => { 5 | const min = findMin(2, 5, 1, 12, 43, 1, 9) 6 | expect(min).toBe(1) 7 | }) 8 | 9 | test('Should return the minimum number in the array', () => { 10 | const min = findMin(21, 513, 6) 11 | expect(min).toBe(6) 12 | }) 13 | 14 | test('Should throw error', () => { 15 | const min = () => findMin() 16 | expect(min).toThrow('Array is empty') 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Maths/test/GetEuclidGCD.test.js: -------------------------------------------------------------------------------- 1 | import { GetEuclidGCD } from '../GetEuclidGCD' 2 | 3 | function testEuclidGCD (n, m, expected) { 4 | test('Testing on ' + n + ' and ' + m + '!', () => { 5 | expect(GetEuclidGCD(n, m)).toBe(expected) 6 | }) 7 | } 8 | 9 | testEuclidGCD(5, 20, 5) 10 | testEuclidGCD(109, 902, 1) 11 | testEuclidGCD(290, 780, 10) 12 | testEuclidGCD(104, 156, 52) 13 | -------------------------------------------------------------------------------- /Maths/test/GridGet.test.js: -------------------------------------------------------------------------------- 1 | import { gridGetX, gridGetY } from '../GridGet' 2 | 3 | describe('GridGet', () => { 4 | it('should have a value of x for the 27th element if the square array has 400 elements', () => { 5 | expect(gridGetX(Math.sqrt(400), 27)).toEqual(8) 6 | }) 7 | it('should have a value of x for the 11th element if the square array has 7 columns and 3 rows', () => { 8 | expect(gridGetX(7, 11)).toEqual(5) 9 | }) 10 | it('should have a value of y for the 27th element if the square array has 400 elements', () => { 11 | expect(gridGetY(Math.sqrt(400), 27)).toEqual(2) 12 | }) 13 | it('should have a value of y for the 11th element if the square array has 7 columns and 3 rows ', () => { 14 | expect(gridGetX(7, 11)).toEqual(5) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Maths/test/IsDivisible.test.js: -------------------------------------------------------------------------------- 1 | import { isDivisible } from '../IsDivisible' 2 | 3 | describe('isDivisible', () => { 4 | const testCases = [ 5 | [0, 1, true], 6 | [0, 2, true], 7 | [1, 1, true], 8 | [1, 2, false], 9 | [2, 1, true], 10 | [4, 4, true], 11 | [16, 4, true], 12 | [36978235, 5, true], 13 | [36978235, 4, false], 14 | [4.5, 1.5, true], 15 | [4.5, 1.2, false], 16 | [5, 0, false], 17 | [5, -0, false] 18 | ] 19 | 20 | test.each(testCases)('if parameters are (%i, %i) it returns %p', (dividend, divisor, expected) => { 21 | expect(isDivisible(dividend, divisor)).toBe(expected) 22 | }) 23 | 24 | const errorCases = [ 25 | [NaN, NaN], 26 | [NaN, 1], 27 | [1, NaN], 28 | ['1', 1], 29 | [1, '1'], 30 | [1, true], 31 | [false, 2] 32 | ] 33 | 34 | test.each(errorCases)('throws an error if parameters are (%p, %p)', (dividend, divisor) => { 35 | expect(() => { 36 | isDivisible(dividend, divisor) 37 | }).toThrow() 38 | }) 39 | }) 40 | -------------------------------------------------------------------------------- /Maths/test/IsEven.test.js: -------------------------------------------------------------------------------- 1 | import { isEven, isEvenBitwise } from '../IsEven' 2 | 3 | describe('Testing isEven function', () => { 4 | it('should return if the number is even or not', () => { 5 | const isEvenNumber = isEven(4) 6 | expect(isEvenNumber).toBe(true) 7 | }) 8 | 9 | it('should return if the number is even or not', () => { 10 | const isEvenNumber = isEven(7) 11 | expect(isEvenNumber).toBe(false) 12 | }) 13 | }) 14 | 15 | describe('Testing isEvenBitwise function', () => { 16 | it('should return if the number is even or not', () => { 17 | const isEvenNumber = isEvenBitwise(6) 18 | expect(isEvenNumber).toBe(true) 19 | }) 20 | 21 | it('should return if the number is even or not', () => { 22 | const isEvenNumber = isEvenBitwise(3) 23 | expect(isEvenNumber).toBe(false) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /Maths/test/IsOdd.test.js: -------------------------------------------------------------------------------- 1 | import { isOdd, isOddBitwise } from '../IsOdd' 2 | 3 | describe('Testing the isOdd function', () => { 4 | it('should return true, if the number is odd', () => { 5 | const isOddNumber = isOdd(4) 6 | expect(isOddNumber).toBe(false) 7 | }) 8 | 9 | it('should return true, if the number is odd', () => { 10 | const isOddNumber = isOdd(7) 11 | expect(isOddNumber).toBe(true) 12 | }) 13 | }) 14 | 15 | describe('Testing the isOddBitwise function', () => { 16 | it('should return true, if the number is odd', () => { 17 | const isOddNumber = isOddBitwise(6) 18 | expect(isOddNumber).toBe(false) 19 | }) 20 | 21 | it('should return true, if the number is odd', () => { 22 | const isOddNumber = isOddBitwise(3) 23 | expect(isOddNumber).toBe(true) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /Maths/test/IsPronic.test.js: -------------------------------------------------------------------------------- 1 | import { isPronic } from '../IsPronic' 2 | 3 | const pronicNumbers = [0, 2, 6, 12, 20, 30, 42, 56, 72, 90, 110, 132, 156, 182, 210, 240, 272, 306, 342, 380, 420, 462, 506, 552, 600, 650, 702, 756, 812, 870, 930, 992, 1056, 1122, 1190, 1260, 1332, 1406, 1482, 1560, 1640, 1722, 1806, 1892, 1980, 2070, 2162, 2256, 2352, 2450, 2550] 4 | 5 | describe('Testing isPronic function', () => { 6 | for (let i = 0; i <= 2500; i++) { 7 | it('should return true', () => { 8 | const isPronicNumber = isPronic(i) 9 | expect(isPronicNumber).toBe(pronicNumbers.includes(i)) 10 | }) 11 | } 12 | }) 13 | -------------------------------------------------------------------------------- /Maths/test/LeapYear.test.js: -------------------------------------------------------------------------------- 1 | import { isLeapYear } from '../LeapYear' 2 | 3 | describe('Leap Year', () => { 4 | it('Should return true on the year 2000', () => { 5 | expect(isLeapYear(2000)).toBe(true) 6 | }) 7 | it('Should return false on the year 2001', () => { 8 | expect(isLeapYear(2001)).toBe(false) 9 | }) 10 | it('Should return false on the year 2002', () => { 11 | expect(isLeapYear(2002)).toBe(false) 12 | }) 13 | it('Should return false on the year 2003', () => { 14 | expect(isLeapYear(2003)).toBe(false) 15 | }) 16 | it('Should return false on the year 2004', () => { 17 | expect(isLeapYear(2004)).toBe(true) 18 | }) 19 | it('Should return false on the year 1900', () => { 20 | expect(isLeapYear(1900)).toBe(false) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /Maths/test/LinearSieve.test.js: -------------------------------------------------------------------------------- 1 | import { LinearSieve } from '../LinearSieve' 2 | import { PrimeCheck } from '../PrimeCheck' 3 | 4 | describe('LinearSieve', () => { 5 | it('should return primes below 100', () => { 6 | expect(LinearSieve(100)).toEqual([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]) 7 | }) 8 | 9 | it('should return primes only', () => { 10 | const n = 100000 11 | const primes = LinearSieve(n) 12 | for (const p of primes) { 13 | expect(PrimeCheck(p)).toBeTruthy() 14 | } 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Maths/test/LucasSeries.test.js: -------------------------------------------------------------------------------- 1 | import { lucas } from '../LucasSeries' 2 | 3 | describe('Nth Lucas Number', () => { 4 | it('should return the 20th Lucas Number', () => { 5 | expect(lucas(20)).toBe(15127) 6 | }) 7 | 8 | it('should return the 20th Lucas Number', () => { 9 | expect(lucas(0)).toBe(2) 10 | }) 11 | 12 | it('should return the 20th Lucas Number', () => { 13 | expect(lucas(100)).toBe(792070839848372100000) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Maths/test/Mandelbrot.manual-test.js: -------------------------------------------------------------------------------- 1 | import { getRGBData } from '../Mandelbrot' 2 | 3 | // plot the results if the script is executed in a browser with a window-object 4 | if (typeof window !== 'undefined') { 5 | const rgbData = getRGBData() 6 | const width = rgbData.length 7 | const height = rgbData[0].length 8 | const canvas = document.createElement('canvas') 9 | canvas.width = width 10 | canvas.height = height 11 | const ctx = canvas.getContext('2d') 12 | for (let x = 0; x < width; x++) { 13 | for (let y = 0; y < height; y++) { 14 | const rgb = rgbData[x][y] 15 | ctx.fillStyle = 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')' 16 | ctx.fillRect(x, y, 1, 1) 17 | } 18 | } 19 | document.body.append(canvas) 20 | } 21 | -------------------------------------------------------------------------------- /Maths/test/Mandelbrot.test.js: -------------------------------------------------------------------------------- 1 | import { getRGBData } from '../Mandelbrot' 2 | 3 | describe('Mandelbrot', () => { 4 | it('should produce black pixels inside the set', () => { 5 | const blackAndWhite = getRGBData(800, 600, -0.6, 0, 3.2, 50, false) 6 | expect(blackAndWhite[400][300]).toEqual([0, 0, 0]) // black 7 | 8 | const colorCoded = getRGBData(800, 600, -0.6, 0, 3.2, 50, true) 9 | expect(colorCoded[400][300]).toEqual([0, 0, 0]) // black 10 | }) 11 | 12 | it('should produce white pixels outside of the set', () => { 13 | const blackAndWhite = getRGBData(800, 600, -0.6, 0, 3.2, 50, false) 14 | expect(blackAndWhite[0][0]).toEqual([255, 255, 255]) // black 15 | }) 16 | 17 | it('should produce colored pixels distant to the set', () => { 18 | const colorCoded = getRGBData(800, 600, -0.6, 0, 3.2, 50, true) 19 | expect(colorCoded[0][0]).toEqual([255, 0, 0]) // red 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /Maths/test/MeanSquareError.test.js: -------------------------------------------------------------------------------- 1 | import { meanSquaredError } from '../MeanSquareError' 2 | 3 | describe('meanSquareError', () => { 4 | it('should throw an error on non-array arguments', () => { 5 | expect(() => meanSquaredError(1, 4)).toThrow('Argument must be an Array') 6 | }) 7 | 8 | it('should throw an error on non equal length ', () => { 9 | const firstArr = [1, 2, 3, 4, 5] 10 | const secondArr = [1, 2, 3] 11 | expect(() => meanSquaredError(firstArr, secondArr)).toThrow( 12 | 'The two lists must be of equal length' 13 | ) 14 | }) 15 | 16 | it('should return the mean square error of two equal length arrays', () => { 17 | const firstArr = [1, 2, 3, 4, 5] 18 | const secondArr = [1, 3, 5, 6, 7] 19 | expect(meanSquaredError(firstArr, secondArr)).toBe(2.6) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /Maths/test/MidpointIntegration.test.js: -------------------------------------------------------------------------------- 1 | import { integralEvaluation } from '../MidpointIntegration' 2 | 3 | test('Should return the integral of f(x) = sqrt(x) in [1, 3] to be equal 2.797434', () => { 4 | const result = integralEvaluation(10000, 1, 3, (x) => { return Math.sqrt(x) }) 5 | expect(Number(result.toPrecision(6))).toBe(2.79743) 6 | }) 7 | 8 | test('Should return the integral of f(x) = sqrt(x) + x^2 in [1, 3] to be equal 11.46410161', () => { 9 | const result = integralEvaluation(10000, 1, 3, (x) => { return Math.sqrt(x) + Math.pow(x, 2) }) 10 | expect(Number(result.toPrecision(10))).toBe(11.46410161) 11 | }) 12 | 13 | test('Should return the integral of f(x) = log(x) + Pi*x^3 in [5, 12] to be equal 15809.9141543', () => { 14 | const result = integralEvaluation(20000, 5, 12, (x) => { return Math.log(x) + Math.PI * Math.pow(x, 3) }) 15 | expect(Number(result.toPrecision(10))).toBe(15809.91415) 16 | }) 17 | -------------------------------------------------------------------------------- /Maths/test/ModularBinaryExponentiationRecursive.test.js: -------------------------------------------------------------------------------- 1 | import { modularBinaryExponentiation } from '../ModularBinaryExponentiationRecursive' 2 | 3 | describe('modularBinaryExponentiation', () => { 4 | it('should return the binary exponentiation', () => { 5 | expect(modularBinaryExponentiation(2, 10, 17)).toBe(4) 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /Maths/test/NumberOfDigits.test.js: -------------------------------------------------------------------------------- 1 | import { numberOfDigit } from '../NumberOfDigits' 2 | 3 | describe('NumberOfDigits', () => { 4 | it('should return the correct number of digits for an integer', () => { 5 | expect(numberOfDigit(1234000)).toBe(7) 6 | }) 7 | 8 | it('should return the correct number of digits for a negative number', () => { 9 | expect(numberOfDigit(-2346243)).toBe(7) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/Palindrome.test.js: -------------------------------------------------------------------------------- 1 | import { PalindromeRecursive, PalindromeIterative } from '../Palindrome' 2 | 3 | describe('Palindrome', () => { 4 | it('should return true for a palindrome for PalindromeRecursive', () => { 5 | expect(PalindromeRecursive('mom')).toBeTruthy() 6 | }) 7 | it('should return true for a palindrome for PalindromeIterative', () => { 8 | expect(PalindromeIterative('mom')).toBeTruthy() 9 | }) 10 | it('should return false for a non-palindrome for PalindromeRecursive', () => { 11 | expect(PalindromeRecursive('Algorithms')).toBeFalsy() 12 | }) 13 | it('should return true for a non-palindrome for PalindromeIterative', () => { 14 | expect(PalindromeIterative('JavaScript')).toBeFalsy() 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Maths/test/PascalTriangle.test.js: -------------------------------------------------------------------------------- 1 | import { generate } from '../PascalTriangle' 2 | 3 | describe('Pascals Triangle', () => { 4 | it('should have the the same length as the number', () => { 5 | const pascalsTriangle = generate(5) 6 | expect(pascalsTriangle.length).toEqual(5) 7 | }) 8 | it('should have same length as its index in the array', () => { 9 | const pascalsTriangle = generate(5) 10 | pascalsTriangle.forEach((arr, index) => { 11 | expect(arr.length).toEqual(index + 1) 12 | }) 13 | }) 14 | it('should return an array of arrays', () => { 15 | const pascalsTriangle = generate(3) 16 | expect(pascalsTriangle).toEqual( 17 | expect.arrayContaining([[1], [1, 1], [1, 2, 1]]) 18 | ) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /Maths/test/PerfectCube.test.js: -------------------------------------------------------------------------------- 1 | import { perfectCube } from '../PerfectCube' 2 | 3 | describe('PerfectCube', () => { 4 | it('should return true for a perfect cube', () => { 5 | expect(perfectCube(125)).toBeTruthy() 6 | }) 7 | it('should return false for a non perfect cube', () => { 8 | expect(perfectCube(100)).toBeFalsy() 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /Maths/test/PerfectNumber.test.js: -------------------------------------------------------------------------------- 1 | import { perfectNumber } from '../PerfectNumber' 2 | 3 | describe('PerfectNumber', () => { 4 | it('should return true for a perfect cube', () => { 5 | expect(perfectNumber(28)).toBeTruthy() 6 | }) 7 | it('should return false for a non perfect cube', () => { 8 | expect(perfectNumber(10)).toBeFalsy() 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /Maths/test/PerfectSquare.test.js: -------------------------------------------------------------------------------- 1 | import { perfectSquare } from '../PerfectSquare' 2 | 3 | describe('PerfectSquare', () => { 4 | it('should return true for a perfect cube', () => { 5 | expect(perfectSquare(16)).toBeTruthy() 6 | }) 7 | it('should return false for a non perfect cube', () => { 8 | expect(perfectSquare(10)).toBeFalsy() 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /Maths/test/PermutationAndCombination.test.js: -------------------------------------------------------------------------------- 1 | import { factorial, permutation, combination } from '../PermutationAndCombination' 2 | 3 | describe('Factorial', () => { 4 | it('factorial(5)', () => { 5 | expect(factorial(5)).toBe(120) 6 | }) 7 | }) 8 | 9 | describe('Permutation', () => { 10 | it('permutation(5, 2)', () => { 11 | expect(permutation(5, 2)).toBe(20) 12 | }) 13 | }) 14 | 15 | describe('Combination', () => { 16 | it('combination(5, 2)', () => { 17 | expect(combination(5, 2)).toBe(10) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Maths/test/PiApproximationMonteCarlo.test.js: -------------------------------------------------------------------------------- 1 | import { piEstimation } from '../PiApproximationMonteCarlo' 2 | 3 | describe('PiApproximationMonteCarlo', () => { 4 | it('should be between the range of 2 to 4', () => { 5 | const pi = piEstimation() 6 | const piRange = pi >= 2 && pi <= 4 7 | expect(piRange).toBeTruthy() 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /Maths/test/PowLogarithmic.test.js: -------------------------------------------------------------------------------- 1 | import { powLogarithmic } from '../PowLogarithmic' 2 | 3 | describe('PowLogarithmic', () => { 4 | it('should return 1 for numbers with exponent 0', () => { 5 | expect(powLogarithmic(2, 0)).toBe(1) 6 | }) 7 | 8 | it('should return 0 for numbers with base 0', () => { 9 | expect(powLogarithmic(0, 23)).toBe(0) 10 | }) 11 | 12 | it('should return the base to the exponent power', () => { 13 | expect(powLogarithmic(24, 4)).toBe(331776) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /Maths/test/PrimeCheck.test.js: -------------------------------------------------------------------------------- 1 | import { PrimeCheck } from '../PrimeCheck' 2 | 3 | describe('PrimeCheck', () => { 4 | it('should return true for Prime Numbers', () => { 5 | expect(PrimeCheck(1000003)).toBeTruthy() 6 | }) 7 | it('should return false for Non Prime Numbers', () => { 8 | expect(PrimeCheck(1000001)).toBeFalsy() 9 | }) 10 | it('should return false for 1 and 0', () => { 11 | expect(PrimeCheck(1)).toBeFalsy() 12 | expect(PrimeCheck(0)).toBeFalsy() 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Maths/test/PrimeFactors.test.js: -------------------------------------------------------------------------------- 1 | import { PrimeFactors } from '../PrimeFactors' 2 | 3 | describe('EulersTotient', () => { 4 | it('should return the prime factors for 100', () => { 5 | expect(PrimeFactors(100)).toEqual([2, 2, 5, 5]) 6 | }) 7 | 8 | it('should return the prime factors for 2560', () => { 9 | expect(PrimeFactors(2560)).toEqual([2, 2, 2, 2, 2, 2, 2, 2, 2, 5]) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/RadianToDegree.test.js: -------------------------------------------------------------------------------- 1 | import { radianToDegree } from '../RadianToDegree' 2 | 3 | test('should convert radian to degree:', () => { 4 | const degreeEqual = radianToDegree(0) 5 | expect(degreeEqual).toBe(0) 6 | }) 7 | 8 | test('should convert radian to degree:', () => { 9 | const degreeEqual = radianToDegree(Math.PI / 4) 10 | expect(degreeEqual).toBe(45) 11 | }) 12 | 13 | test('should convert radian to degree:', () => { 14 | const degreeEqual = radianToDegree(Math.PI / 2) 15 | expect(degreeEqual).toBe(90) 16 | }) 17 | 18 | test('should convert radian to degree:', () => { 19 | const degreeEqual = radianToDegree(Math.PI) 20 | expect(degreeEqual).toBe(180) 21 | }) 22 | -------------------------------------------------------------------------------- /Maths/test/ReversePolishNotation.test.js: -------------------------------------------------------------------------------- 1 | import { calcRPN } from '../ReversePolishNotation' 2 | 3 | describe('ReversePolishNotation', () => { 4 | it('should evaluate correctly for two values', () => { 5 | expect(calcRPN('2 3 +')).toEqual(5) 6 | }) 7 | it("should evaluate' for multiple values", () => { 8 | expect(calcRPN('2 2 2 * +')).toEqual(6) 9 | expect(calcRPN('6 9 7 + 2 / + 3 *')).toEqual(42) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/SieveOfEratosthenes.test.js: -------------------------------------------------------------------------------- 1 | import { sieveOfEratosthenes } from '../SieveOfEratosthenes' 2 | import { PrimeCheck } from '../PrimeCheck' 3 | 4 | describe('should return an array of prime booleans', () => { 5 | it('should have each element in the array as a prime boolean', () => { 6 | const n = 30 7 | const primes = sieveOfEratosthenes(n) 8 | primes.forEach((primeBool, index) => { 9 | if (primeBool) { 10 | expect(PrimeCheck(index)).toBeTruthy() 11 | } 12 | }) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Maths/test/SimpsonIntegration.test.js: -------------------------------------------------------------------------------- 1 | import { integralEvaluation } from '../SimpsonIntegration' 2 | 3 | test('Should return the integral of f(x) = sqrt(x) in [1, 3] to be equal 2.797434', () => { 4 | const result = integralEvaluation(16, 1, 3, (x) => { return Math.sqrt(x) }) 5 | expect(Number(result.toPrecision(7))).toBe(2.797434) 6 | }) 7 | 8 | test('Should return the integral of f(x) = sqrt(x) + x^2 in [1, 3] to be equal 11.46410161', () => { 9 | const result = integralEvaluation(64, 1, 3, (x) => { return Math.sqrt(x) + Math.pow(x, 2) }) 10 | expect(Number(result.toPrecision(10))).toBe(11.46410161) 11 | }) 12 | 13 | test('Should return the integral of f(x) = log(x) + Pi*x^3 in [5, 12] to be equal 15809.9141543', () => { 14 | const result = integralEvaluation(128, 5, 12, (x) => { return Math.log(x) + Math.PI * Math.pow(x, 3) }) 15 | expect(Number(result.toPrecision(12))).toBe(15809.9141543) 16 | }) 17 | -------------------------------------------------------------------------------- /Maths/test/Softmax.test.js: -------------------------------------------------------------------------------- 1 | import { Softmax } from '../Softmax' 2 | 3 | describe('Softmax', () => { 4 | it('should return equal distribution of 1 for equal input values', () => { 5 | expect(Softmax([1, 1])).toEqual([0.5, 0.5]) 6 | expect(Softmax([1, 1, 1, 1])).toEqual([0.25, 0.25, 0.25, 0.25]) 7 | }) 8 | 9 | it('should return values which sum to the value of 1', () => { 10 | expect(Softmax([1, 2, 3, 4]).reduce((a, b) => a + b, 0)).toEqual(1) 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /Maths/test/SquareRoot.test.js: -------------------------------------------------------------------------------- 1 | import { sqrt } from '../SquareRoot' 2 | 3 | test('Check SquareRoot of 4 is 2', () => { 4 | const res = sqrt(4, 10) 5 | expect(res).toBeCloseTo(2) 6 | }) 7 | 8 | test('Check SquareRoot of 2 is 1.4142135', () => { 9 | const res = sqrt(2, 10) 10 | expect(res).toBeCloseTo(1.4142135) 11 | }) 12 | 13 | test('Check SquareRoot of 3.2 is 1.788854381999832', () => { 14 | const res = sqrt(3.2, 10) 15 | expect(res).toBeCloseTo(1.788854381999832) 16 | }) 17 | 18 | test('Check SquareRoot of 1 is 1', () => { 19 | const res = sqrt(1, 10) 20 | expect(res).toBe(1) 21 | }) 22 | 23 | test('Check SquareRoot of 144 is 12', () => { 24 | const res = sqrt(144, 10) 25 | expect(res).toBeCloseTo(12) 26 | }) 27 | 28 | test('Check SquareRoot of 0 is 0', () => { 29 | const res = sqrt(0, 10) 30 | expect(res).toBeCloseTo(0) 31 | }) 32 | 33 | test('Check SquareRoot of 1000 is 31.62277', () => { 34 | const res = sqrt(1000, 10) 35 | expect(res).toBeCloseTo(31.62277) 36 | }) 37 | -------------------------------------------------------------------------------- /Maths/test/SumOfDigits.test.js: -------------------------------------------------------------------------------- 1 | import { sumOfDigitsUsingLoop, sumOfDigitsUsingRecursion, sumOfDigitsUsingString } from '../SumOfDigits' 2 | 3 | test('Testing on sumOfDigitsUsingLoop', () => { 4 | const sum = sumOfDigitsUsingLoop(123) 5 | expect(sum).toBe(6) 6 | }) 7 | 8 | test('Testing on sumOfDigitsUsingRecursion', () => { 9 | const sum = sumOfDigitsUsingRecursion(123) 10 | expect(sum).toBe(6) 11 | }) 12 | 13 | test('Testing on sumOfDigitsUsingString', () => { 14 | const sum = sumOfDigitsUsingString(123) 15 | expect(sum).toBe(6) 16 | }) 17 | -------------------------------------------------------------------------------- /Maths/test/SumOfGeometricProgression.test.js: -------------------------------------------------------------------------------- 1 | import { sumOfGeometricProgression } from '../SumOfGeometricProgression' 2 | 3 | describe('Sum Of Geometric Progression', () => { 4 | it('should return the sum of a finite GP', () => { 5 | expect(sumOfGeometricProgression(100, 1.5, 4)).toBe(812.5) 6 | }) 7 | 8 | it('should return the sum of an infinite GP', () => { 9 | expect(sumOfGeometricProgression(2, 0.5, Infinity)).toBe(4) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Maths/test/TwinPrime.test.js: -------------------------------------------------------------------------------- 1 | import { twinPrime } from '../TwinPrime.js' 2 | 3 | describe('Twin Primes', () => { 4 | it('Should be valid twin primes', () => { 5 | expect(twinPrime(3)).toBe(5) 6 | expect(twinPrime(5)).toBe(7) 7 | expect(twinPrime(4)).toBe(-1) 8 | expect(twinPrime(17)).toBe(19) 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /Maths/test/WhileLoopFactorial.test.js: -------------------------------------------------------------------------------- 1 | import { factorialize } from '../WhileLoopFactorial' 2 | 3 | function testFactorial (n, expected) { 4 | test('Testing on ' + n + '!', () => { 5 | expect(factorialize(n)).toBe(expected) 6 | }) 7 | } 8 | 9 | testFactorial(3, 6) 10 | testFactorial(7, 5040) 11 | testFactorial(0, 1) 12 | testFactorial(12, 479001600) 13 | -------------------------------------------------------------------------------- /Maths/test/ZellersCongruenceAlgorithm.test.js: -------------------------------------------------------------------------------- 1 | import { zellersCongruenceAlgorithm } from '../ZellersCongruenceAlgorithm' 2 | 3 | function testZeller (day, month, year, expected) { 4 | test('Testing on ' + day + '/' + month + '/' + year, () => { 5 | expect(zellersCongruenceAlgorithm(day, month, year)).toBe(expected) 6 | }) 7 | } 8 | 9 | test('Testing on this/should/throw', () => { 10 | expect(() => { 11 | zellersCongruenceAlgorithm('this', 'should', 'error') 12 | }).toThrowError(new TypeError('Arguments are not all numbers.')) 13 | }) 14 | testZeller(25, 1, 2013, 'Friday') 15 | testZeller(26, 1, 2013, 'Saturday') 16 | testZeller(16, 4, 2022, 'Saturday') 17 | testZeller(25, 4, 2022, 'Monday') 18 | -------------------------------------------------------------------------------- /Navigation/test/Haversine.test.js: -------------------------------------------------------------------------------- 1 | import { haversineDistance } from '../Haversine' 2 | 3 | describe('Testing the haversine distance calculator', () => { 4 | it('Calculate distance', () => { 5 | const distance = haversineDistance(64.1265, -21.8174, 40.7128, -74.0060) 6 | expect(distance).toBe(4208198.758424171) 7 | }) 8 | it('Test validation, expect throw', () => { 9 | expect(() => haversineDistance(64.1265, -21.8174, 40.7128, '74.0060')).toThrow() 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Project-Euler/Problem001.js: -------------------------------------------------------------------------------- 1 | // https://projecteuler.net/problem=1 2 | /* Multiples of 3 and 5 3 | If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. 4 | Find the sum of all the multiples of 3 or 5 below the provided parameter value number. 5 | */ 6 | 7 | const multiplesThreeAndFive = (num) => { 8 | let total = 0 9 | // total for calculating the sum 10 | for (let i = 0; i < num; i++) { 11 | if (i % 3 === 0 || i % 5 === 0) { 12 | total += i 13 | } 14 | } 15 | return total 16 | } 17 | 18 | export { multiplesThreeAndFive } 19 | -------------------------------------------------------------------------------- /Project-Euler/Problem002.js: -------------------------------------------------------------------------------- 1 | // https://projecteuler.net/problem=2 2 | const SQ5 = 5 ** 0.5 // Square root of 5 3 | const PHI = (1 + SQ5) / 2 // definition of PHI 4 | 5 | // theoretically it should take O(1) constant amount of time as long 6 | // arithmetic calculations are considered to be in constant amount of time 7 | export const EvenFibonacci = (limit) => { 8 | const highestIndex = Math.floor(Math.log(limit * SQ5) / Math.log(PHI)) 9 | const n = Math.floor(highestIndex / 3) 10 | return ((PHI ** (3 * n + 3) - 1) / (PHI ** 3 - 1) - 11 | ((1 - PHI) ** (3 * n + 3) - 1) / ((1 - PHI) ** 3 - 1)) / SQ5 12 | } 13 | -------------------------------------------------------------------------------- /Project-Euler/Problem003.js: -------------------------------------------------------------------------------- 1 | // https://projecteuler.net/problem=3 2 | 3 | export const largestPrime = (num = 600851475143) => { 4 | let newnumm = num 5 | let largestFact = 0 6 | let counter = 2 7 | while (counter * counter <= newnumm) { 8 | if (newnumm % counter === 0) { 9 | newnumm = newnumm / counter 10 | } else { 11 | counter++ 12 | } 13 | } 14 | if (newnumm > largestFact) { 15 | largestFact = newnumm 16 | } 17 | return largestFact 18 | } 19 | -------------------------------------------------------------------------------- /Project-Euler/Problem005.js: -------------------------------------------------------------------------------- 1 | /* 2 | Smallest multiple 3 | 4 | 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. 5 | What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? 6 | */ 7 | 8 | export const findSmallestMultiple = () => { 9 | const divisors = [20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2] 10 | let num = 21 11 | let result 12 | 13 | while (!result) { 14 | const isDivisibleByAll = divisors.every((divisor) => num % divisor === 0) 15 | if (isDivisibleByAll) result = num 16 | else num++ 17 | } 18 | 19 | return result 20 | } 21 | -------------------------------------------------------------------------------- /Project-Euler/Problem006.js: -------------------------------------------------------------------------------- 1 | // https://projecteuler.net/problem=6 2 | 3 | export const squareDifference = (num = 100) => { 4 | let sumOfSquares = 0 5 | let sums = 0 6 | for (let i = 1; i <= num; i++) { 7 | sumOfSquares += i ** 2 // add squares to the sum of squares 8 | sums += i // add number to sum to square later 9 | } 10 | return (sums ** 2) - sumOfSquares // difference of square of the total sum and sum of squares 11 | } 12 | -------------------------------------------------------------------------------- /Project-Euler/Problem008.js: -------------------------------------------------------------------------------- 1 | // Problem: https://projecteuler.net/problem=8 2 | 3 | const largestAdjacentNumber = (grid, consecutive) => { 4 | grid = grid.split('\n').join('') 5 | const splitedGrid = grid.split('\n') 6 | let largestProd = 0 7 | 8 | for (const row in splitedGrid) { 9 | const currentRow = splitedGrid[row].split('').map(x => Number(x)) 10 | 11 | for (let i = 0; i < currentRow.length - consecutive; i++) { 12 | const combine = currentRow.slice(i, i + consecutive) 13 | 14 | if (!combine.includes(0)) { 15 | const product = combine.reduce(function (a, b) { 16 | return a * b 17 | }) 18 | 19 | if (largestProd < product) largestProd = product 20 | } 21 | } 22 | } 23 | return largestProd 24 | } 25 | 26 | export { largestAdjacentNumber } 27 | -------------------------------------------------------------------------------- /Project-Euler/Problem009.js: -------------------------------------------------------------------------------- 1 | /* 2 | Special Pythagorean triplet 3 | 4 | A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, 5 | 6 | a^2 + b^2 = c^2 7 | For example, 32 + 42 = 9 + 16 = 25 = 52. 8 | 9 | There exists exactly one Pythagorean triplet for which a + b + c = 1000. 10 | Find the product abc. 11 | */ 12 | 13 | const isPythagoreanTriplet = (a, b, c) => Math.pow(a, 2) + Math.pow(b, 2) === Math.pow(c, 2) 14 | 15 | export const findSpecialPythagoreanTriplet = () => { 16 | for (let a = 0; a < 1000; a++) { 17 | for (let b = a + 1; b < 1000; b++) { 18 | for (let c = b + 1; c < 1000; c++) { 19 | if (isPythagoreanTriplet(a, b, c) && a + b + c === 1000) { 20 | return a * b * c 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Project-Euler/Problem010.js: -------------------------------------------------------------------------------- 1 | // https://projecteuler.net/problem=10 2 | 3 | const isPrime = (number) => { 4 | if (number === 2) return true 5 | if (number % 2 === 0) return false 6 | 7 | for (let j = 3; j * j <= number; j += 2) { 8 | if (number % j === 0) { 9 | return false 10 | } 11 | } 12 | return true 13 | } 14 | 15 | const calculateSumOfPrimeNumbers = (maxNumber) => { 16 | let sum = 0 17 | for (let i = maxNumber - 1; i >= 2; i--) { 18 | if (isPrime(parseInt(i)) === true) { 19 | sum += i 20 | } 21 | } 22 | return sum 23 | } 24 | export { calculateSumOfPrimeNumbers } 25 | -------------------------------------------------------------------------------- /Project-Euler/Problem015.js: -------------------------------------------------------------------------------- 1 | // https://projecteuler.net/problem=15 2 | /* Starting in the top left corner of a 2×2 grid, and only being able to move to 3 | the right and down, there are exactly 6 routes to the bottom right corner. 4 | How many such routes are there through a 20×20 grid? 5 | */ 6 | 7 | // A lattice path is composed of horizontal and vertical lines that pass through lattice points. 8 | 9 | export const latticePath = (gridSize) => { 10 | let paths 11 | for (let i = 1, paths = 1; i <= gridSize; i++) { 12 | paths = paths * (gridSize + i) / i 13 | } 14 | // The total number of paths can be found using the binomial coefficient (b+a)/a. 15 | return paths 16 | } 17 | 18 | // > latticePath(20)) 19 | // 137846528820 20 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem010.test.js: -------------------------------------------------------------------------------- 1 | import { calculateSumOfPrimeNumbers } from '../Problem010' 2 | 3 | describe('checkAnagram', () => { 4 | it('Return the sum of prime numbers up to but less than 14', () => { 5 | const SUT = calculateSumOfPrimeNumbers(14) 6 | expect(SUT).toBe(41) 7 | }) 8 | it('Return the sum of prime numbers up to but less than 10', () => { 9 | const SUT = calculateSumOfPrimeNumbers(10) 10 | expect(SUT).toBe(17) 11 | }) 12 | it('Return the sum of prime numbers up to but less than 100', () => { 13 | const SUT = calculateSumOfPrimeNumbers(100) 14 | expect(SUT).toBe(1060) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem012.test.js: -------------------------------------------------------------------------------- 1 | import { firstTriangularWith500Divisors } from '../Problem012' 2 | 3 | describe('checkFirstTriangularWith500Divisors()', () => { 4 | it('Problem Statement Answer', () => { 5 | const firstTriangular = firstTriangularWith500Divisors() 6 | expect(firstTriangular).toBe(76576500) 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem016.test.js: -------------------------------------------------------------------------------- 1 | import { powerDigitSum } from '../Problem016' 2 | 3 | describe('Check Problem 16 - Power digit sum', () => { 4 | it('Power digit sum of 2^15', () => { 5 | expect(powerDigitSum(2, 15)).toBe(26) 6 | }) 7 | 8 | it('Power digit sum of 2^1000', () => { 9 | expect(powerDigitSum()).toBe(1366) 10 | expect(powerDigitSum(2, 1000)).toBe(1366) 11 | }) 12 | 13 | it('Power digit sum of 3^5000', () => { 14 | expect(powerDigitSum(3, 5000)).toBe(11097) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem018.test.js: -------------------------------------------------------------------------------- 1 | import { maxPathSum } from '../Problem018' 2 | 3 | const example = ` 4 | 3 5 | 7 4 6 | 2 4 6 7 | 8 5 9 3 8 | ` 9 | 10 | describe('Check Problem 18 - Maximum path sum I', () => { 11 | it('Check example', () => { 12 | expect(maxPathSum(example)).toBe(23) 13 | }) 14 | 15 | it('Check solution', () => { 16 | expect(maxPathSum()).toBe(1074) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem020.test.js: -------------------------------------------------------------------------------- 1 | import { factorialDigitSum } from '../Problem020' 2 | 3 | describe('Check Problem 20 - Factorial digit sum', () => { 4 | it('Factorial digit sum of 10!', () => { 5 | expect(factorialDigitSum(10)).toBe(27) 6 | }) 7 | 8 | it('Factorial digit sum of 100!', () => { 9 | expect(factorialDigitSum()).toBe(648) 10 | expect(factorialDigitSum(100)).toBe(648) 11 | }) 12 | 13 | it('Factorial digit sum of 1000!', () => { 14 | expect(factorialDigitSum(1000)).toBe(10539) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /Project-Euler/test/Problem025.test.js: -------------------------------------------------------------------------------- 1 | import { fibonacciIndex } from '../Problem025' 2 | 3 | describe('Check Problem 25 - 1000 digit Fibonnaci number', () => { 4 | it('First term of the Fibonnaci sequence containing 3 digits', () => { 5 | expect(fibonacciIndex(3)).toBe(12) 6 | }) 7 | 8 | it('First term of the Fibonnaci sequence containing 10 digits', () => { 9 | expect(fibonacciIndex(10)).toBe(45) 10 | }) 11 | 12 | it('First term of the Fibonnaci sequence containing 50 digits', () => { 13 | expect(fibonacciIndex(50)).toBe(237) 14 | }) 15 | 16 | it('First term of the Fibonnaci sequence containing 100 digits', () => { 17 | expect(fibonacciIndex(100)).toBe(476) 18 | }) 19 | 20 | it('First term of the Fibonnaci sequence containing 1000 digits', () => { 21 | expect(fibonacciIndex(1000)).toBe(4782) 22 | }) 23 | 24 | it('First term of the Fibonnaci sequence containing 10000 digits', () => { 25 | expect(fibonacciIndex(10000)).toBe(47847) 26 | }) 27 | }) 28 | -------------------------------------------------------------------------------- /Recursive/BinaryEquivalent.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem Statement: Given a positive number `num`, find it's binary equivalent using recursion 3 | * 4 | * What is Binary Equivalent? 5 | * - In binary number system, a number is represented in terms of 0s and 1s, 6 | * for example: 7 | * - Binary Of 2 = 10 8 | * - Binary of 3 = 11 9 | * - Binary of 4 = 100 10 | * 11 | * Reference on how to find Binary Equivalent 12 | * - https://byjus.com/maths/decimal-to-binary/ 13 | * 14 | */ 15 | 16 | export const binaryEquivalent = (num) => { 17 | if (num === 0 || num === 1) { 18 | return String(num) 19 | } 20 | return binaryEquivalent(Math.floor(num / 2)) + String(num % 2) 21 | } 22 | -------------------------------------------------------------------------------- /Recursive/EucledianGCD.js: -------------------------------------------------------------------------------- 1 | function euclideanGCDRecursive (first, second) { 2 | /* 3 | Calculates GCD of two numbers using Euclidean Recursive Algorithm 4 | :param first: First number 5 | :param second: Second number 6 | :return: GCD of the numbers 7 | */ 8 | if (second === 0) { 9 | return first 10 | } else { 11 | return euclideanGCDRecursive(second, (first % second)) 12 | } 13 | } 14 | 15 | function euclideanGCDIterative (first, second) { 16 | /* 17 | Calculates GCD of two numbers using Euclidean Iterative Algorithm 18 | :param first: First number 19 | :param second: Second number 20 | :return: GCD of the numbers 21 | */ 22 | while (second !== 0) { 23 | const temp = second 24 | second = first % second 25 | first = temp 26 | } 27 | return first 28 | } 29 | 30 | export { euclideanGCDIterative, euclideanGCDRecursive } 31 | -------------------------------------------------------------------------------- /Recursive/Factorial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function Factorial 3 | * @description function to find factorial using recursion. 4 | * @param {Integer} n - The input integer 5 | * @return {Integer} - Factorial of n. 6 | * @see [Factorial](https://en.wikipedia.org/wiki/Factorial) 7 | * @example 5! = 1*2*3*4*5 = 120 8 | * @example 2! = 1*2 = 2 9 | */ 10 | 11 | const factorial = (n) => { 12 | if (n === 0) { 13 | return 1 14 | } 15 | return n * factorial(n - 1) 16 | } 17 | 18 | export { factorial } 19 | -------------------------------------------------------------------------------- /Recursive/FibonacciNumberRecursive.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @function Fibonacci 4 | * @description Function to return the N-th Fibonacci number. 5 | * @param {Integer} n - The input integer 6 | * @return {Integer} - Return the N-th Fibonacci number 7 | * @see [Fibonacci](https://en.wikipedia.org/wiki/Fibonacci_number) 8 | */ 9 | 10 | const fibonacci = (n) => { 11 | if (n < 2) { 12 | return n 13 | } 14 | return fibonacci(n - 2) + fibonacci(n - 1) 15 | } 16 | 17 | export { fibonacci } 18 | -------------------------------------------------------------------------------- /Recursive/Palindrome.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function Palindrome 3 | * @description Check whether the given string is Palindrome or not. 4 | * @param {String} str - The input string 5 | * @return {Boolean}. 6 | * @see [Palindrome](https://en.wikipedia.org/wiki/Palindrome) 7 | */ 8 | 9 | const palindrome = (str) => { 10 | if (typeof str !== 'string') { 11 | throw new TypeError('Invalid Input') 12 | } 13 | 14 | if (str.length <= 1) { 15 | return true 16 | } 17 | 18 | if (str[0] !== str[str.length - 1]) { 19 | return false 20 | } else { 21 | return palindrome(str.slice(1, str.length - 1)) 22 | } 23 | } 24 | 25 | export { palindrome } 26 | -------------------------------------------------------------------------------- /Recursive/TowerOfHanoi.js: -------------------------------------------------------------------------------- 1 | // wiki - https://en.wikipedia.org/wiki/Tower_of_Hanoi 2 | // Recursive Javascript function to solve tower of hanoi 3 | 4 | export function TowerOfHanoi (n, from, to, aux, output = []) { 5 | if (n === 1) { 6 | output.push(`Move disk 1 from rod ${from} to rod ${to}`) 7 | return output 8 | } 9 | TowerOfHanoi(n - 1, from, aux, to, output) 10 | output.push(`Move disk ${n} from rod ${from} to rod ${to}`) 11 | TowerOfHanoi(n - 1, aux, to, from, output) 12 | return output 13 | } 14 | 15 | // Driver code (A, C, B are the name of rods) 16 | 17 | // const n = 4 18 | // TowerOfHanoi(n, 'A', 'C', 'B') 19 | -------------------------------------------------------------------------------- /Recursive/test/Factorial.test.js: -------------------------------------------------------------------------------- 1 | import { factorial } from '../Factorial' 2 | 3 | describe('Factorial', () => { 4 | it('should return factorial 1 for value "0"', () => { 5 | expect(factorial(0)).toBe(1) 6 | }) 7 | 8 | it('should return factorial 120 for value "5"', () => { 9 | expect(factorial(5)).toBe(120) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Recursive/test/FibonacciNumberRecursive.test.js: -------------------------------------------------------------------------------- 1 | import { fibonacci } from '../FibonacciNumberRecursive' 2 | 3 | describe('FibonacciNumberRecursive', () => { 4 | it('should return 0', () => { 5 | expect(fibonacci(0)).toBe(0) 6 | }) 7 | 8 | it('should return 1', () => { 9 | expect(fibonacci(1)).toBe(1) 10 | }) 11 | 12 | it('should return 5', () => { 13 | expect(fibonacci(5)).toBe(5) 14 | }) 15 | 16 | it('should return 9', () => { 17 | expect(fibonacci(9)).toBe(34) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Recursive/test/KochSnowflake.test.js: -------------------------------------------------------------------------------- 1 | import { iterate, Vector2 } from '../KochSnowflake' 2 | 3 | describe('KochSnowflake', () => { 4 | it('should produce the correctly-transformed vectors', () => { 5 | expect(iterate([new Vector2(0, 0), new Vector2(1, 0)], 1)[0]) 6 | .toEqual({ x: 0, y: 0 }) 7 | 8 | expect(iterate([new Vector2(0, 0), new Vector2(1, 0)], 1)[1]) 9 | .toEqual({ x: 1 / 3, y: 0 }) 10 | 11 | expect(iterate([new Vector2(0, 0), new Vector2(1, 0)], 1)[2]) 12 | .toEqual({ x: 1 / 2, y: Math.sin(Math.PI / 3) / 3 }) 13 | 14 | expect(iterate([new Vector2(0, 0), new Vector2(1, 0)], 1)[3]) 15 | .toEqual({ x: 2 / 3, y: 0 }) 16 | 17 | expect(iterate([new Vector2(0, 0), new Vector2(1, 0)], 1)[4]) 18 | .toEqual({ x: 1, y: 0 }) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /Recursive/test/palindrome.test.js: -------------------------------------------------------------------------------- 1 | import { palindrome } from '../Palindrome' 2 | 3 | describe('Palindrome', () => { 4 | it('expects to return true for palindrome string', () => { 5 | const isPalindrome = palindrome('madam') 6 | expect(isPalindrome).toBe(true) 7 | }) 8 | 9 | it('expects to return true for Empty String', () => { 10 | const isPalindrome = palindrome('') 11 | expect(isPalindrome).toBe(true) 12 | }) 13 | 14 | it('expects to return false for non-palindrome string', () => { 15 | const isPalindrome = palindrome('foobar') 16 | expect(isPalindrome).toBe(false) 17 | }) 18 | 19 | it('Throw Error for Invalid Input', () => { 20 | expect(() => palindrome(123)).toThrow('Invalid Input') 21 | expect(() => palindrome(null)).toThrow('Invalid Input') 22 | expect(() => palindrome(undefined)).toThrow('Invalid Input') 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /Search/LinearSearch.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Linear search or sequential search is a method for finding a target 3 | * value within a list. It sequentially checks each element of the list 4 | * for the target value until a match is found or until all the elements 5 | * have been searched. 6 | */ 7 | function SearchArray (searchNum, ar, output = v => console.log(v)) { 8 | const position = Search(ar, searchNum) 9 | if (position !== -1) { 10 | output('The element was found at ' + (position + 1)) 11 | } else { 12 | output('The element not found') 13 | } 14 | } 15 | 16 | // Search “theArray” for the specified “key” value 17 | function Search (theArray, key) { 18 | for (let n = 0; n < theArray.length; n++) { 19 | if (theArray[n] === key) { return n } 20 | } 21 | return -1 22 | } 23 | 24 | export { SearchArray, Search } 25 | 26 | // const ar = [1, 2, 3, 4, 5, 6, 7, 8, 9] 27 | // SearchArray(3, ar) 28 | // SearchArray(4, ar) 29 | // SearchArray(11, ar) 30 | -------------------------------------------------------------------------------- /Search/test/ExponentialSearch.test.js: -------------------------------------------------------------------------------- 1 | import { exponentialSearch } from '../ExponentialSearch' 2 | 3 | test('The Exponential Search of the Array [2, 3, 4, 10, 40, 65, 78, 100] is 6 where the value = 78', () => { 4 | const arr = [2, 3, 4, 10, 40, 65, 78, 100] 5 | const value = 78 6 | const result = exponentialSearch(arr, arr.length, value) 7 | expect(result).toEqual(6) 8 | }) 9 | 10 | test('The Exponential Search of the Array [2, 3, 4, 10, 40, 65, 78, 100] is -1 where the value = 178', () => { 11 | const arr = [2, 3, 4, 10, 40, 65, 78, 100] 12 | const value = 178 13 | const result = exponentialSearch(arr, arr.length, value) 14 | expect(result).toEqual(-1) 15 | }) 16 | -------------------------------------------------------------------------------- /Search/test/FibonacciSearch.test.js: -------------------------------------------------------------------------------- 1 | import { fibonacciSearch } from '../FibonacciSearch' 2 | 3 | test('fibonacciSearch([10, 22, 35, 40, 45, 50, 80, 82, 85, 90, 100], 90, arr.length) => 9', () => { 4 | const arr = [10, 22, 35, 40, 45, 50, 80, 82, 85, 90, 100] 5 | const target = 90 6 | const res = fibonacciSearch(arr, target, arr.length) 7 | expect(res).toEqual(9) 8 | }) 9 | 10 | test('fibonacciSearch([1, 11, 55, 56, 78, 82, 104], 104, arr.length) => 6', () => { 11 | const arr = [1, 11, 55, 56, 78, 82, 104] 12 | const target = 104 13 | const res = fibonacciSearch(arr, target, arr.length) 14 | expect(res).toEqual(6) 15 | }) 16 | 17 | test('fibonacciSearch([40, 45, 50, 80, 82, 85, 90, 100]. 190, arr.length) => -1', () => { 18 | const arr = [40, 45, 50, 80, 82, 85, 90, 100] 19 | const target = 190 20 | const res = fibonacciSearch(arr, target, arr.length) 21 | expect(res).toEqual(-1) 22 | }) 23 | -------------------------------------------------------------------------------- /Search/test/SlidingWindow.test.js: -------------------------------------------------------------------------------- 1 | import { slidingWindow } from '../SlidingWindow' 2 | 3 | test('expect to return the largest sum of sequence in the array', () => { 4 | const sum = slidingWindow([1, 2, 5, 2, 8, 1, 5], 2) 5 | expect(sum).toBe(10) 6 | }) 7 | 8 | test('expect to return the largest sum of sequence in the array', () => { 9 | const sum = slidingWindow([5, 2, 6, 9], 3) 10 | expect(sum).toBe(17) 11 | }) 12 | 13 | test('expect to return null when the sequence size is larger then the array length', () => { 14 | const sum = slidingWindow([1, 2, 5, 2, 8, 1, 5], 15) 15 | expect(sum).toBe(null) 16 | }) 17 | -------------------------------------------------------------------------------- /Search/test/jumpSearch.test.js: -------------------------------------------------------------------------------- 1 | import { jumpSearch } from '../JumpSearch' 2 | 3 | test('jumpSearch([0, 0, 4, 7, 10, 23, 34, 40, 55, 68, 77, 90], 77) => 10', () => { 4 | const arr = [0, 0, 4, 7, 10, 23, 34, 40, 55, 68, 77, 90] 5 | const res = jumpSearch(arr, 77) 6 | expect(res).toEqual(10) 7 | }) 8 | 9 | test('jumpSearch([11, 12, 15, 65, 78, 90], 4) => -1', () => { 10 | const arr = [11, 12, 15, 65, 78, 90] 11 | const res = jumpSearch(arr, 4) 12 | expect(res).toEqual(-1) 13 | }) 14 | 15 | test('jumpSearch([11, 12, 15, 65, 78, 90], 11) => 0', () => { 16 | const arr = [11, 12, 15, 65, 78, 90] 17 | const res = jumpSearch(arr, 11) 18 | expect(res).toEqual(0) 19 | }) 20 | -------------------------------------------------------------------------------- /Sorts/BogoSort.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Checks whether the given array is sorted in ascending order. 3 | */ 4 | export function isSorted (array) { 5 | const length = array.length 6 | for (let i = 0; i < length - 1; i++) { 7 | if (array[i] > array[i + 1]) { 8 | return false 9 | } 10 | } 11 | return true 12 | } 13 | 14 | /** 15 | * Shuffles the given array randomly in place. 16 | */ 17 | function shuffle (array) { 18 | for (let i = array.length - 1; i; i--) { 19 | const m = Math.floor(Math.random() * i) 20 | const n = array[i - 1] 21 | array[i - 1] = array[m] 22 | array[m] = n 23 | } 24 | } 25 | 26 | /** 27 | * Implementation of the bogosort algorithm. 28 | * 29 | * This sorting algorithm randomly rearranges the array until it is sorted. 30 | * 31 | * For more information see: https://en.wikipedia.org/wiki/Bogosort 32 | */ 33 | export function bogoSort (items) { 34 | while (!isSorted(items)) { 35 | shuffle(items) 36 | } 37 | return items 38 | } 39 | -------------------------------------------------------------------------------- /Sorts/FindSecondLargestElement.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Find Second Largest is a real technical interview question. 3 | * Chances are you will be asked to find the second largest value 4 | * inside of an array of numbers. You must also be able to filter 5 | * out duplicate values. It's important to know how to do this with 6 | * clean code that is also easy to explain. 7 | * 8 | * Resources: 9 | * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set 10 | */ 11 | 12 | const secondLargestElement = (array) => { 13 | const largestElement = Math.max(...array) 14 | let element = -Number.MAX_VALUE 15 | 16 | for (let i = 0; i < array.length; i++) { 17 | if (element < array[i] && array[i] !== largestElement) { 18 | element = array[i] 19 | } 20 | } 21 | 22 | return element 23 | } 24 | 25 | export { secondLargestElement } 26 | -------------------------------------------------------------------------------- /Sorts/FisherYatesShuffle.js: -------------------------------------------------------------------------------- 1 | export const shuffle = (array) => { 2 | let maxLength = array.length 3 | let temp 4 | let idx 5 | 6 | // While there remain elements to shuffle... 7 | while (maxLength) { 8 | // Pick a remaining element... 9 | idx = Math.floor(Math.random() * maxLength--) 10 | 11 | // And swap it with the current element 12 | temp = array[maxLength] 13 | array[maxLength] = array[idx] 14 | array[idx] = temp 15 | } 16 | 17 | return array 18 | } 19 | -------------------------------------------------------------------------------- /Sorts/GnomeSort.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Gnome sort is a sort algorithm that moving an element to its proper place is accomplished by a series of swap 3 | * more information: https://en.wikipedia.org/wiki/Gnome_sort 4 | * 5 | */ 6 | export function gnomeSort (items) { 7 | if (items.length <= 1) { 8 | return 9 | } 10 | 11 | let i = 1 12 | 13 | while (i < items.length) { 14 | if (items[i - 1] <= items[i]) { 15 | i++ 16 | } else { 17 | [items[i], items[i - 1]] = [items[i - 1], items[i]] 18 | 19 | i = Math.max(1, i - 1) 20 | } 21 | } 22 | return items 23 | } 24 | 25 | // Implementation of gnomeSort 26 | 27 | // const ar = [5, 6, 7, 8, 1, 2, 12, 14] 28 | // gnomeSort(ar) 29 | -------------------------------------------------------------------------------- /Sorts/HeapSortV2.js: -------------------------------------------------------------------------------- 1 | let arrayLength = 0 2 | 3 | /* to create MAX array */ 4 | 5 | function heapRoot (input, i) { 6 | const left = 2 * i + 1 7 | const right = 2 * i + 2 8 | let max = i 9 | 10 | if (left < arrayLength && input[left] > input[max]) { 11 | max = left 12 | } 13 | 14 | if (right < arrayLength && input[right] > input[max]) { 15 | max = right 16 | } 17 | 18 | if (max !== i) { 19 | swap(input, i, max) 20 | heapRoot(input, max) 21 | } 22 | } 23 | 24 | function swap (input, indexA, indexB) { 25 | [input[indexA], input[indexB]] = [input[indexB], input[indexA]] 26 | } 27 | 28 | export function heapSort (input) { 29 | arrayLength = input.length 30 | 31 | for (let i = Math.floor(arrayLength / 2); i >= 0; i -= 1) { 32 | heapRoot(input, i) 33 | } 34 | 35 | for (let i = input.length - 1; i > 0; i--) { 36 | swap(input, 0, i) 37 | arrayLength-- 38 | 39 | heapRoot(input, 0) 40 | } 41 | return input 42 | } 43 | -------------------------------------------------------------------------------- /Sorts/OddEvenSort.js: -------------------------------------------------------------------------------- 1 | /* 2 | odd–even sort or odd–even transposition sort 3 | is a relatively simple sorting algorithm, developed originally for use on parallel processors with local interconnections. 4 | It is a comparison sort related to bubble sort, with which it shares many characteristics. 5 | 6 | for more information : https://en.wikipedia.org/wiki/Odd%E2%80%93even_sort 7 | */ 8 | 9 | // Helper function to swap array items 10 | function swap (arr, i, j) { 11 | const tmp = arr[i] 12 | arr[i] = arr[j] 13 | arr[j] = tmp 14 | } 15 | 16 | export function oddEvenSort (arr) { 17 | let sorted = false 18 | while (!sorted) { 19 | sorted = true 20 | for (let i = 1; i < arr.length - 1; i += 2) { 21 | if (arr[i] > arr[i + 1]) { 22 | swap(arr, i, i + 1) 23 | sorted = false 24 | } 25 | } 26 | for (let i = 0; i < arr.length - 1; i += 2) { 27 | if (arr[i] > arr[i + 1]) { 28 | swap(arr, i, i + 1) 29 | sorted = false 30 | } 31 | } 32 | } 33 | return arr 34 | } 35 | -------------------------------------------------------------------------------- /Sorts/PigeonHoleSort.js: -------------------------------------------------------------------------------- 1 | /* 2 | https://en.wikipedia.org/wiki/Pigeonhole_sort 3 | 4 | *Pigeonhole sorting is a sorting algorithm that is suitable 5 | * for sorting lists of elements where the number of elements 6 | * (n) and the length of the range of possible key values (N) 7 | * are approximately the same. 8 | */ 9 | export function pigeonHoleSort (arr) { 10 | let min = arr[0] 11 | let max = arr[0] 12 | 13 | for (let i = 0; i < arr.length; i++) { 14 | if (arr[i] > max) { max = arr[i] } 15 | if (arr[i] < min) { min = arr[i] } 16 | } 17 | 18 | const range = max - min + 1 19 | const pigeonhole = Array(range).fill(0) 20 | 21 | for (let i = 0; i < arr.length; i++) { 22 | pigeonhole[arr[i] - min]++ 23 | } 24 | 25 | let index = 0 26 | 27 | for (let j = 0; j < range; j++) { 28 | while (pigeonhole[j]-- > 0) { 29 | arr[index++] = j + min 30 | } 31 | } 32 | return arr 33 | } 34 | -------------------------------------------------------------------------------- /Sorts/QuickSort.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function QuickSort 3 | * @description Quick sort is a comparison sorting algorithm that uses a divide and conquer strategy. 4 | * @param {Integer[]} items - Array of integers 5 | * @return {Integer[]} - Sorted array. 6 | * @see [QuickSort](https://en.wikipedia.org/wiki/Quicksort) 7 | */ 8 | function quickSort (items) { 9 | const length = items.length 10 | 11 | if (length <= 1) { 12 | return items 13 | } 14 | const PIVOT = items[0] 15 | const GREATER = [] 16 | const LESSER = [] 17 | 18 | for (let i = 1; i < length; i++) { 19 | if (items[i] > PIVOT) { 20 | GREATER.push(items[i]) 21 | } else { 22 | LESSER.push(items[i]) 23 | } 24 | } 25 | 26 | const sorted = [...quickSort(LESSER), PIVOT, ...quickSort(GREATER)] 27 | return sorted 28 | } 29 | 30 | export { quickSort } 31 | -------------------------------------------------------------------------------- /Sorts/ShellSort.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Shell Sort sorts an array based on insertion sort algorithm 3 | * more information: https://en.wikipedia.org/wiki/Shellsort 4 | * 5 | */ 6 | export function shellSort (items) { 7 | let interval = 1 8 | 9 | while (interval < items.length / 3) { 10 | interval = interval * 3 + 1 11 | } 12 | 13 | while (interval > 0) { 14 | for (let outer = interval; outer < items.length; outer++) { 15 | const value = items[outer] 16 | let inner = outer 17 | 18 | while (inner > interval - 1 && items[inner - interval] >= value) { 19 | items[inner] = items[inner - interval] 20 | inner = inner - interval 21 | } 22 | items[inner] = value 23 | } 24 | interval = (interval - 1) / 3 25 | } 26 | return items 27 | } 28 | -------------------------------------------------------------------------------- /Sorts/StoogeSort.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Stooge Sort sorts an array based on divide and conquer principle 3 | * note the exceptionally bad time complexity 4 | * more information: https://en.wikipedia.org/wiki/Stooge_sort 5 | * 6 | */ 7 | export function stoogeSort (items, leftEnd, rightEnd) { 8 | if (items[rightEnd - 1] < items[leftEnd]) { 9 | const temp = items[leftEnd] 10 | items[leftEnd] = items[rightEnd - 1] 11 | items[rightEnd - 1] = temp 12 | } 13 | const length = rightEnd - leftEnd 14 | if (length > 2) { 15 | const third = Math.floor(length / 3) 16 | stoogeSort(items, leftEnd, rightEnd - third) 17 | stoogeSort(items, leftEnd + third, rightEnd) 18 | stoogeSort(items, leftEnd, rightEnd - third) 19 | } 20 | return items 21 | } 22 | -------------------------------------------------------------------------------- /Sorts/test/BeadSort.test.js: -------------------------------------------------------------------------------- 1 | import { beadSort } from '../BeadSort' 2 | 3 | describe('BeadSort', () => { 4 | it('should sort arrays correctly', () => { 5 | expect(beadSort([5, 4, 3, 2, 1])).toEqual([1, 2, 3, 4, 5]) 6 | expect(beadSort([7, 9, 4, 3, 5])).toEqual([3, 4, 5, 7, 9]) 7 | }) 8 | 9 | it('should throw a RangeError when the array contains negative integers', () => { 10 | expect(() => beadSort([-1, 5, 8, 4, 3, 19])).toThrow(RangeError) 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /Sorts/test/BogoSort.test.js: -------------------------------------------------------------------------------- 1 | import { bogoSort, isSorted } from '../BogoSort' 2 | 3 | describe('isSorted', () => { 4 | it('should return true for empty arrays', () => { 5 | expect(isSorted([])).toBe(true) 6 | }) 7 | 8 | it('should return true for single-element arrays', () => { 9 | expect(isSorted([1])).toBe(true) 10 | }) 11 | 12 | it('should return true for arrays that are properly sorted', () => { 13 | expect(isSorted([1, 2, 3])).toBe(true) 14 | }) 15 | 16 | it('should return false for arrays that are not properly sorted', () => { 17 | expect(isSorted([3, 2, 1])).toBe(false) 18 | }) 19 | }) 20 | 21 | describe('bogoSort', () => { 22 | it('should (eventually) sort the array', () => { 23 | expect(bogoSort([5, 6, 7, 8, 1, 2, 12, 14])).toEqual([1, 2, 5, 6, 7, 8, 12, 14]) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /Sorts/test/CocktailShakerSort.test.js: -------------------------------------------------------------------------------- 1 | import { cocktailShakerSort } from '../CocktailShakerSort' 2 | 3 | describe('CocktailShakerSort', () => { 4 | it('should sort arrays correctly', () => { 5 | expect(cocktailShakerSort([5, 4, 1, 2, 3])).toEqual([1, 2, 3, 4, 5]) 6 | expect(cocktailShakerSort([1, 2, 3])).toEqual([1, 2, 3]) 7 | expect(cocktailShakerSort([5, 6, 7, 8, 1, 2, 12, 14])).toEqual([1, 2, 5, 6, 7, 8, 12, 14]) 8 | }) 9 | 10 | it('should work for empty arrays, too', () => { 11 | expect(cocktailShakerSort([])).toEqual([]) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /Sorts/test/FindSecondLargestElement.test.js: -------------------------------------------------------------------------------- 1 | import { secondLargestElement } from '../FindSecondLargestElement' 2 | 3 | test('The second largest element of the array [1, 2, 3, 4, 5] is 4', () => { 4 | const array = [1, 2, 3, 4, 5] 5 | const res = secondLargestElement(array) 6 | expect(res).toEqual(4) 7 | }) 8 | 9 | test('The second largest element of the array [-1, -2, -3, -4, -5] is -2', () => { 10 | const array = [-1, -2, -3, -4, -5] 11 | const res = secondLargestElement(array) 12 | expect(res).toEqual(-2) 13 | }) 14 | -------------------------------------------------------------------------------- /Sorts/test/FisherYatesShuffle.test.js: -------------------------------------------------------------------------------- 1 | import { shuffle } from '../FisherYatesShuffle' 2 | 3 | describe('shuffle', () => { 4 | it('expects to have a new array with same size', () => { 5 | const fibonacci = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] 6 | const mixedArray = shuffle(fibonacci) 7 | 8 | expect(mixedArray).toHaveLength(fibonacci.length) 9 | }) 10 | 11 | it('expects to have a new array with same values', () => { 12 | const fibonacci = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] 13 | const mixedArray = shuffle(fibonacci) 14 | 15 | expect(mixedArray).toContain(0) 16 | expect(mixedArray).toContain(1) 17 | expect(mixedArray).toContain(2) 18 | expect(mixedArray).toContain(3) 19 | expect(mixedArray).toContain(5) 20 | expect(mixedArray).toContain(8) 21 | expect(mixedArray).toContain(13) 22 | expect(mixedArray).toContain(21) 23 | expect(mixedArray).toContain(34) 24 | expect(mixedArray).toContain(55) 25 | expect(mixedArray).toContain(89) 26 | }) 27 | }) 28 | -------------------------------------------------------------------------------- /Sorts/test/GnomeSort.test.js: -------------------------------------------------------------------------------- 1 | import { gnomeSort } from '../GnomeSort' 2 | 3 | test('The gnomeSort of the array [5, 4, 3, 2, 1] is [1, 2, 3, 4, 5]', () => { 4 | const arr = [5, 4, 3, 2, 1] 5 | const res = gnomeSort(arr) 6 | expect(res).toEqual([1, 2, 3, 4, 5]) 7 | }) 8 | 9 | test('The gnomeSort of the array [-5, 4, -3, 2, -1] is [-5, -3, -1, 2, 4]', () => { 10 | const arr = [-5, 4, -3, 2, -1] 11 | const res = gnomeSort(arr) 12 | expect(res).toEqual([-5, -3, -1, 2, 4]) 13 | }) 14 | 15 | test('The gnomeSort of the array [15, 4, -13, 2, -11] is [-13, -11, 2, 4, 15]', () => { 16 | const arr = [15, 4, -13, 2, -11] 17 | const res = gnomeSort(arr) 18 | expect(res).toEqual([-13, -11, 2, 4, 15]) 19 | }) 20 | -------------------------------------------------------------------------------- /Sorts/test/HeapSort.test.js: -------------------------------------------------------------------------------- 1 | import { heapSort } from '../HeapSort' 2 | 3 | test('The HeapSort of the array [5, 4, 3, 2, 1] is [1, 2, 3, 4, 5]', () => { 4 | const array = [5, 4, 3, 2, 1] 5 | const res = heapSort(array) 6 | expect(res).toEqual([1, 2, 3, 4, 5]) 7 | }) 8 | 9 | test('The HeapSort of the array [-5, -4, -3, -2, -1] is [-5, -4, -3, -2, -1]', () => { 10 | const array = [-5, -4, -3, -2, -1] 11 | const res = heapSort(array) 12 | expect(res).toEqual([-5, -4, -3, -2, -1]) 13 | }) 14 | 15 | test('The HeapSort of the array [50, 43, 31, 52, 91] is [31, 43, 50, 52, 91]', () => { 16 | const array = [50, 43, 31, 52, 91] 17 | const res = heapSort(array) 18 | expect(res).toEqual([31, 43, 50, 52, 91]) 19 | }) 20 | 21 | test('The HeapSort of the array [] is []', () => { 22 | const array = [] 23 | const res = heapSort(array) 24 | expect(res).toEqual([]) 25 | }) 26 | -------------------------------------------------------------------------------- /Sorts/test/HeapSortV2.test.js: -------------------------------------------------------------------------------- 1 | import { heapSort } from '../HeapSortV2' 2 | 3 | test('The heapSort of the array [4, 3, 2, 1] is [1, 2, 3, 4]', () => { 4 | const arr = [4, 3, 2, 1] 5 | const res = heapSort(arr) 6 | expect(res).toEqual([1, 2, 3, 4]) 7 | }) 8 | 9 | test('The heapSort of the array [] is []', () => { 10 | const arr = [] 11 | const res = heapSort(arr) 12 | expect(res).toEqual([]) 13 | }) 14 | 15 | test('The heapSort of the array [41, 31, 32, 31] is [31, 31, 32, 41]', () => { 16 | const arr = [41, 31, 32, 31] 17 | const res = heapSort(arr) 18 | expect(res).toEqual([31, 31, 32, 41]) 19 | }) 20 | -------------------------------------------------------------------------------- /Sorts/test/InsertionSort.test.js: -------------------------------------------------------------------------------- 1 | import { insertionSortAlternativeImplementation } from '../InsertionSort' 2 | 3 | describe('insertionSortAlternativeImplementation', () => { 4 | it('expects to work with empty array', () => { 5 | expect(insertionSortAlternativeImplementation([])).toEqual([]) 6 | }) 7 | 8 | it('expects to return input array when array.length is less than 2', () => { 9 | const input = [3] 10 | expect(insertionSortAlternativeImplementation(input)).toEqual(input) 11 | }) 12 | 13 | it('expects to return array sorted in ascending order', () => { 14 | expect(insertionSortAlternativeImplementation([14, 11])).toEqual([11, 14]) 15 | expect(insertionSortAlternativeImplementation([21, 22, 23])).toEqual([21, 22, 23]) 16 | expect(insertionSortAlternativeImplementation([1, 3, 2, 3, 7, 2])).toEqual([1, 2, 2, 3, 3, 7]) 17 | expect(insertionSortAlternativeImplementation([1, 6, 4, 5, 9, 2])).toEqual([1, 2, 4, 5, 6, 9]) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Sorts/test/MergeSort.test.js: -------------------------------------------------------------------------------- 1 | import { merge, mergeSort } from '../MergeSort' 2 | 3 | describe('merge', () => { 4 | it('should merge arrays correctly', () => { 5 | expect(merge([5, 4], [1, 2, 3])).toEqual([1, 2, 3, 5, 4]) 6 | expect(merge([], [1, 2])).toEqual([1, 2]) 7 | expect(merge([1, 2, 3], [1])).toEqual([1, 1, 2, 3]) 8 | expect(merge([], [])).toEqual([]) 9 | }) 10 | }) 11 | 12 | describe('MergeSort', () => { 13 | it('should work for empty arrays', () => { 14 | expect(mergeSort([])).toEqual([]) 15 | }) 16 | 17 | it('should sort arrays correctly', () => { 18 | expect(mergeSort([5, 4])).toEqual([4, 5]) 19 | expect(mergeSort([8, 4, 10, 15, 9])).toEqual([4, 8, 9, 10, 15]) 20 | expect(mergeSort([1, 2, 3])).toEqual([1, 2, 3]) 21 | expect(mergeSort([10, 5, 3, 8, 2, 6, 4, 7, 9, 1])).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /Sorts/test/OddEvenSort.test.js: -------------------------------------------------------------------------------- 1 | import { oddEvenSort } from '../OddEvenSort' 2 | 3 | test('The OddEvenSort of the array [5, 4, 3, 2, 1] is [1, 2, 3, 4, 5]', () => { 4 | const arr = [5, 4, 3, 2, 1] 5 | const res = oddEvenSort(arr) 6 | expect(res).toEqual([1, 2, 3, 4, 5]) 7 | }) 8 | 9 | test('The OddEvenSort of the array [] is []', () => { 10 | const arr = [] 11 | const res = oddEvenSort(arr) 12 | expect(res).toEqual([]) 13 | }) 14 | 15 | test('The OddEvenSort of the array [10, 14, 12, 20] is [10, 12, 14, 20]', () => { 16 | const arr = [10, 14, 12, 20] 17 | const res = oddEvenSort(arr) 18 | expect(res).toEqual([10, 12, 14, 20]) 19 | }) 20 | 21 | test('The OddEvenSort of the array [166, 169, 144] is [144, 166, 169]', () => { 22 | const arr = [166, 169, 144] 23 | const res = oddEvenSort(arr) 24 | expect(res).toEqual([144, 166, 169]) 25 | }) 26 | -------------------------------------------------------------------------------- /Sorts/test/PancakeSort.test.js: -------------------------------------------------------------------------------- 1 | import { flipArray, findMax, pancakeSort } from '../PancakeSort' 2 | 3 | describe('flipArray', () => { 4 | it('should flip any subarray of any array', () => { 5 | expect(flipArray([1, 2, 3, 4], 0, 3)).toEqual([4, 3, 2, 1]) 6 | expect(flipArray([1, 2, 3, 4, 5], 2, 4)).toEqual([1, 2, 5, 4, 3]) 7 | expect(flipArray([], 0, 0)).toEqual([]) 8 | }) 9 | }) 10 | 11 | describe('findMax', () => { 12 | it('should find the index of the maximum value in any subarray of any array', () => { 13 | expect(findMax([1, 3, 2, 5], 0, 3)).toEqual(3) 14 | expect(findMax([1, 3, 2, 5], 0, 2)).toEqual(1) 15 | }) 16 | }) 17 | 18 | describe('pancakeSort', () => { 19 | it('should sort any array', () => { 20 | expect(pancakeSort([4, 3, 2, 1])).toEqual([1, 2, 3, 4]) 21 | expect(pancakeSort([3, 1, 4, 2])).toEqual([1, 2, 3, 4]) 22 | expect(pancakeSort([100, 1000, 10, 1])).toEqual([1, 10, 100, 1000]) 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /Sorts/test/PigeonHoleSort.test.js: -------------------------------------------------------------------------------- 1 | import { pigeonHoleSort } from '../PigeonHoleSort' 2 | 3 | test('The pigeonHoleSort of the array [1, 4, 3, 2] is [1, 2, 3, 4]', () => { 4 | const arr = [1, 4, 3, 2] 5 | const res = pigeonHoleSort(arr) 6 | expect(res).toEqual([1, 2, 3, 4]) 7 | }) 8 | 9 | test('The pigeonHoleSort of the array [5, 4, 1, 2] is [1, 2, 4, 5]', () => { 10 | const arr = [5, 4, 1, 2] 11 | const res = pigeonHoleSort(arr) 12 | expect(res).toEqual([1, 2, 4, 5]) 13 | }) 14 | 15 | test('The pigeonHoleSort of the array [18, 31, 29, 35, 11] is [11, 18, 29, 31, 35]', () => { 16 | const arr = [18, 31, 29, 35, 11] 17 | const res = pigeonHoleSort(arr) 18 | expect(res).toEqual([11, 18, 29, 31, 35]) 19 | }) 20 | -------------------------------------------------------------------------------- /Sorts/test/QuickSort.test.js: -------------------------------------------------------------------------------- 1 | import { quickSort } from '../QuickSort' 2 | 3 | describe('QuickSort', () => { 4 | it('should work for empty arrays', () => { 5 | expect(quickSort([])).toEqual([]) 6 | }) 7 | 8 | it('should sort arrays correctly', () => { 9 | expect(quickSort([5, 4, 3, 10, 2, 1])).toEqual([1, 2, 3, 4, 5, 10]) 10 | expect(quickSort([5, 4])).toEqual([4, 5]) 11 | expect(quickSort([1, 2, 3])).toEqual([1, 2, 3]) 12 | expect(quickSort([0, 5, 3, 2, 2])).toEqual([0, 2, 2, 3, 5]) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Sorts/test/RadixSort.test.js: -------------------------------------------------------------------------------- 1 | import { radixSort } from '../RadixSort' 2 | 3 | test('The RadixSort of the array [4, 3, 2, 1] is [1, 2, 3, 4]', () => { 4 | const arr = [4, 3, 2, 1] 5 | const res = radixSort(arr, 10) 6 | expect(res).toEqual([1, 2, 3, 4]) 7 | }) 8 | 9 | test('The RadixSort of the array [] is []', () => { 10 | const arr = [] 11 | const res = radixSort(arr, 10) 12 | expect(res).toEqual([]) 13 | }) 14 | 15 | test('The RadixSort of the array [14, 16, 10, 12] is [10, 12, 14, 16]', () => { 16 | const arr = [14, 16, 10, 12] 17 | const res = radixSort(arr, 10) 18 | expect(res).toEqual([10, 12, 14, 16]) 19 | }) 20 | -------------------------------------------------------------------------------- /Sorts/test/SecondLargestElement.test.js: -------------------------------------------------------------------------------- 1 | import { secondLargestElement } from '../FindSecondLargestElement' 2 | 3 | test('The second largest element of the array [100, 200, 300, 400] is 300', () => { 4 | const array = [100, 200, 300, 400] 5 | const res = secondLargestElement(array) 6 | expect(res).toBe(300) 7 | }) 8 | 9 | test('The second largest element of the array [1100, 2400, 1300, 4002] is 2400', () => { 10 | const array = [1100, 2400, 1300, 4002] 11 | const res = secondLargestElement(array) 12 | expect(res).toBe(2400) 13 | }) 14 | 15 | test('The second largest element of the array [10, 20, 39, 34] is 34', () => { 16 | const array = [10, 20, 39, 34] 17 | const res = secondLargestElement(array) 18 | expect(res).toBe(34) 19 | }) 20 | 21 | test('The second largest element of the array [1, 20, 3, 40] is 20', () => { 22 | const array = [1, 20, 3, 40] 23 | const res = secondLargestElement(array) 24 | expect(res).toBe(20) 25 | }) 26 | -------------------------------------------------------------------------------- /Sorts/test/ShellSort.test.js: -------------------------------------------------------------------------------- 1 | import { shellSort } from '../ShellSort' 2 | 3 | test('The ShellSort of the array [5, 4, 3, 2, 1] is [1, 2, 3, 4, 5]', () => { 4 | const arr = [5, 4, 3, 2, 1] 5 | const res = shellSort(arr) 6 | expect(res).toEqual([1, 2, 3, 4, 5]) 7 | }) 8 | 9 | test('The ShellSort of the array [] is []', () => { 10 | const arr = [] 11 | const res = shellSort(arr) 12 | expect(res).toEqual([]) 13 | }) 14 | 15 | test('The ShellSort of the array [15, 24, 31, 42, 11] is [11, 15, 24, 31, 42]', () => { 16 | const arr = [15, 24, 31, 42, 11] 17 | const res = shellSort(arr) 18 | expect(res).toEqual([11, 15, 24, 31, 42]) 19 | }) 20 | 21 | test('The ShellSort of the array [121, 190, 169] is [121, 169, 190]', () => { 22 | const arr = [121, 190, 169] 23 | const res = shellSort(arr) 24 | expect(res).toEqual([121, 169, 190]) 25 | }) 26 | -------------------------------------------------------------------------------- /Sorts/test/SimplifiedWiggleSort.test.js: -------------------------------------------------------------------------------- 1 | import { simplifiedWiggleSort } from '../SimplifiedWiggleSort.js' 2 | 3 | describe('simplified wiggle sort', () => { 4 | test('simplified wiggle sort for chars', () => { 5 | const src = ['a', 'b', 'c'] 6 | expect(simplifiedWiggleSort(src)).toEqual(['a', 'c', 'b']) 7 | }) 8 | 9 | test('wiggle sort with duplicates, even array', () => { 10 | const src = [2, 2, 1, 3] 11 | expect(simplifiedWiggleSort(src)).toEqual([1, 3, 2, 2]) 12 | }) 13 | 14 | test('wiggle sort with duplicates, odd array', () => { 15 | const src = [1, 1, 1, 2, 4] 16 | expect(simplifiedWiggleSort(src)).toEqual([1, 4, 1, 2, 1]) 17 | }) 18 | 19 | test('simplified wiggle sort which leads to equal values next to ' + 20 | 'each other', () => { 21 | const src = [3, 3, 5, 1] 22 | expect(simplifiedWiggleSort(src)).toEqual([1, 5, 3, 3]) 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /Sorts/test/TimSort.test.js: -------------------------------------------------------------------------------- 1 | import { Timsort } from '../TimSort' 2 | 3 | test('The Timsort of the array [5, 4, 3, 2, 1] is [1, 2, 3, 4, 5]', () => { 4 | const arr = [5, 4, 3, 2, 1] 5 | const res = Timsort(arr) 6 | expect(res).toEqual([1, 2, 3, 4, 5]) 7 | }) 8 | 9 | test('The Timsort of the array [] is []', () => { 10 | const arr = [] 11 | const res = Timsort(arr) 12 | expect(res).toEqual([]) 13 | }) 14 | 15 | test('The Timsort of the array [-5, -4, -3, -2, -1] is [-5, -4, -3, -2, -1]', () => { 16 | const arr = [-5, -4, -3, -2, -1] 17 | const res = Timsort(arr) 18 | expect(res).toEqual([-5, -4, -3, -2, -1]) 19 | }) 20 | 21 | test('The Timsort of the array [9, 0, -5, -11, 3] is [-11, -5, 0, 3, 9]', () => { 22 | const arr = [9, 0, -5, -11, 3] 23 | const res = Timsort(arr) 24 | expect(res).toEqual([-11, -5, 0, 3, 9]) 25 | }) 26 | -------------------------------------------------------------------------------- /String/CheckCamelCase.js: -------------------------------------------------------------------------------- 1 | // CheckCamelCase method checks the given string is in camelCase or not. 2 | 3 | // Problem Source & Explanation: https://en.wikipedia.org/wiki/Camel_case 4 | 5 | /** 6 | * checkCamelCase method returns true if the string in camelCase, else return the false. 7 | * @param {String} varName the name of the variable to check. 8 | * @returns `Boolean` return true if the string is in camelCase, else return false. 9 | */ 10 | const checkCamelCase = (varName) => { 11 | // firstly, check that input is a string or not. 12 | if (typeof varName !== 'string') { 13 | throw new TypeError('Argument is not a string.') 14 | } 15 | 16 | const pat = /^[a-z][A-Za-z]*$/ 17 | return pat.test(varName) 18 | } 19 | 20 | export { checkCamelCase } 21 | -------------------------------------------------------------------------------- /String/CheckFlatCase.js: -------------------------------------------------------------------------------- 1 | // checkFlatCase method checks if the given string is in flatcase or not. Flatcase is a convention 2 | // where all letters are in lowercase, and there are no spaces between words. 3 | // thisvariable is an example of flatcase. In camelCase it would be thisVariable, snake_case this_variable and so on. 4 | 5 | // Problem Source & Explanation: https://en.wikipedia.org/wiki/Naming_convention_(programming) 6 | 7 | /** 8 | * checkFlatCase method returns true if the string in flatcase, else return the false. 9 | * @param {string} varname the name of the variable to check. 10 | * @returns {boolean} return true if the string is in flatcase, else return false. 11 | */ 12 | const checkFlatCase = (varname) => { 13 | // firstly, check that input is a string or not. 14 | if (typeof varname !== 'string') { 15 | return new TypeError('Argument is not a string.') 16 | } 17 | 18 | const pat = /^[a-z]*$/ 19 | return pat.test(varname) 20 | } 21 | 22 | export { checkFlatCase } 23 | -------------------------------------------------------------------------------- /String/CheckKebabCase.js: -------------------------------------------------------------------------------- 1 | // CheckKebabCase method checks the given string is in kebab-case or not. 2 | 3 | // Problem Source & Explanation: https://en.wikipedia.org/wiki/Naming_convention_(programming) 4 | 5 | /** 6 | * CheckKebabCase method returns true if the string in kebab-case, else return the false. 7 | * @param {String} varName the name of the variable to check. 8 | * @returns `Boolean` return true if the string is in kebab-case, else return false. 9 | */ 10 | const CheckKebabCase = (varName) => { 11 | // firstly, check that input is a string or not. 12 | if (typeof varName !== 'string') { 13 | return new TypeError('Argument is not a string.') 14 | } 15 | 16 | const pat = /(\w+)-(\w)([\w-]*)/ 17 | return pat.test(varName) && !varName.includes('_') 18 | } 19 | 20 | export { CheckKebabCase } 21 | -------------------------------------------------------------------------------- /String/CheckPalindrome.js: -------------------------------------------------------------------------------- 1 | // Palindrome check is case sensitive; i.e. Aba is not a palindrome 2 | // input is a string 3 | const checkPalindrome = (str) => { 4 | // check that input is a string 5 | if (typeof str !== 'string') { 6 | return 'Not a string' 7 | } 8 | if (str.length === 0) { 9 | return 'Empty string' 10 | } 11 | // Reverse only works with array, thus convert the string to array, reverse it and convert back to string 12 | // return as palindrome if the reversed string is equal to the input string 13 | const reversed = [...str].reverse().join('') 14 | return str === reversed ? 'Palindrome' : 'Not a Palindrome' 15 | } 16 | 17 | export { checkPalindrome } 18 | -------------------------------------------------------------------------------- /String/CheckPascalCase.js: -------------------------------------------------------------------------------- 1 | // CheckPascalCase method checks the given string is in PascalCase or not. 2 | 3 | // Problem Source & Explanation: https://www.theserverside.com/definition/Pascal-case 4 | 5 | /** 6 | * CheckPascalCase method returns true if the string in PascalCase, else return the false. 7 | * @param {String} VarName the name of the variable to check. 8 | * @returns `Boolean` return true if the string is in PascalCase, else return false. 9 | */ 10 | const CheckPascalCase = (VarName) => { 11 | // firstly, check that input is a string or not. 12 | if (typeof VarName !== 'string') { 13 | return new TypeError('Argument is not a string.') 14 | } 15 | 16 | const pat = /^[A-Z][A-Za-z]*$/ 17 | return pat.test(VarName) 18 | } 19 | 20 | export { CheckPascalCase } 21 | -------------------------------------------------------------------------------- /String/CheckSnakeCase.js: -------------------------------------------------------------------------------- 1 | // CheckSnakeCase method checks the given string is in snake_case or not. 2 | 3 | // Problem Source & Explanation: https://en.wikipedia.org/wiki/Naming_convention_(programming) 4 | 5 | /** 6 | * checkSnakeCase method returns true if the string in snake_case, else return the false. 7 | * @param {String} varName the name of the variable to check. 8 | * @returns `Boolean` return true if the string is in snake_case, else return false. 9 | */ 10 | const checkSnakeCase = (varName) => { 11 | // firstly, check that input is a string or not. 12 | if (typeof varName !== 'string') { 13 | throw new TypeError('Argument is not a string.') 14 | } 15 | 16 | const pat = /(.*?)_([a-zA-Z])*/ 17 | return pat.test(varName) 18 | } 19 | 20 | export { checkSnakeCase } 21 | -------------------------------------------------------------------------------- /String/CheckWordOccurrence.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function checkWordOccurrence 3 | * @description - this function count all the words in a sentence and return an word occurrence object 4 | * @param {string} str 5 | * @param {boolean} isCaseSensitive 6 | * @returns {Object} 7 | */ 8 | const checkWordOccurrence = (str, isCaseSensitive = false) => { 9 | if (typeof str !== 'string') { 10 | throw new TypeError('The first param should be a string') 11 | } 12 | 13 | if (typeof isCaseSensitive !== 'boolean') { 14 | throw new TypeError('The second param should be a boolean') 15 | } 16 | 17 | const modifiedStr = isCaseSensitive ? str.toLowerCase() : str 18 | 19 | return modifiedStr 20 | .split(/\s+/) // remove all spaces and distribute all word in List 21 | .reduce( 22 | (occurrence, word) => { 23 | occurrence[word] = occurrence[word] + 1 || 1 24 | return occurrence 25 | }, 26 | {} 27 | ) 28 | } 29 | 30 | export { checkWordOccurrence } 31 | -------------------------------------------------------------------------------- /String/CountVowels.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function countVowels 3 | * @description Given a string of words or phrases, count the number of vowels. 4 | * @param {String} str - The input string 5 | * @return {Number} - The number of vowels 6 | * @example countVowels("ABCDE") => 2 7 | * @example countVowels("Hello") => 2 8 | */ 9 | 10 | const countVowels = (str) => { 11 | if (typeof str !== 'string') { 12 | throw new TypeError('Input should be a string') 13 | } 14 | 15 | const vowelRegex = /[aeiou]/gi 16 | const vowelsArray = str.match(vowelRegex) || [] 17 | 18 | return vowelsArray.length 19 | } 20 | 21 | export { countVowels } 22 | -------------------------------------------------------------------------------- /String/FormatPhoneNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description - function that takes 10 digits and returns a string of the formatted phone number e.g.: 1234567890 -> (123) 456-7890 3 | * @param {string} phoneNumber 4 | * @returns {string} - Format to (XXX) XXX-XXXX pattern 5 | */ 6 | const formatPhoneNumber = (phoneNumber) => { 7 | if ((phoneNumber.length !== 10) || isNaN(phoneNumber)) { 8 | // return "Invalid phone number." 9 | throw new TypeError('Invalid phone number!') 10 | } 11 | 12 | let index = 0 13 | return '(XXX) XXX-XXXX'.replace(/X/g, () => phoneNumber[index++]) 14 | } 15 | 16 | export default formatPhoneNumber 17 | -------------------------------------------------------------------------------- /String/GenerateGUID.js: -------------------------------------------------------------------------------- 1 | /* 2 | Generates a UUID/GUID in Node.Js. 3 | The script uses `Math.random` in combination with the timestamp for better randomness. 4 | The function generate an RFC4122 (https://www.ietf.org/rfc/rfc4122.txt) version 4 UUID/GUID 5 | */ 6 | 7 | export const Guid = () => { 8 | const pattern = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' 9 | let currentDateMilliseconds = new Date().getTime() 10 | return pattern.replace(/[xy]/g, currentChar => { 11 | const randomChar = (currentDateMilliseconds + Math.random() * 16) % 16 | 0 12 | currentDateMilliseconds = Math.floor(currentDateMilliseconds / 16) 13 | return (currentChar === 'x' ? randomChar : (randomChar & 0x7 | 0x8)).toString(16) 14 | }) 15 | } 16 | 17 | // > Guid() 18 | // 'edc848db-3478-1760-8b55-7986003d895f' 19 | -------------------------------------------------------------------------------- /String/HammingDistance.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Hamming Distance: https://en.wikipedia.org/wiki/Hamming_distance 3 | * 4 | * 5 | * Hamming distance is a metric for comparing two binary data strings. 6 | * 7 | * While comparing two binary strings of equal length, Hamming distance 8 | * is the number of bit positions in which the two bits are different. 9 | * The Hamming distance between two strings, a and b is denoted as d(a,b) 10 | */ 11 | 12 | /** 13 | * @param {string} a 14 | * @param {string} b 15 | * @return {number} 16 | */ 17 | 18 | export const hammingDistance = (a, b) => { 19 | if (a.length !== b.length) { 20 | throw new Error('Strings must be of the same length') 21 | } 22 | 23 | let distance = 0 24 | 25 | for (let i = 0; i < a.length; i += 1) { 26 | if (a[i] !== b[i]) { 27 | distance += 1 28 | } 29 | } 30 | 31 | return distance 32 | } 33 | -------------------------------------------------------------------------------- /String/Lower.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function lower 3 | * @description Will convert the entire string to lowercase letters. 4 | * @param {String} str - The input string 5 | * @returns {String} Lowercase string 6 | * @example lower("HELLO") => hello 7 | * @example lower("He_llo") => he_llo 8 | */ 9 | 10 | const lower = (str) => { 11 | if (typeof str !== 'string') { 12 | throw new TypeError('Invalid Input Type') 13 | } 14 | 15 | return str.replace( 16 | /[A-Z]/g, (char) => String.fromCharCode(char.charCodeAt() + 32) 17 | ) 18 | } 19 | 20 | export default lower 21 | -------------------------------------------------------------------------------- /String/ReverseWords.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function reverseWords 3 | * @param {string} str 4 | * @returns {string} - reverse string 5 | */ 6 | const reverseWords = (str) => { 7 | if (typeof str !== 'string') { 8 | throw new TypeError('The given value is not a string') 9 | } 10 | 11 | return str 12 | .split(/\s+/) // create an array with each word in string 13 | .reduceRight((reverseStr, word) => `${reverseStr} ${word}`, '') // traverse the array from last & create an string 14 | .trim() // remove the first useless space 15 | } 16 | 17 | export default reverseWords 18 | -------------------------------------------------------------------------------- /String/Upper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function upper 3 | * @description Will convert the entire string to uppercase letters. 4 | * @param {String} str - The input string 5 | * @return {String} Uppercase string 6 | * @example upper("hello") => HELLO 7 | * @example upper("He_llo") => HE_LLO 8 | */ 9 | const upper = (str) => { 10 | if (typeof str !== 'string') { 11 | throw new TypeError('Argument should be string') 12 | } 13 | 14 | return str.replace( 15 | /[a-z]/g, (char) => String.fromCharCode(char.charCodeAt() - 32) 16 | ) 17 | } 18 | 19 | export default upper 20 | -------------------------------------------------------------------------------- /String/ValidateEmail.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns whether the given string is a valid email address or not. 3 | */ 4 | const validateEmail = (str) => { 5 | if (str === '' || str === null) { 6 | throw new TypeError('Email Address String Null or Empty.') 7 | } 8 | 9 | return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str) 10 | } 11 | 12 | export { validateEmail } 13 | -------------------------------------------------------------------------------- /String/ValidateUrl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function ValidateURL 3 | * @description validate the URL. 4 | * @param {String} url - The input URL string 5 | * @return {Boolean} 6 | */ 7 | const validateURL = (url) => { 8 | const URL_PATTERN = /^(https?:\/\/(?:www\.|(?!www))[^\s.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})$/gi 9 | 10 | return URL_PATTERN.test(url) 11 | } 12 | 13 | export { validateURL } 14 | -------------------------------------------------------------------------------- /String/test/AlphaNumericPalindrome.test.js: -------------------------------------------------------------------------------- 1 | import alphaNumericPalindrome from '../AlphaNumericPalindrome' 2 | 3 | describe('Testing the alpha numeric palindrome', () => { 4 | // should return true if the given string has alphanumeric characters that are palindrome irrespective of case and symbols 5 | it('Testing with valid alphabetic palindrome', () => { 6 | expect(alphaNumericPalindrome('eye')).toBe(true) 7 | expect(alphaNumericPalindrome('Madam')).toBe(true) 8 | expect(alphaNumericPalindrome('race CAR')).toBe(true) 9 | expect(alphaNumericPalindrome('A man, a plan, a canal. Panama')).toBe(true) 10 | }) 11 | 12 | it('Testing with number and symbol', () => { 13 | expect(alphaNumericPalindrome('0_0 (: /-:) 0-0')).toBe(true) 14 | expect(alphaNumericPalindrome('03_|53411435|_30')).toBe(true) 15 | }) 16 | 17 | it('Testing with alphabets and symbols', () => { 18 | expect(alphaNumericPalindrome('five|_/|evif')).toBe(true) 19 | expect(alphaNumericPalindrome('five|_/|four')).toBe(false) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /String/test/AlternativeStringArrange.test.js: -------------------------------------------------------------------------------- 1 | import { AlternativeStringArrange } from '../AlternativeStringArrange' 2 | 3 | test('AlternativeStringArrange(Agrtm, loih) -> Algorithm', () => { 4 | const str1 = 'Agrtm' 5 | const str2 = 'loih' 6 | const res = AlternativeStringArrange(str1, str2) 7 | expect(res).toEqual('Algorithm') 8 | }) 9 | 10 | test('AlternativeStringArrange(JvSrp, aacit) -> JavaScript', () => { 11 | const str1 = 'JvSrp' 12 | const str2 = 'aacit' 13 | const res = AlternativeStringArrange(str1, str2) 14 | expect(res).toEqual('JavaScript') 15 | }) 16 | 17 | test('AlternativeStringArrange(abc, def) -> adbecf', () => { 18 | const str1 = 'abc' 19 | const str2 = 'def' 20 | const res = AlternativeStringArrange(str1, str2) 21 | expect(res).toEqual('adbecf') 22 | }) 23 | -------------------------------------------------------------------------------- /String/test/CheckCamelCase.test.js: -------------------------------------------------------------------------------- 1 | import { checkCamelCase } from '../CheckCamelCase' 2 | describe('checkCamelCase', () => { 3 | it('expect to throw an error if input is not a string', () => { 4 | expect(() => checkCamelCase(null)).toThrow() 5 | }) 6 | 7 | it('expects to return true if the input is in camel case format', () => { 8 | const value = 'dockerBuild' 9 | const result = checkCamelCase(value) 10 | expect(result).toBe(true) 11 | }) 12 | 13 | it('expects to return false if the input is not in camel case format', () => { 14 | const value = 'docker_build' 15 | const result = checkCamelCase(value) 16 | expect(result).toBe(false) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /String/test/CheckFlatCase.test.js: -------------------------------------------------------------------------------- 1 | import { checkFlatCase } from '../CheckFlatCase' 2 | 3 | describe('checkFlatCase function', () => { 4 | it('should return false when the input string is not in flatcase', () => { 5 | const actual = checkFlatCase('this is not in flatcase') 6 | expect(actual).toBe(false) 7 | }) 8 | 9 | it('should return true when the input string is a single letter character', () => { 10 | const actual = checkFlatCase('a') 11 | expect(actual).toBe(true) 12 | }) 13 | 14 | it('should return true when the input string is a string of lowercase letter characters with no spaces', () => { 15 | const actual = checkFlatCase('abcdefghijklmnopqrstuvwxyz') 16 | expect(actual).toBe(true) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /String/test/CheckKebabCase.test.js: -------------------------------------------------------------------------------- 1 | import { CheckKebabCase } from '../CheckKebabCase' 2 | 3 | test('CheckKebabCase(The-Algorithms) -> true', () => { 4 | const word = 'The-Algorithms' 5 | const res = CheckKebabCase(word) 6 | expect(res).toBeTruthy() 7 | }) 8 | 9 | test('CheckKebabCase(The Algorithms) -> false', () => { 10 | const word = 'The Algorithms' 11 | const res = CheckKebabCase(word) 12 | expect(res).toBeFalsy() 13 | }) 14 | -------------------------------------------------------------------------------- /String/test/CheckPalindrome.test.js: -------------------------------------------------------------------------------- 1 | import { checkPalindrome } from '../CheckPalindrome' 2 | 3 | describe('checkPalindrome', () => { 4 | it('expects to return "Palindrome" if the given string is a palindrome', () => { 5 | const SUT = checkPalindrome('madam') 6 | expect(SUT).toBe('Palindrome') 7 | }) 8 | it('expects to return "Empty string" if the given string is empty', () => { 9 | const SUT = checkPalindrome('') 10 | expect(SUT).toBe('Empty string') 11 | }) 12 | it('expects to return "Not a string" if the given string is not a string', () => { 13 | const SUT = checkPalindrome(123) 14 | expect(SUT).toBe('Not a string') 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /String/test/CheckPascalCase.test.js: -------------------------------------------------------------------------------- 1 | import { CheckPascalCase } from '../CheckPascalCase' 2 | 3 | test('CheckPascalCase(TheAlgorithms) -> true', () => { 4 | const word = 'TheAlgorithms' 5 | const res = CheckPascalCase(word) 6 | expect(res).toBeTruthy() 7 | }) 8 | 9 | test('CheckPascalCase(theAlgorithms) -> false', () => { 10 | const word = 'theAlgorithms' 11 | const res = CheckPascalCase(word) 12 | expect(res).toBeFalsy() 13 | }) 14 | 15 | test('CheckPascalCase(The Algorithms) -> false', () => { 16 | const word = 'The Algorithms' 17 | const res = CheckPascalCase(word) 18 | expect(res).toBeFalsy() 19 | }) 20 | -------------------------------------------------------------------------------- /String/test/CheckRearrangePalindrome.test.js: -------------------------------------------------------------------------------- 1 | import { palindromeRearranging } from '../CheckRearrangePalindrome' 2 | 3 | test('palindromeRearranging(apple) -> false', () => { 4 | const word = 'apple' 5 | const res = palindromeRearranging(word) 6 | expect(res).toBeFalsy() 7 | }) 8 | 9 | test('palindromeRearranging(aapplle) -> true', () => { 10 | const word = 'aapplle' 11 | const res = palindromeRearranging(word) 12 | expect(res).toBeTruthy() 13 | }) 14 | 15 | test('palindromeRearranging(value) -> false', () => { 16 | const word = 'value' 17 | const res = palindromeRearranging(word) 18 | expect(res).toBeFalsy() 19 | }) 20 | 21 | test('palindromeRearranging(aaeccrr) -> true', () => { 22 | const word = 'aaeccrr' 23 | const res = palindromeRearranging(word) 24 | expect(res).toBeTruthy() 25 | }) 26 | -------------------------------------------------------------------------------- /String/test/CheckSnakeCase.test.js: -------------------------------------------------------------------------------- 1 | import { checkSnakeCase } from '../CheckSnakeCase' 2 | describe('checkSnakeCase', () => { 3 | it('expect to throw an error if input is not a string', () => { 4 | expect(() => checkSnakeCase(0)).toThrow() 5 | }) 6 | 7 | it('expects to return true if the input is in snake case format', () => { 8 | const value = 'docker_build' 9 | const result = checkSnakeCase(value) 10 | expect(result).toBe(true) 11 | }) 12 | 13 | it('expects to return false if the input is not in snake case format', () => { 14 | const value = 'dockerBuild' 15 | const result = checkSnakeCase(value) 16 | expect(result).toBe(false) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /String/test/CreatePermutations.test.js: -------------------------------------------------------------------------------- 1 | import { createPermutations } from '../CreatePermutations' 2 | 3 | describe('createPermutations', () => { 4 | it('expects to generate 6 different combinations', () => { 5 | const text = 'abc' 6 | const SUT = createPermutations(text) 7 | expect(SUT).toStrictEqual(['abc', 'acb', 'bac', 'bca', 'cab', 'cba']) 8 | }) 9 | it('expects to generate 2 different combinations', () => { 10 | const text = '12' 11 | const SUT = createPermutations(text) 12 | expect(SUT).toStrictEqual(['12', '21']) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /String/test/DiceCoefficient.test.js: -------------------------------------------------------------------------------- 1 | import { diceCoefficient } from '../DiceCoefficient' 2 | 3 | describe('diceCoefficient', () => { 4 | it('should calculate edit distance between two strings', () => { 5 | // equal strings return 1 (max possible value) 6 | expect(diceCoefficient('abc', 'abc')).toBe(1) 7 | expect(diceCoefficient('', '')).toBe(1) 8 | 9 | // string length needs to be at least 2 (unless equal) 10 | expect(diceCoefficient('a', '')).toBe(0) 11 | expect(diceCoefficient('', 'a')).toBe(0) 12 | 13 | expect(diceCoefficient('skate', 'ate')).toBe(0.66) 14 | 15 | expect(diceCoefficient('money', 'honey')).toBe(0.75) 16 | 17 | expect(diceCoefficient('love', 'hate')).toBe(0) 18 | 19 | expect(diceCoefficient('skilled', 'killed')).toBe(0.9) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /String/test/FormatPhoneNumber.test.js: -------------------------------------------------------------------------------- 1 | import formatPhoneNumber from '../FormatPhoneNumber' 2 | 3 | describe('Testing the formatPhoneNumber functions', () => { 4 | it('expects to throw a type error', () => { 5 | expect(() => formatPhoneNumber('1234567')).toThrow('Invalid phone number!') 6 | expect(() => formatPhoneNumber('123456text')).toThrow('Invalid phone number!') 7 | expect(() => formatPhoneNumber(12345)).toThrow('Invalid phone number!') 8 | }) 9 | 10 | it('expects to return the formatted phone number', () => { 11 | expect(formatPhoneNumber('1234567890')).toEqual('(123) 456-7890') 12 | expect(formatPhoneNumber('2124323322')).toEqual('(212) 432-3322') 13 | expect(formatPhoneNumber('1721543455')).toEqual('(172) 154-3455') 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /String/test/HammingDistance.test.js: -------------------------------------------------------------------------------- 1 | import { hammingDistance } from '../HammingDistance' 2 | 3 | test('should throw an error when trying to compare the strings of different length', () => { 4 | const compareStringsOfDifferentLength = () => { 5 | hammingDistance('abc', 'abcd') 6 | } 7 | 8 | expect(compareStringsOfDifferentLength).toThrowError() 9 | }) 10 | 11 | test('should calculate difference between two strings', () => { 12 | expect(hammingDistance('a', 'a')).toBe(0) 13 | }) 14 | 15 | test('should calculate difference between two strings', () => { 16 | expect(hammingDistance('abc', 'add')).toBe(2) 17 | }) 18 | 19 | test('should calculate difference between two strings', () => { 20 | expect(hammingDistance('1011101', '1001001')).toBe(2) 21 | }) 22 | -------------------------------------------------------------------------------- /String/test/KMPPatternSearching.test.js: -------------------------------------------------------------------------------- 1 | import { KMPSearch } from '../KMPPatternSearching' 2 | 3 | describe('KMP Matcher', () => { 4 | it('TC1: expects to return matching indices for pattern in text', () => { 5 | const text = 'ABC ABCDAB ABCDABCDABDE' 6 | const pattern = 'ABCDABD' 7 | expect(KMPSearch(text, pattern)).toStrictEqual([15]) 8 | }) 9 | 10 | it('TC2: expects to return matching indices for pattern in text', () => { 11 | const text = 'ABC ABCDABD ABCDABCDABDE' 12 | const pattern = 'ABCDABD' 13 | expect(KMPSearch(text, pattern)).toStrictEqual([4, 16]) 14 | }) 15 | 16 | it('TC3: expects to return matching indices for pattern in text', () => { 17 | const text = 'AAAAA' 18 | const pattern = 'AAA' 19 | expect(KMPSearch(text, pattern)).toStrictEqual([0, 1, 2]) 20 | }) 21 | 22 | it('TC4: expects to return matching indices for pattern in text', () => { 23 | const text = 'ABCD' 24 | const pattern = 'BA' 25 | expect(KMPSearch(text, pattern)).toStrictEqual([]) 26 | }) 27 | }) 28 | -------------------------------------------------------------------------------- /String/test/Lower.test.js: -------------------------------------------------------------------------------- 1 | import lower from '../Lower' 2 | 3 | describe('Testing the Lower function', () => { 4 | it('Test 1: Check by invalid type', () => { 5 | expect(() => lower(345)).toThrowError() 6 | expect(() => lower(true)).toThrowError() 7 | expect(() => lower(null)).toThrowError() 8 | }) 9 | 10 | it('Test 2: Check by uppercase string', () => { 11 | expect(lower('WORLD')).toBe('world') 12 | expect(lower('Hello_WORLD')).toBe('hello_world') 13 | }) 14 | 15 | it('Test 3: Check by lowercase string', () => { 16 | expect(lower('hello')).toBe('hello') 17 | expect(lower('hello_world')).toBe('hello_world') 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /String/test/MaxCharacter.test.js: -------------------------------------------------------------------------------- 1 | import maxCharacter from '../MaxCharacter' 2 | 3 | describe('Testing the maxCharacter function', () => { 4 | it('Expect throw with wrong arg', () => { 5 | expect(() => maxCharacter(123)).toThrow() 6 | expect(() => maxCharacter('')).toThrow() 7 | }) 8 | 9 | it('Check the max character in string', () => { 10 | const theString = 'I can\'t do that' 11 | const maxCharInAllCount = maxCharacter(theString) 12 | const maxChar = maxCharacter(theString, /\s/) 13 | 14 | expect(maxCharInAllCount).toBe(' ') 15 | expect(maxChar).toBe('t') 16 | 17 | expect(maxCharacter('!!!Hello, World!!!', /[a-z]/)).toBe('!') 18 | 19 | expect(maxCharacter('!!!Hello, World!!!', /[^a-z]/i)).toBe('l') 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /String/test/MaxWord.test.js: -------------------------------------------------------------------------------- 1 | import { maxWord } from '../MaxWord' 2 | 3 | describe('Testing the maxWord function', () => { 4 | it('Expect throw with non string argument', () => { 5 | expect(() => maxWord(10)).toThrow() 6 | }) 7 | it('get the max word', () => { 8 | const string = 'be be be be a a banana' 9 | const mostOccurringWord = maxWord(string) 10 | expect(mostOccurringWord).toBe('be') 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /String/test/PermutateString.test.js: -------------------------------------------------------------------------------- 1 | import { permutate } from '../PermutateString' 2 | 3 | describe('Permutate a string', () => { 4 | it('expects to throw an Error with an empty string', () => { 5 | expect(() => { permutate() }).toThrow('The arg must be a valid, non empty string') 6 | }) 7 | it('expects to permute "no" into [no, on]', () => { 8 | expect(['no', 'on']).toEqual(permutate('no')) 9 | }) 10 | it('expects to permute "yes" into [esy, eys, sey, sye, yes, yse]', () => { 11 | expect(['esy', 'eys', 'sey', 'sye', 'yes', 'yse']).toEqual(permutate('yes')) 12 | }) 13 | it('expects to permute "good" into [dgoo dogo doog gdoo godo good odgo odog ogdo ogod oodg oogd ]', () => { 14 | expect(['dgoo', 'dogo', 'doog', 'gdoo', 'godo', 'good', 'odgo', 'odog', 'ogdo', 'ogod', 'oodg', 'oogd']) 15 | .toEqual(permutate('good')) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /String/test/ReverseWords.test.js: -------------------------------------------------------------------------------- 1 | import reverseWords from '../ReverseWords' 2 | 3 | describe('Testing the reverseWords function', () => { 4 | it.each` 5 | input 6 | ${123456} 7 | ${[1, 2, 3, 4, 5, 6]} 8 | ${{ test: 'test' }} 9 | ${null} 10 | `( 11 | 'expects to throw a type error given a value that is $input', 12 | ({ input }) => { 13 | expect(() => { 14 | reverseWords(input) 15 | }).toThrow('The given value is not a string') 16 | } 17 | ) 18 | 19 | it('expects to reverse words to return a joined word', () => { 20 | expect(reverseWords('I Love JS')).toBe('JS Love I') 21 | expect(reverseWords('Hello World')).toBe('World Hello') 22 | expect(reverseWords('The Algorithms Javascript')).toBe('Javascript Algorithms The') 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /String/test/ScrambleStrings.test.js: -------------------------------------------------------------------------------- 1 | import { isScramble } from '../ScrambleStrings' 2 | 3 | describe('ScrambleStrings', () => { 4 | it('expects to return true for same string', () => { 5 | expect(isScramble('a', 'a')).toBe(true) 6 | }) 7 | 8 | it('expects to return false for non-scrambled strings', () => { 9 | expect(isScramble('abcde', 'caebd')).toBe(false) 10 | }) 11 | 12 | it('expects to return true for scrambled strings', () => { 13 | expect(isScramble('great', 'rgeat')).toBe(true) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /String/test/Upper.test.js: -------------------------------------------------------------------------------- 1 | import upper from '../Upper' 2 | 3 | describe('Testing the Upper function', () => { 4 | it('return uppercase strings', () => { 5 | expect(upper('hello')).toBe('HELLO') 6 | expect(upper('WORLD')).toBe('WORLD') 7 | expect(upper('hello_WORLD')).toBe('HELLO_WORLD') 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /String/test/ValidateEmail.test.js: -------------------------------------------------------------------------------- 1 | import { validateEmail } from '../ValidateEmail' 2 | 3 | describe('Validation of an Email Address', () => { 4 | it('expects to return false', () => { 5 | expect(validateEmail('mahfoudh.arous.com')).toEqual(false) 6 | }) 7 | 8 | it('expects to return false', () => { 9 | expect(validateEmail('mahfoudh.arous@com')).toEqual(false) 10 | }) 11 | 12 | it('expects to return true', () => { 13 | expect(validateEmail('mahfoudh.arous@gmail.com')).toEqual(true) 14 | }) 15 | 16 | it('expects to return true', () => { 17 | expect(validateEmail('icristianbaciu@.helsinki.edu')).toEqual(true) 18 | }) 19 | 20 | it('expects to throw a type error', () => { 21 | expect(() => { validateEmail('') }).toThrow('Email Address String Null or Empty.') 22 | expect(() => { validateEmail(null) }).toThrow('Email Address String Null or Empty.') 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /String/test/ValidateUrl.test.js: -------------------------------------------------------------------------------- 1 | import { validateURL } from '../ValidateUrl' 2 | 3 | describe('ValidateUrl', () => { 4 | it('expects to return false', () => { 5 | expect(validateURL('google')).toEqual(false) 6 | expect(validateURL('link: https://www.google.com')).toEqual(false) 7 | }) 8 | 9 | it('expects to return true', () => { 10 | expect(validateURL('http://www.google.com')).toEqual(true) 11 | expect(validateURL('https://www.google.com')).toEqual(true) 12 | expect(validateURL('www.google.com')).toEqual(true) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Timing-Functions/GetMonthDays.js: -------------------------------------------------------------------------------- 1 | /** 2 | function that takes month number and its year and returns the number of days within it 3 | * @param monthNumber. 4 | * @param year. 5 | e.g.: mahfoudh.arous@gmail.com -> true 6 | e.g.: mahfoudh.arous.com ->false 7 | */ 8 | 9 | const getMonthDays = (monthNumber, year) => { 10 | const the31DaysMonths = [1, 3, 5, 7, 8, 10, 12] 11 | const the30DaysMonths = [4, 6, 9, 11] 12 | 13 | if (!the31DaysMonths.includes(monthNumber) && !the30DaysMonths.includes(monthNumber) && 14 | (monthNumber !== 2) 15 | ) { 16 | throw new TypeError('Invalid Month Number.') 17 | } 18 | 19 | if (the31DaysMonths.includes(monthNumber)) { return 31 } 20 | 21 | if (the30DaysMonths.includes(monthNumber)) { return 30 } 22 | 23 | // Check for Leap year 24 | if (year % 4 === 0) { 25 | if ((year % 100 !== 0) || (year % 100 === 0 && year % 400 === 0)) { 26 | return 29 27 | } 28 | } 29 | 30 | return 28 31 | } 32 | 33 | export { getMonthDays } 34 | -------------------------------------------------------------------------------- /Timing-Functions/test/GetMonthDays.test.js: -------------------------------------------------------------------------------- 1 | import { getMonthDays } from '../GetMonthDays' 2 | 3 | describe('Get the Days of a Month', () => { 4 | it('expects to return 28', () => { 5 | expect(getMonthDays(2, 2018)).toEqual(28) 6 | }) 7 | 8 | it('expects to return 30', () => { 9 | expect(getMonthDays(6, 254)).toEqual(30) 10 | }) 11 | 12 | it('expects to return 29', () => { 13 | expect(getMonthDays(2, 2024)).toEqual(29) 14 | }) 15 | 16 | it('expects to throw a type error', () => { 17 | expect(() => { getMonthDays(13, 2020) }).toThrow('Invalid Month Number.') 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /Trees/FenwickTree.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Mohit Kumar 3 | * Fedwick Tree Implementation in JavaScript 4 | * Fedwick Tree Implementation for finding prefix sum. 5 | */ 6 | 7 | class FenwickTree { 8 | constructor (feneickArray, array, n) { 9 | for (let i = 1; i <= n; i++) { 10 | feneickArray[i] = 0 11 | } 12 | for (let i = 0; i < n; i++) { 13 | this.update(feneickArray, n, i, array[i]) 14 | } 15 | } 16 | 17 | update (feneickArray, n, index, value) { 18 | index = index + 1 19 | while (index <= n) { 20 | feneickArray[index] += value 21 | index += index & (-index) 22 | } 23 | } 24 | 25 | getPrefixSum (feneickArray, index) { 26 | let currSum = 0 27 | index = index + 1 28 | while (index > 0) { 29 | currSum += feneickArray[index] 30 | index -= index & (-index) 31 | } 32 | 33 | return currSum 34 | } 35 | } 36 | export { FenwickTree } 37 | -------------------------------------------------------------------------------- /Trees/test/BreadthFirstTreeTraversal.test.js: -------------------------------------------------------------------------------- 1 | import { BinaryTree, Node } from '../BreadthFirstTreeTraversal' 2 | 3 | describe('Breadth First Tree Traversal', () => { 4 | const binaryTree = new BinaryTree() 5 | 6 | const root = new Node(7) 7 | root.left = new Node(5) 8 | root.right = new Node(8) 9 | root.left.left = new Node(3) 10 | root.left.right = new Node(6) 11 | root.right.right = new Node(9) 12 | binaryTree.root = root 13 | 14 | // Visualization : 15 | // 16 | // 7 17 | // / \ 18 | // 5 8 19 | // / \ \ 20 | // 3 6 9 21 | 22 | it('Binary tree - Level order traversal', () => { 23 | expect(binaryTree.traversal).toStrictEqual([]) 24 | const traversal = binaryTree.breadthFirst() 25 | expect(traversal).toStrictEqual([7, 5, 8, 3, 6, 9]) 26 | }) 27 | }) 28 | -------------------------------------------------------------------------------- /Trees/test/FenwickTree.test.js: -------------------------------------------------------------------------------- 1 | import { FenwickTree } from '../FenwickTree' 2 | 3 | describe('Fenwick Tree Implementation', () => { 4 | const fenwickArray = new Array(1000) 5 | const array = [3, 2, 0, 6, 5, -1, 2] 6 | const length = array.length 7 | 8 | const fenwickTree = new FenwickTree(fenwickArray, array, length) 9 | 10 | it('Fenwick Tree - Prefix sum of array', () => { 11 | const prefixSum = fenwickTree.getPrefixSum(fenwickArray, 6) 12 | expect(prefixSum).toBe(23) 13 | }) 14 | 15 | array[2] += 6 16 | fenwickTree.update(fenwickArray, length, 2, 6) 17 | 18 | it('Fenwick Tree - Prefix sum of Updated array', () => { 19 | const prefixSum = fenwickTree.getPrefixSum(fenwickArray, 6) 20 | expect(prefixSum).toBe(23) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /babel.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | targets: { 7 | esmodules: true 8 | } 9 | } 10 | ] 11 | ] 12 | } 13 | --------------------------------------------------------------------------------