mirror of
https://github.com/TheAlgorithms/JavaScript.git
synced 2025-07-04 07:29:47 +08:00
Merge branch 'master' into add-trapping-water
This commit is contained in:
15
.prettierrc
Normal file
15
.prettierrc
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"arrowParens": "always",
|
||||
"bracketSpacing": true,
|
||||
"endOfLine": "lf",
|
||||
"insertPragma": false,
|
||||
"printWidth": 80,
|
||||
"proseWrap": "preserve",
|
||||
"quoteProps": "as-needed",
|
||||
"requirePragma": false,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "none",
|
||||
"useTabs": false
|
||||
}
|
21
Ciphers/ROT13.js
Normal file
21
Ciphers/ROT13.js
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Transcipher a ROT13 cipher
|
||||
* @param {String} text - string to be encrypted
|
||||
* @return {String} - decrypted string
|
||||
*/
|
||||
const transcipher = (text) => {
|
||||
const originalCharacterList = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
||||
const toBeMappedCharaterList = 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'
|
||||
const index = x => originalCharacterList.indexOf(x)
|
||||
const replace = x => index(x) > -1 ? toBeMappedCharaterList[index(x)] : x
|
||||
return text.split('').map(replace).join('')
|
||||
}
|
||||
|
||||
(() => {
|
||||
const messageToBeEncrypted = 'The quick brown fox jumps over the lazy dog'
|
||||
console.log(`Original Text = "${messageToBeEncrypted}"`)
|
||||
const rot13CipheredText = transcipher(messageToBeEncrypted)
|
||||
console.log(`Ciphered Text = "${rot13CipheredText}"`)
|
||||
const rot13DecipheredText = transcipher(rot13CipheredText)
|
||||
console.log(`Deciphered Text = "${rot13DecipheredText}"`)
|
||||
})()
|
@ -1,11 +1,14 @@
|
||||
function binaryToDeicmal (binaryNumber) {
|
||||
const binaryToDecimal = (binaryString) => {
|
||||
let decimalNumber = 0
|
||||
const binaryDigits = binaryNumber.split('').reverse() // Splits the binary number into reversed single digits
|
||||
const binaryDigits = binaryString.split('').reverse() // Splits the binary number into reversed single digits
|
||||
binaryDigits.forEach((binaryDigit, index) => {
|
||||
decimalNumber += binaryDigit * (Math.pow(2, index)) // Summation of all the decimal converted digits
|
||||
})
|
||||
console.log(`Decimal of ${binaryNumber} is ${decimalNumber}`)
|
||||
console.log(`Decimal of ${binaryString} is ${decimalNumber}`)
|
||||
return decimalNumber
|
||||
}
|
||||
|
||||
binaryToDeicmal('111001')
|
||||
binaryToDeicmal('101')
|
||||
(() => {
|
||||
binaryToDecimal('111001')
|
||||
binaryToDecimal('101')
|
||||
})()
|
||||
|
@ -1,7 +1,7 @@
|
||||
function hexStringToRGB (hexString) {
|
||||
var r = (hexString.substring(1, 3)).toUpperCase()
|
||||
var g = hexString.substring(3, 5).toUpperCase()
|
||||
var b = hexString.substring(5, 7).toUpperCase()
|
||||
var r = hexString.substring(0, 2)
|
||||
var g = hexString.substring(2, 4)
|
||||
var b = hexString.substring(4, 6)
|
||||
|
||||
r = parseInt(r, 16)
|
||||
g = parseInt(g, 16)
|
||||
@ -11,4 +11,4 @@ function hexStringToRGB (hexString) {
|
||||
return obj
|
||||
}
|
||||
|
||||
console.log(hexStringToRGB('javascript rock !!'))
|
||||
console.log(hexStringToRGB('ffffff'))
|
||||
|
16
Conversions/RGBToHex.js
Normal file
16
Conversions/RGBToHex.js
Normal file
@ -0,0 +1,16 @@
|
||||
function RGBToHex (r, g, b) {
|
||||
if (
|
||||
typeof r !== 'number' ||
|
||||
typeof g !== 'number' ||
|
||||
typeof b !== 'number'
|
||||
) {
|
||||
throw new TypeError('argument is not a Number')
|
||||
}
|
||||
|
||||
const toHex = n => (n || '0').toString(16).padStart(2, '0')
|
||||
|
||||
return `#${toHex(r)}${toHex(g)}${toHex(b)}`
|
||||
}
|
||||
|
||||
console.log(RGBToHex(255, 255, 255) === '#ffffff')
|
||||
console.log(RGBToHex(255, 99, 71) === '#ff6347')
|
118
DIRECTORY.md
118
DIRECTORY.md
@ -1,8 +1,10 @@
|
||||
|
||||
## back-tracking
|
||||
* [KnightTour](https://github.com/TheAlgorithms/Javascript/blob/master/back-tracking/KnightTour.js)
|
||||
* [NQueen](https://github.com/TheAlgorithms/Javascript/blob/master/back-tracking/NQueen.js)
|
||||
* [Sudoku](https://github.com/TheAlgorithms/Javascript/blob/master/back-tracking/Sudoku.js)
|
||||
## [babel](https://github.com/TheAlgorithms/Javascript/blob/master//babel.config.js)
|
||||
|
||||
## Backtracking
|
||||
* [KnightTour](https://github.com/TheAlgorithms/Javascript/blob/master/Backtracking/KnightTour.js)
|
||||
* [NQueen](https://github.com/TheAlgorithms/Javascript/blob/master/Backtracking/NQueen.js)
|
||||
* [Sudoku](https://github.com/TheAlgorithms/Javascript/blob/master/Backtracking/Sudoku.js)
|
||||
|
||||
## Cache
|
||||
* [LFUCache](https://github.com/TheAlgorithms/Javascript/blob/master/Cache/LFUCache.js)
|
||||
@ -11,6 +13,7 @@
|
||||
## Ciphers
|
||||
* [CaesarsCipher](https://github.com/TheAlgorithms/Javascript/blob/master/Ciphers/CaesarsCipher.js)
|
||||
* [KeyFinder](https://github.com/TheAlgorithms/Javascript/blob/master/Ciphers/KeyFinder.js)
|
||||
* [ROT13](https://github.com/TheAlgorithms/Javascript/blob/master/Ciphers/ROT13.js)
|
||||
* [VigenereCipher](https://github.com/TheAlgorithms/Javascript/blob/master/Ciphers/VigenereCipher.js)
|
||||
* [XORCipher](https://github.com/TheAlgorithms/Javascript/blob/master/Ciphers/XORCipher.js)
|
||||
|
||||
@ -20,6 +23,7 @@
|
||||
* [DecimalToHex](https://github.com/TheAlgorithms/Javascript/blob/master/Conversions/DecimalToHex.js)
|
||||
* [DecimalToOctal](https://github.com/TheAlgorithms/Javascript/blob/master/Conversions/DecimalToOctal.js)
|
||||
* [HexToRGB](https://github.com/TheAlgorithms/Javascript/blob/master/Conversions/HexToRGB.js)
|
||||
* [RGBToHex](https://github.com/TheAlgorithms/Javascript/blob/master/Conversions/RGBToHex.js)
|
||||
* [RomanToDecimal](https://github.com/TheAlgorithms/Javascript/blob/master/Conversions/RomanToDecimal.js)
|
||||
|
||||
## Data-Structures
|
||||
@ -32,7 +36,10 @@
|
||||
* [MaxHeap](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Heap/MaxHeap.js)
|
||||
* [MinPriorityQueue](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Heap/MinPriorityQueue.js)
|
||||
* Linked-List
|
||||
* [CycleDetection](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Linked-List/CycleDetection.js)
|
||||
* [DoublyLinkedList](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Linked-List/DoublyLinkedList.js)
|
||||
* [RotateListRight](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Linked-List/RotateListRight.js)
|
||||
* [SingleCircularLinkedList](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Linked-List/SingleCircularLinkedList.js.js)
|
||||
* [SinglyLinkList](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Linked-List/SinglyLinkList.js)
|
||||
* Queue
|
||||
* [Queue](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Queue/Queue.js)
|
||||
@ -45,12 +52,21 @@
|
||||
* [Trie](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Tree/Trie.js)
|
||||
|
||||
## Dynamic-Programming
|
||||
* [ClimbingStairs](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/ClimbingStairs.js)
|
||||
* [CoinChange](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/CoinChange.js)
|
||||
* [EditDistance](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/EditDistance.js)
|
||||
* [FibonacciNumber](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/FibonacciNumber.js)
|
||||
* [KadaneAlgo](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/KadaneAlgo.js)
|
||||
* [LevenshteinDistance](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/LevenshteinDistance.js)
|
||||
* [LongestCommonSubsequence](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/LongestCommonSubsequence.js)
|
||||
* [LongestIncreasingSubsequence](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/LongestIncreasingSubsequence.js)
|
||||
* [LongestPalindromicSubsequence](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/LongestPalindromicSubsequence.js)
|
||||
* [MaxNonAdjacentSum](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/MaxNonAdjacentSum.js)
|
||||
* [MinimumCostPath](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/MinimumCostPath.js)
|
||||
* [NumberOfSubsetEqualToGivenSum](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/NumberOfSubsetEqualToGivenSum.js)
|
||||
* [SieveOfEratosthenes](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/SieveOfEratosthenes.js)
|
||||
* [SudokuSolver](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/SudokuSolver.js)
|
||||
* [ZeroOneKnapsack](https://github.com/TheAlgorithms/Javascript/blob/master/Dynamic-Programming/ZeroOneKnapsack.js)
|
||||
|
||||
## Graphs
|
||||
* [ConnectedComponents](https://github.com/TheAlgorithms/Javascript/blob/master/Graphs/ConnectedComponents.js)
|
||||
@ -59,6 +75,7 @@
|
||||
* [Dijkstra](https://github.com/TheAlgorithms/Javascript/blob/master/Graphs/Dijkstra.js)
|
||||
* [DijkstraSmallestPath](https://github.com/TheAlgorithms/Javascript/blob/master/Graphs/DijkstraSmallestPath.js)
|
||||
* [KruskalMST](https://github.com/TheAlgorithms/Javascript/blob/master/Graphs/KruskalMST.js)
|
||||
* [NumberOfIslands](https://github.com/TheAlgorithms/Javascript/blob/master/Graphs/NumberOfIslands.js)
|
||||
* [PrimMST](https://github.com/TheAlgorithms/Javascript/blob/master/Graphs/PrimMST.js)
|
||||
|
||||
## Hashes
|
||||
@ -73,32 +90,89 @@
|
||||
|
||||
## Maths
|
||||
* [Abs](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/Abs.js)
|
||||
* [Area](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/Area.js)
|
||||
* [ArmstrongNumber](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/ArmstrongNumber.js)
|
||||
* [AverageMean](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/AverageMean.js)
|
||||
* [digitSum](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/digitSum.js)
|
||||
* [DigitSum](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/DigitSum.js)
|
||||
* [Factorial](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/Factorial.js)
|
||||
* [Factors](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/Factors.js)
|
||||
* [Fibonacci](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/Fibonacci.js)
|
||||
* [FindHcf](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/FindHcf.js)
|
||||
* [FindLcm](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/FindLcm.js)
|
||||
* [GridGet](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/GridGet.js)
|
||||
* [isDivisible](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/isDivisible.js)
|
||||
* [isOdd](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/isOdd.js)
|
||||
* [MatrixMultiplication](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/MatrixMultiplication.js)
|
||||
* [MeanSquareError](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/MeanSquareError.js)
|
||||
* [ModularBinaryExponentiationRecursive](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/ModularBinaryExponentiationRecursive.js)
|
||||
* [NumberOfDigits](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/NumberOfDigits.js)
|
||||
* [Palindrome](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/Palindrome.js)
|
||||
* [PascalTriangle](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/PascalTriangle.js)
|
||||
* [PerfectCube](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/PerfectCube.js)
|
||||
* [PerfectNumber](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/PerfectNumber.js)
|
||||
* [PerfectSquare](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/PerfectSquare.js)
|
||||
* [PiApproximationMonteCarlo](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/PiApproximationMonteCarlo.js)
|
||||
* [Polynomial](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/Polynomial.js)
|
||||
* [PrimeCheck](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/PrimeCheck.js)
|
||||
* [ReversePolishNotation](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/ReversePolishNotation.js)
|
||||
* [SieveOfEratosthenes](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/SieveOfEratosthenes.js)
|
||||
* test
|
||||
* [Abs](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/Abs.test.js)
|
||||
* [Area](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/Area.test.js)
|
||||
* [ArmstrongNumber](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/ArmstrongNumber.test.js)
|
||||
* [AverageMean](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/AverageMean.test.js)
|
||||
* [DigitSum](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/DigitSum.test.js)
|
||||
* [Factorial](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/Factorial.test.js)
|
||||
* [Factors](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/Factors.test.js)
|
||||
* [Fibonacci](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/Fibonacci.test.js)
|
||||
* [FindHcf](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/FindHcf.test.js)
|
||||
* [FindLcm](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/FindLcm.test.js)
|
||||
* [GridGet](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/GridGet.test.js)
|
||||
* [MeanSquareError](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/MeanSquareError.test.js)
|
||||
* [ModularBinaryExponentiationRecursive](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/ModularBinaryExponentiationRecursive.test.js)
|
||||
* [NumberOfDigits](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/NumberOfDigits.test.js)
|
||||
* [Palindrome](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/Palindrome.test.js)
|
||||
* [PascalTriangle](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/PascalTriangle.test.js)
|
||||
* [PerfectCube](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/PerfectCube.test.js)
|
||||
* [PerfectNumber](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/PerfectNumber.test.js)
|
||||
* [PerfectSquare](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/PerfectSquare.test.js)
|
||||
* [PiApproximationMonteCarlo](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/PiApproximationMonteCarlo.test.js)
|
||||
* [Polynomial](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/Polynomial.test.js)
|
||||
* [PrimeCheck](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/PrimeCheck.test.js)
|
||||
* [ReversePolishNotation](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/ReversePolishNotation.test.js)
|
||||
* [SieveOfEratosthenes](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/test/SieveOfEratosthenes.test.js)
|
||||
|
||||
## Navigation
|
||||
* [Haversine](https://github.com/TheAlgorithms/Javascript/blob/master/Navigation/Haversine.js)
|
||||
* [Haversine](https://github.com/TheAlgorithms/Javascript/blob/master/Navigation/Haversine.test.js)
|
||||
|
||||
## Project-Euler
|
||||
* [Problem1](https://github.com/TheAlgorithms/Javascript/blob/master/Project-Euler/Problem1.js)
|
||||
* [Problem2](https://github.com/TheAlgorithms/Javascript/blob/master/Project-Euler/Problem2.js)
|
||||
* [Problem3](https://github.com/TheAlgorithms/Javascript/blob/master/Project-Euler/Problem3.js)
|
||||
* [Problem4](https://github.com/TheAlgorithms/Javascript/blob/master/Project-Euler/Problem4.js)
|
||||
* [Problem6](https://github.com/TheAlgorithms/Javascript/blob/master/Project-Euler/Problem6.js)
|
||||
* [Problem7](https://github.com/TheAlgorithms/Javascript/blob/master/Project-Euler/Problem7.js)
|
||||
|
||||
## Recursive
|
||||
* [BinarySearch](https://github.com/TheAlgorithms/Javascript/blob/master/Recursive/BinarySearch.js)
|
||||
* [EucledianGCD](https://github.com/TheAlgorithms/Javascript/blob/master/Recursive/EucledianGCD.js)
|
||||
* [factorial](https://github.com/TheAlgorithms/Javascript/blob/master/Recursive/factorial.js)
|
||||
* [FibonacciNumberRecursive](https://github.com/TheAlgorithms/Javascript/blob/master/Recursive/FibonacciNumberRecursive.js)
|
||||
* [Palindrome](https://github.com/TheAlgorithms/Javascript/blob/master/Recursive/Palindrome.js)
|
||||
* [TowerOfHanoi](https://github.com/TheAlgorithms/Javascript/blob/master/Recursive/TowerOfHanoi.js)
|
||||
|
||||
## Search
|
||||
* [BinarySearch](https://github.com/TheAlgorithms/Javascript/blob/master/Search/BinarySearch.js)
|
||||
* [ExponentialSearch](https://github.com/TheAlgorithms/Javascript/blob/master/Search/ExponentialSearch.js)
|
||||
* [FibonacciSearch](https://github.com/TheAlgorithms/Javascript/blob/master/Search/FibonacciSearch.js)
|
||||
* [InterpolationSearch](https://github.com/TheAlgorithms/Javascript/blob/master/Search/InterpolationSearch.js)
|
||||
* [JumpSearch](https://github.com/TheAlgorithms/Javascript/blob/master/Search/JumpSearch.js)
|
||||
* [LinearSearch](https://github.com/TheAlgorithms/Javascript/blob/master/Search/LinearSearch.js)
|
||||
* [StringSearch](https://github.com/TheAlgorithms/Javascript/blob/master/Search/StringSearch.js)
|
||||
|
||||
## Sorts
|
||||
* [BeadSort](https://github.com/TheAlgorithms/Javascript/blob/master/Sorts/BeadSort.js)
|
||||
* [BogoSort](https://github.com/TheAlgorithms/Javascript/blob/master/Sorts/BogoSort.js)
|
||||
* [BubbleSort](https://github.com/TheAlgorithms/Javascript/blob/master/Sorts/BubbleSort.js)
|
||||
* [BucketSort](https://github.com/TheAlgorithms/Javascript/blob/master/Sorts/BucketSort.js)
|
||||
@ -116,21 +190,51 @@
|
||||
* [QuickSort](https://github.com/TheAlgorithms/Javascript/blob/master/Sorts/QuickSort.js)
|
||||
* [RadixSort](https://github.com/TheAlgorithms/Javascript/blob/master/Sorts/RadixSort.js)
|
||||
* [SelectionSort](https://github.com/TheAlgorithms/Javascript/blob/master/Sorts/SelectionSort.js)
|
||||
* [SelectionSort](https://github.com/TheAlgorithms/Javascript/blob/master/Sorts/SelectionSort.test.js)
|
||||
* [ShellSort](https://github.com/TheAlgorithms/Javascript/blob/master/Sorts/ShellSort.js)
|
||||
* [TimSort](https://github.com/TheAlgorithms/Javascript/blob/master/Sorts/TimSort.js)
|
||||
* [TopologicalSort](https://github.com/TheAlgorithms/Javascript/blob/master/Sorts/TopologicalSort.js)
|
||||
* [WiggleSort](https://github.com/TheAlgorithms/Javascript/blob/master/Sorts/WiggleSort.js)
|
||||
|
||||
## String
|
||||
* [CheckAnagram](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckAnagram.js)
|
||||
* [CheckPalindrome](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckPalindrome.js)
|
||||
* [CheckPangram](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckPangram.js)
|
||||
* [CheckRearrangePalindrome](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckRearrangePalindrome.js)
|
||||
* [CheckVowels](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckVowels.js)
|
||||
* [CheckVowels](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckVowels.test.js)
|
||||
* [CheckWordOccurrence](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckWordOccurrence.js)
|
||||
* [CheckWordOcurrence](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckWordOcurrence.test.js)
|
||||
* [createPurmutations](https://github.com/TheAlgorithms/Javascript/blob/master/String/createPurmutations.js)
|
||||
* [FormatPhoneNumber](https://github.com/TheAlgorithms/Javascript/blob/master/String/FormatPhoneNumber.js)
|
||||
* [FormatPhoneNumber](https://github.com/TheAlgorithms/Javascript/blob/master/String/FormatPhoneNumber.test.js)
|
||||
* [GenerateGUID](https://github.com/TheAlgorithms/Javascript/blob/master/String/GenerateGUID.js)
|
||||
* [LevenshteinDistance](https://github.com/TheAlgorithms/Javascript/blob/master/String/LevenshteinDistance.js)
|
||||
* [LevenshteinDistance](https://github.com/TheAlgorithms/Javascript/blob/master/String/LevenshteinDistance.test.js)
|
||||
* [MaxCharacter](https://github.com/TheAlgorithms/Javascript/blob/master/String/MaxCharacter.js)
|
||||
* [MaxCharacter](https://github.com/TheAlgorithms/Javascript/blob/master/String/MaxCharacter.test.js)
|
||||
* [PatternMatching](https://github.com/TheAlgorithms/Javascript/blob/master/String/PatternMatching.js)
|
||||
* [PermutateString](https://github.com/TheAlgorithms/Javascript/blob/master/String/PermutateString.js)
|
||||
* [PermutateString](https://github.com/TheAlgorithms/Javascript/blob/master/String/PermutateString.test.js)
|
||||
* [ReverseString](https://github.com/TheAlgorithms/Javascript/blob/master/String/ReverseString.js)
|
||||
* [ReverseWords](https://github.com/TheAlgorithms/Javascript/blob/master/String/ReverseWords.js)
|
||||
* test
|
||||
* [CheckAnagram](https://github.com/TheAlgorithms/Javascript/blob/master/String/test/CheckAnagram.test.js)
|
||||
* [CheckPalindrome](https://github.com/TheAlgorithms/Javascript/blob/master/String/test/CheckPalindrome.test.js)
|
||||
* [CheckPangram](https://github.com/TheAlgorithms/Javascript/blob/master/String/test/CheckPangram.test.js)
|
||||
* [PatternMatching](https://github.com/TheAlgorithms/Javascript/blob/master/String/test/PatternMatching.test.js)
|
||||
* [ReverseString](https://github.com/TheAlgorithms/Javascript/blob/master/String/test/ReverseString.test.js)
|
||||
* [ReverseWords](https://github.com/TheAlgorithms/Javascript/blob/master/String/test/ReverseWords.test.js)
|
||||
* [ValidateEmail](https://github.com/TheAlgorithms/Javascript/blob/master/String/ValidateEmail.js)
|
||||
* [ValidateEmail](https://github.com/TheAlgorithms/Javascript/blob/master/String/ValidateEmail.test.js)
|
||||
|
||||
## TimingFunctions
|
||||
* [IntervalTimer](https://github.com/TheAlgorithms/Javascript/blob/master/TimingFunctions/IntervalTimer.js)
|
||||
## Timing-Functions
|
||||
* [GetMonthDays](https://github.com/TheAlgorithms/Javascript/blob/master/Timing-Functions/GetMonthDays.js)
|
||||
* [GetMonthDays](https://github.com/TheAlgorithms/Javascript/blob/master/Timing-Functions/GetMonthDays.test.js)
|
||||
* [IntervalTimer](https://github.com/TheAlgorithms/Javascript/blob/master/Timing-Functions/IntervalTimer.js)
|
||||
|
||||
## Trees
|
||||
* [BreadthFirstTreeTraversal](https://github.com/TheAlgorithms/Javascript/blob/master/Trees/BreadthFirstTreeTraversal.js)
|
||||
* [DepthFirstSearch](https://github.com/TheAlgorithms/Javascript/blob/master/Trees/DepthFirstSearch.js)
|
||||
|
||||
## Web-Programming
|
||||
|
32
Data-Structures/Linked-List/CycleDetection.js
Normal file
32
Data-Structures/Linked-List/CycleDetection.js
Normal file
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* A LinkedList based solution for Detect a Cycle in a list
|
||||
* https://en.wikipedia.org/wiki/Cycle_detection
|
||||
*/
|
||||
|
||||
function main () {
|
||||
/*
|
||||
Problem Statement:
|
||||
Given head, the head of a linked list, determine if the linked list has a cycle in it.
|
||||
|
||||
Note:
|
||||
* While Solving the problem in given link below, don't use main() function.
|
||||
* Just use only the code inside main() function.
|
||||
* The purpose of using main() function here is to aviod global variables.
|
||||
|
||||
Link for the Problem: https://leetcode.com/problems/linked-list-cycle/
|
||||
*/
|
||||
const head = '' // Reference to head is given in the problem. So please ignore this line
|
||||
let fast = head
|
||||
let slow = head
|
||||
|
||||
while (fast != null && fast.next != null && slow != null) {
|
||||
fast = fast.next.next
|
||||
slow = slow.next
|
||||
if (fast === slow) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
main()
|
45
Data-Structures/Linked-List/RotateListRight.js
Normal file
45
Data-Structures/Linked-List/RotateListRight.js
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* A LinkedList based solution for Rotating a List to the right by k places
|
||||
*/
|
||||
|
||||
function main () {
|
||||
/*
|
||||
Problem Statement:
|
||||
Given a linked list, rotate the list to the right by k places, where k is non-negative.
|
||||
|
||||
Note:
|
||||
* While Solving the problem in given link below, don't use main() function.
|
||||
* Just use only the code inside main() function.
|
||||
* The purpose of using main() function here is to aviod global variables.
|
||||
|
||||
Link for the Problem: https://leetcode.com/problems/rotate-list/
|
||||
*/
|
||||
// Reference to both head and k is given in the problem. So please ignore below two lines
|
||||
let head = ''
|
||||
let k = ''
|
||||
let i = 0
|
||||
let current = head
|
||||
while (current) {
|
||||
i++
|
||||
current = current.next
|
||||
}
|
||||
k %= i
|
||||
current = head
|
||||
let prev = null
|
||||
while (k--) {
|
||||
if (!current || !current.next) {
|
||||
return current
|
||||
} else {
|
||||
while (current.next) {
|
||||
prev = current
|
||||
current = current.next
|
||||
}
|
||||
prev.next = current.next
|
||||
current.next = head
|
||||
head = current
|
||||
}
|
||||
}
|
||||
return head
|
||||
}
|
||||
|
||||
main()
|
97
Data-Structures/Linked-List/SingleCircularLinkedList.js.js
Normal file
97
Data-Structures/Linked-List/SingleCircularLinkedList.js.js
Normal file
@ -0,0 +1,97 @@
|
||||
class Node {
|
||||
constructor (data, next = null) {
|
||||
this.data = data
|
||||
this.next = next
|
||||
}
|
||||
}
|
||||
|
||||
class SinglyCircularLinkedList {
|
||||
constructor () {
|
||||
this.head = null
|
||||
this.size = 0
|
||||
}
|
||||
|
||||
insert (data) {
|
||||
const node = new Node(data)
|
||||
|
||||
if (!this.head) {
|
||||
node.next = node
|
||||
this.head = node
|
||||
this.size++
|
||||
} else {
|
||||
node.next = this.head
|
||||
|
||||
let current = this.head
|
||||
|
||||
while (current.next.data !== this.head.data) {
|
||||
current = current.next
|
||||
}
|
||||
|
||||
current.next = node
|
||||
this.size++
|
||||
}
|
||||
}
|
||||
|
||||
insertAt (index, data) {
|
||||
const node = new Node(data)
|
||||
|
||||
if (index < 0 || index > this.size) return
|
||||
|
||||
if (index === 0) {
|
||||
this.head = node
|
||||
this.size = 1
|
||||
return
|
||||
}
|
||||
|
||||
let previous
|
||||
let count = 0
|
||||
let current = this.head
|
||||
|
||||
while (count < index) {
|
||||
previous = current
|
||||
current = current.next
|
||||
count++
|
||||
}
|
||||
|
||||
node.next = current
|
||||
previous.next = node
|
||||
this.size++
|
||||
}
|
||||
|
||||
remove () {
|
||||
if (!this.head) return
|
||||
|
||||
let prev
|
||||
let current = this.head
|
||||
|
||||
while (current.next !== this.head) {
|
||||
prev = current
|
||||
current = current.next
|
||||
}
|
||||
|
||||
prev.next = this.head
|
||||
this.size--
|
||||
}
|
||||
|
||||
printData () {
|
||||
let count = 0
|
||||
let current = this.head
|
||||
|
||||
while (current !== null && count !== this.size) {
|
||||
console.log(current.data + '\n')
|
||||
current = current.next
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ll = new SinglyCircularLinkedList()
|
||||
|
||||
ll.insert(10)
|
||||
ll.insert(20)
|
||||
ll.insert(30)
|
||||
ll.insert(40)
|
||||
ll.insert(50)
|
||||
ll.insertAt(5, 60)
|
||||
ll.remove(5)
|
||||
ll.printData()
|
26
Dynamic-Programming/ClimbingStairs.js
Normal file
26
Dynamic-Programming/ClimbingStairs.js
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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?
|
||||
*/
|
||||
|
||||
const climbStairs = (n) => {
|
||||
let prev = 0
|
||||
let cur = 1
|
||||
let temp
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
temp = prev
|
||||
prev = cur
|
||||
cur += temp
|
||||
}
|
||||
return cur
|
||||
}
|
||||
|
||||
const main = () => {
|
||||
const number = 5
|
||||
|
||||
console.log('Number of ways to climb ' + number + ' stairs in ' + climbStairs(5))
|
||||
}
|
||||
|
||||
// testing
|
||||
main()
|
61
Dynamic-Programming/EditDistance.js
Normal file
61
Dynamic-Programming/EditDistance.js
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
Wikipedia -> https://en.wikipedia.org/wiki/Edit_distance
|
||||
|
||||
Q. -> Given two strings `word1` and `word2`. You can perform these operations on any of the string to make both strings similar.
|
||||
- Insert
|
||||
- Remove
|
||||
- Replace
|
||||
Find the minimum operation cost required to make both same. Each operation cost is 1.
|
||||
|
||||
Algorithm details ->
|
||||
time complexity - O(n*m)
|
||||
space complexity - O(n*m)
|
||||
*/
|
||||
|
||||
const minimumEditDistance = (word1, word2) => {
|
||||
const n = word1.length
|
||||
const m = word2.length
|
||||
const dp = new Array(m + 1).fill(0).map(item => [])
|
||||
|
||||
/*
|
||||
fill dp matrix with default values -
|
||||
- first row is filled considering no elements in word2.
|
||||
- first column filled considering no elements in word1.
|
||||
*/
|
||||
|
||||
for (let i = 0; i < n + 1; i++) {
|
||||
dp[0][i] = i
|
||||
}
|
||||
|
||||
for (let i = 0; i < m + 1; i++) {
|
||||
dp[i][0] = i
|
||||
}
|
||||
|
||||
/*
|
||||
indexing is 1 based for dp matrix as we defined some known values at first row and first column/
|
||||
*/
|
||||
|
||||
for (let i = 1; i < m + 1; i++) {
|
||||
for (let j = 1; j < n + 1; j++) {
|
||||
const letter1 = word1[j - 1]
|
||||
const letter2 = word2[i - 1]
|
||||
|
||||
if (letter1 === letter2) {
|
||||
dp[i][j] = dp[i - 1][j - 1]
|
||||
} else {
|
||||
dp[i][j] = Math.min(dp[i - 1][j], dp[i - 1][j - 1], dp[i][j - 1]) + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dp[m][n]
|
||||
}
|
||||
|
||||
const main = () => {
|
||||
console.log(minimumEditDistance('horse', 'ros'))
|
||||
console.log(minimumEditDistance('cat', 'cut'))
|
||||
console.log(minimumEditDistance('', 'abc'))
|
||||
console.log(minimumEditDistance('google', 'glgool'))
|
||||
}
|
||||
|
||||
main()
|
18
Dynamic-Programming/FibonacciNumber.js
Normal file
18
Dynamic-Programming/FibonacciNumber.js
Normal file
@ -0,0 +1,18 @@
|
||||
// https://en.wikipedia.org/wiki/Fibonacci_number
|
||||
|
||||
const fibonacci = (N) => {
|
||||
// creating array to store values
|
||||
const memo = new Array(N + 1)
|
||||
memo[0] = 0
|
||||
memo[1] = 1
|
||||
for (let i = 2; i <= N; i++) {
|
||||
memo[i] = memo[i - 1] + memo[i - 2]
|
||||
}
|
||||
return memo[N]
|
||||
}
|
||||
|
||||
// testing
|
||||
(() => {
|
||||
const number = 5
|
||||
console.log(number + 'th Fibonacci number is ' + fibonacci(number))
|
||||
})()
|
33
Dynamic-Programming/LongestCommonSubsequence.js
Normal file
33
Dynamic-Programming/LongestCommonSubsequence.js
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Given two sequences, find the length of longest subsequence present in both of them.
|
||||
* A subsequence is a sequence that appears in the same relative order, but not necessarily contiguous.
|
||||
* For example, “abc”, “abg”, “bdf”, “aeg”, ‘”acefg”, .. etc are subsequences of “abcdefg”
|
||||
*/
|
||||
|
||||
function longestCommonSubsequence (x, y, str1, str2, dp) {
|
||||
if (x === -1 || y === -1) {
|
||||
return 0
|
||||
} else {
|
||||
if (dp[x][y] !== 0) {
|
||||
return dp[x][y]
|
||||
} else {
|
||||
if (str1[x] === str2[y]) {
|
||||
dp[x][y] = 1 + longestCommonSubsequence(x - 1, y - 1, str1, str2, dp)
|
||||
return dp[x][y]
|
||||
} else {
|
||||
dp[x][y] = Math.max(longestCommonSubsequence(x - 1, y, str1, str2, dp), longestCommonSubsequence(x, y - 1, str1, str2, dp))
|
||||
return dp[x][y]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function main () {
|
||||
const str1 = 'ABCDGH'
|
||||
const str2 = 'AEDFHR'
|
||||
const dp = new Array(str1.length + 1).fill(0).map(x => new Array(str2.length + 1).fill(0))
|
||||
const res = longestCommonSubsequence(str1.length - 1, str2.length - 1, str1, str2, dp)
|
||||
console.log(res)
|
||||
}
|
||||
|
||||
main()
|
27
Dynamic-Programming/LongestIncreasingSubsequence.js
Normal file
27
Dynamic-Programming/LongestIncreasingSubsequence.js
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* A Dynamic Programming based solution for calculating Longest Increasing Subsequence
|
||||
* https://en.wikipedia.org/wiki/Longest_increasing_subsequence
|
||||
*/
|
||||
|
||||
function main () {
|
||||
const x = [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]
|
||||
const length = x.length
|
||||
const dp = Array(length).fill(1)
|
||||
|
||||
let res = 1
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
for (let j = 0; j < i; j++) {
|
||||
if (x[i] > x[j]) {
|
||||
dp[i] = Math.max(dp[i], 1 + dp[j])
|
||||
if (dp[i] > res) {
|
||||
res = dp[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Length of Longest Increasing Subsequence is:', res)
|
||||
}
|
||||
|
||||
main()
|
39
Dynamic-Programming/LongestPalindromicSubsequence.js
Normal file
39
Dynamic-Programming/LongestPalindromicSubsequence.js
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
LeetCode -> https://leetcode.com/problems/longest-palindromic-subsequence/
|
||||
|
||||
Given a string s, find the longest palindromic subsequence's length in s.
|
||||
You may assume that the maximum length of s is 1000.
|
||||
|
||||
*/
|
||||
|
||||
const longestPalindromeSubsequence = function (s) {
|
||||
const n = s.length
|
||||
|
||||
const dp = new Array(n).fill(0).map(item => new Array(n).fill(0).map(item => 0))
|
||||
|
||||
// fill predefined for single character
|
||||
for (let i = 0; i < n; i++) {
|
||||
dp[i][i] = 1
|
||||
}
|
||||
|
||||
for (let i = 1; i < n; i++) {
|
||||
for (let j = 0; j < n - i; j++) {
|
||||
const col = j + i
|
||||
if (s[j] === s[col]) {
|
||||
dp[j][col] = 2 + dp[j + 1][col - 1]
|
||||
} else {
|
||||
dp[j][col] = Math.max(dp[j][col - 1], dp[j + 1][col])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dp[0][n - 1]
|
||||
}
|
||||
|
||||
const main = () => {
|
||||
console.log(longestPalindromeSubsequence('bbbab')) // 4
|
||||
console.log(longestPalindromeSubsequence('axbya')) // 3
|
||||
console.log(longestPalindromeSubsequence('racexyzcxar')) // 7
|
||||
}
|
||||
|
||||
main()
|
37
Dynamic-Programming/MinimumCostPath.js
Normal file
37
Dynamic-Programming/MinimumCostPath.js
Normal file
@ -0,0 +1,37 @@
|
||||
// youtube Link -> https://www.youtube.com/watch?v=lBRtnuxg-gU
|
||||
|
||||
const minCostPath = (matrix) => {
|
||||
/*
|
||||
Find the min cost path from top-left to bottom-right in matrix
|
||||
>>> minCostPath([[2, 1], [3, 1], [4, 2]])
|
||||
6
|
||||
*/
|
||||
const n = matrix.length
|
||||
const m = matrix[0].length
|
||||
|
||||
// Preprocessing first row
|
||||
for (let i = 1; i < m; i++) {
|
||||
matrix[0][i] += matrix[0][i - 1]
|
||||
}
|
||||
|
||||
// Preprocessing first column
|
||||
for (let i = 1; i < n; i++) {
|
||||
matrix[i][0] += matrix[i - 1][0]
|
||||
}
|
||||
|
||||
// Updating cost to current position
|
||||
for (let i = 1; i < n; i++) {
|
||||
for (let j = 1; j < m; j++) {
|
||||
matrix[i][j] += Math.min(matrix[i - 1][j], matrix[i][j - 1])
|
||||
}
|
||||
}
|
||||
|
||||
return matrix[n - 1][m - 1]
|
||||
}
|
||||
|
||||
const main = () => {
|
||||
console.log(minCostPath([[2, 1], [3, 1], [4, 2]]))
|
||||
console.log(minCostPath([[2, 1, 4], [2, 1, 3], [3, 2, 1]]))
|
||||
}
|
||||
|
||||
main()
|
50
Dynamic-Programming/SudokuSolver.js
Normal file
50
Dynamic-Programming/SudokuSolver.js
Normal file
@ -0,0 +1,50 @@
|
||||
const _board = [
|
||||
['.', '9', '.', '.', '4', '2', '1', '3', '6'],
|
||||
['.', '.', '.', '9', '6', '.', '4', '8', '5'],
|
||||
['.', '.', '.', '5', '8', '1', '.', '.', '.'],
|
||||
['.', '.', '4', '.', '.', '.', '.', '.', '.'],
|
||||
['5', '1', '7', '2', '.', '.', '9', '.', '.'],
|
||||
['6', '.', '2', '.', '.', '.', '3', '7', '.'],
|
||||
['1', '.', '.', '8', '.', '4', '.', '2', '.'],
|
||||
['7', '.', '6', '.', '.', '.', '8', '1', '.'],
|
||||
['3', '.', '.', '.', '9', '.', '.', '.', '.']
|
||||
]
|
||||
|
||||
const isValid = (board, row, col, k) => {
|
||||
for (let i = 0; i < 9; i++) {
|
||||
const m = 3 * Math.floor(row / 3) + Math.floor(i / 3)
|
||||
const n = 3 * Math.floor(col / 3) + i % 3
|
||||
if (board[row][i] === k || board[i][col] === k || board[m][n] === k) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const sodokoSolver = (data) => {
|
||||
for (let i = 0; i < 9; i++) {
|
||||
for (let j = 0; j < 9; j++) {
|
||||
if (data[i][j] === '.') {
|
||||
for (let k = 1; k <= 9; k++) {
|
||||
if (isValid(data, i, j, k)) {
|
||||
data[i][j] = `${k}`
|
||||
if (sodokoSolver(data)) {
|
||||
return true
|
||||
} else {
|
||||
data[i][j] = '.'
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// testing
|
||||
(() => {
|
||||
if (sodokoSolver(_board)) {
|
||||
console.log(_board)
|
||||
}
|
||||
})()
|
71
Dynamic-Programming/ZeroOneKnapsack.js
Normal file
71
Dynamic-Programming/ZeroOneKnapsack.js
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* A Dynamic Programming based solution for calculating Zero One Knapsack
|
||||
* https://en.wikipedia.org/wiki/Knapsack_problem
|
||||
*/
|
||||
|
||||
const zeroOneKnapsack = (arr, n, cap, cache) => {
|
||||
if (cap === 0 || n === 0) {
|
||||
cache[n][cap] = 0
|
||||
return cache[n][cap]
|
||||
}
|
||||
if (cache[n][cap] !== -1) {
|
||||
return cache[n][cap]
|
||||
}
|
||||
if (arr[n - 1][0] <= cap) {
|
||||
cache[n][cap] = Math.max(arr[n - 1][1] + zeroOneKnapsack(arr, n - 1, cap - arr[n - 1][0], cache), zeroOneKnapsack(arr, n - 1, cap, cache))
|
||||
return cache[n][cap]
|
||||
} else {
|
||||
cache[n][cap] = zeroOneKnapsack(arr, n - 1, cap, cache)
|
||||
return cache[n][cap]
|
||||
}
|
||||
}
|
||||
|
||||
const main = () => {
|
||||
/*
|
||||
Problem Statement:
|
||||
You are a thief carrying a single bag with limited capacity S. The museum you stole had N artifact that you could steal. Unfortunately you might not be able to steal all the artifact because of your limited bag capacity.
|
||||
You have to cherry pick the artifact in order to maximize the total value of the artifacts you stole.
|
||||
|
||||
Link for the Problem: https://www.hackerrank.com/contests/srin-aadc03/challenges/classic-01-knapsack
|
||||
*/
|
||||
let input = `1
|
||||
4 5
|
||||
1 8
|
||||
2 4
|
||||
3 0
|
||||
2 5
|
||||
2 3`
|
||||
|
||||
input = input.trim().split('\n')
|
||||
input.shift()
|
||||
const length = input.length
|
||||
|
||||
let i = 0
|
||||
while (i < length) {
|
||||
const cap = Number(input[i].trim().split(' ')[0])
|
||||
const currlen = Number(input[i].trim().split(' ')[1])
|
||||
let j = i + 1
|
||||
const arr = []
|
||||
while (j <= i + currlen) {
|
||||
arr.push(input[j])
|
||||
j++
|
||||
}
|
||||
const newArr = []
|
||||
arr.map(e => {
|
||||
newArr.push(e.trim().split(' ').map(Number))
|
||||
})
|
||||
const cache = []
|
||||
for (let i = 0; i <= currlen; i++) {
|
||||
const temp = []
|
||||
for (let j = 0; j <= cap; j++) {
|
||||
temp.push(-1)
|
||||
}
|
||||
cache.push(temp)
|
||||
}
|
||||
const result = zeroOneKnapsack(newArr, currlen, cap, cache)
|
||||
console.log(result)
|
||||
i += currlen + 1
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
86
Graphs/NumberOfIslands.js
Normal file
86
Graphs/NumberOfIslands.js
Normal file
@ -0,0 +1,86 @@
|
||||
/* Number of Islands
|
||||
https://dev.to/rattanakchea/amazons-interview-question-count-island-21h6
|
||||
Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
|
||||
|
||||
two a dimensial grid map
|
||||
each element is going to represent a peice of land
|
||||
1 is land,
|
||||
0 is water
|
||||
output a number which is the number of islands
|
||||
|
||||
Example 1:
|
||||
Input:
|
||||
11110
|
||||
11010
|
||||
11000
|
||||
00000
|
||||
|
||||
Output: 1
|
||||
|
||||
Example 2:
|
||||
Input:
|
||||
11000
|
||||
11000
|
||||
00100
|
||||
00011
|
||||
|
||||
Output: 3
|
||||
|
||||
I: two dimensional array
|
||||
O: a single integer; total number of islands
|
||||
|
||||
Pseudocode:
|
||||
OUTER FUNCTION
|
||||
set count to 0
|
||||
|
||||
INNER FUNCTION - flood (col, row)
|
||||
if the tile is water
|
||||
return
|
||||
make tile water(flood tile)
|
||||
invoke flood on the neighbor coordinates
|
||||
|
||||
iterate over the matrix (col, row)
|
||||
if the current element is a 1
|
||||
increment count
|
||||
invoke flood (coordinates for col and row)
|
||||
|
||||
Return the count
|
||||
*/
|
||||
const grid = [
|
||||
['1', '1', '0', '0', '0'],
|
||||
['1', '1', '0', '0', '0'],
|
||||
['0', '0', '1', '0', '0'],
|
||||
['0', '0', '0', '1', '1']
|
||||
]
|
||||
|
||||
const islands = (matrixGrid) => {
|
||||
const matrix = matrixGrid
|
||||
let counter = 0
|
||||
|
||||
const flood = (row, col) => {
|
||||
if (row < 0 || col < 0) return // Off the map above or left
|
||||
if (row >= matrix.length || col >= matrix[row].length) return // Off the map below or right
|
||||
|
||||
const tile = matrix[row][col]
|
||||
if (tile !== '1') return
|
||||
|
||||
matrix[row][col] = '0'
|
||||
|
||||
flood(row + 1, col) // Down
|
||||
flood(row - 1, col) // Up
|
||||
flood(row, col + 1) // Right
|
||||
flood(row, col - 1) // Left
|
||||
}
|
||||
|
||||
for (let row = 0; row < matrix.length; row += 1) {
|
||||
for (let col = 0; col < matrix[row].length; col += 1) {
|
||||
const current = matrix[row][col]
|
||||
if (current === '1') {
|
||||
flood(row, col)
|
||||
counter += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return counter
|
||||
}
|
||||
console.log(islands(grid))
|
@ -11,7 +11,7 @@
|
||||
https://en.wikipedia.org/wiki/Absolute_value
|
||||
*/
|
||||
|
||||
function absVal (num) {
|
||||
const absVal = (num) => {
|
||||
// Find absolute value of `num`.
|
||||
'use strict'
|
||||
if (num < 0) {
|
||||
@ -21,6 +21,4 @@ function absVal (num) {
|
||||
return num
|
||||
}
|
||||
|
||||
// Run `abs` function to find absolute value of two numbers.
|
||||
console.log('The absolute value of -34 is ' + absVal(-34))
|
||||
console.log('The absolute value of 34 is ' + absVal(34))
|
||||
export { absVal }
|
||||
|
99
Maths/Area.js
Normal file
99
Maths/Area.js
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
Calculate the area of various shapes
|
||||
|
||||
Calculate the Surface Area of a Cube.
|
||||
Example: surfaceAreaCube(1) will return 6
|
||||
More about: https://en.wikipedia.org/wiki/Area#Surface_area
|
||||
*/
|
||||
const surfaceAreaCube = (sideLength) => {
|
||||
validateNumericParam(sideLength, 'sideLength')
|
||||
return (6.0 * sideLength ** 2.0)
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate the Surface Area of a Sphere.
|
||||
Wikipedia reference: https://en.wikipedia.org/wiki/Sphere
|
||||
return 4 * pi * r^2
|
||||
*/
|
||||
const surfaceAreaSphere = (radius) => {
|
||||
validateNumericParam(radius, 'radius')
|
||||
return (4.0 * Math.PI * radius ** 2.0)
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate the area of a rectangle
|
||||
Wikipedia reference: https://en.wikipedia.org/wiki/Area#Quadrilateral_area
|
||||
return width * length
|
||||
*/
|
||||
const areaRectangle = (length, width) => {
|
||||
validateNumericParam(length, 'Length')
|
||||
validateNumericParam(width, 'Width')
|
||||
return (width * length)
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate the area of a square
|
||||
*/
|
||||
const areaSquare = (sideLength) => {
|
||||
validateNumericParam(sideLength, 'side length')
|
||||
return (sideLength ** 2)
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate the area of a triangle
|
||||
Wikipedia reference: https://en.wikipedia.org/wiki/Area#Triangle_area
|
||||
return base * height / 2
|
||||
*/
|
||||
const areaTriangle = (base, height) => {
|
||||
validateNumericParam(base, 'Base')
|
||||
validateNumericParam(height, 'Height')
|
||||
return (base * height) / 2.0
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate the area of a parallelogram
|
||||
Wikipedia reference: https://en.wikipedia.org/wiki/Area#Dissection,_parallelograms,_and_triangles
|
||||
*/
|
||||
const areaParallelogram = (base, height) => {
|
||||
validateNumericParam(base, 'Base')
|
||||
validateNumericParam(height, 'Height')
|
||||
return (base * height)
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate the area of a trapezium
|
||||
*/
|
||||
const areaTrapezium = (base1, base2, height) => {
|
||||
validateNumericParam(base1, 'Base One')
|
||||
validateNumericParam(base2, 'Base Two')
|
||||
validateNumericParam(height, 'Height')
|
||||
return 1.0 / 2.0 * (base1 + base2) * height
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate the area of a circle
|
||||
*/
|
||||
const areaCircle = (radius) => {
|
||||
validateNumericParam(radius, 'Radius')
|
||||
return (Math.PI * radius ** 2)
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate the area of a rhombus
|
||||
Wikipedia reference: https://en.wikipedia.org/wiki/Rhombus
|
||||
*/
|
||||
const areaRhombus = (diagonal1, diagonal2) => {
|
||||
validateNumericParam(diagonal1, 'diagonal one')
|
||||
validateNumericParam(diagonal2, 'diagonal two')
|
||||
return (1 / 2 * diagonal1 * diagonal2)
|
||||
}
|
||||
|
||||
const validateNumericParam = (param, paramName = 'param') => {
|
||||
if (typeof param !== 'number') {
|
||||
throw new TypeError('The ' + paramName + ' should be type Number')
|
||||
} else if (param < 0) {
|
||||
throw new Error('The ' + paramName + ' only accepts non-negative values')
|
||||
}
|
||||
}
|
||||
|
||||
export { surfaceAreaCube, surfaceAreaSphere, areaRectangle, areaSquare, areaTriangle, areaParallelogram, areaTrapezium, areaCircle, areaRhombus }
|
24
Maths/ArmstrongNumber.js
Normal file
24
Maths/ArmstrongNumber.js
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Author: dephraiim
|
||||
* License: GPL-3.0 or later
|
||||
*
|
||||
* An Armstrong number is equal to the sum of the cubes of its digits.
|
||||
* For example, 370 is an Armstrong number because 3*3*3 + 7*7*7 + 0*0*0 = 370.
|
||||
* An Armstrong number is often called Narcissistic number.
|
||||
*
|
||||
*/
|
||||
|
||||
const armstrongNumber = (num) => {
|
||||
if (num < 0 || typeof num !== 'number') return false
|
||||
|
||||
let newSum = 0
|
||||
|
||||
const numArr = num.toString().split('')
|
||||
numArr.forEach((num) => {
|
||||
newSum += parseInt(num) ** numArr.length
|
||||
})
|
||||
|
||||
return newSum === num
|
||||
}
|
||||
|
||||
export { armstrongNumber }
|
@ -1,3 +1,4 @@
|
||||
'use strict'
|
||||
/*
|
||||
author: PatOnTheBack
|
||||
license: GPL-3.0 or later
|
||||
@ -11,20 +12,18 @@
|
||||
https://en.wikipedia.org/wiki/Mean
|
||||
*/
|
||||
|
||||
function mean (nums) {
|
||||
'use strict'
|
||||
var sum = 0
|
||||
var avg
|
||||
const mean = (nums) => {
|
||||
// This is a function returns average/mean of array
|
||||
let sum = 0
|
||||
|
||||
// This loop sums all values in the 'nums' array.
|
||||
// This loop sums all values in the 'nums' array using forEach loop
|
||||
nums.forEach(function (current) {
|
||||
sum += current
|
||||
})
|
||||
|
||||
// Divide sum by the length of the 'nums' array.
|
||||
avg = sum / nums.length
|
||||
const avg = sum / nums.length
|
||||
return avg
|
||||
}
|
||||
|
||||
// Run `mean` Function to find average of a list of numbers.
|
||||
console.log(mean([2, 4, 6, 8, 20, 50, 70]))
|
||||
export { mean }
|
||||
|
@ -1,18 +1,16 @@
|
||||
// program to find sum of digits of a number
|
||||
|
||||
// function which would calculate sum and return it
|
||||
function digitSum (num) {
|
||||
const digitSum = (num) => {
|
||||
// sum will store sum of digits of a number
|
||||
let sum = 0
|
||||
// while will run untill num become 0
|
||||
while (num) {
|
||||
sum += (num % 10)
|
||||
sum += num % 10
|
||||
num = parseInt(num / 10)
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
|
||||
// assigning number
|
||||
const num = 12345
|
||||
console.log(digitSum(num))
|
||||
export { digitSum }
|
@ -13,10 +13,10 @@
|
||||
|
||||
'use strict'
|
||||
|
||||
function calcRange (num) {
|
||||
const calcRange = (num) => {
|
||||
// Generate a range of numbers from 1 to `num`.
|
||||
var i = 1
|
||||
var range = []
|
||||
let i = 1
|
||||
const range = []
|
||||
while (i <= num) {
|
||||
range.push(i)
|
||||
i += 1
|
||||
@ -24,9 +24,9 @@ function calcRange (num) {
|
||||
return range
|
||||
}
|
||||
|
||||
function calcFactorial (num) {
|
||||
var factorial
|
||||
var range = calcRange(num)
|
||||
const calcFactorial = (num) => {
|
||||
let factorial
|
||||
const range = calcRange(num)
|
||||
|
||||
// Check if the number is negative, positive, null, undefined, or zero
|
||||
if (num < 0) {
|
||||
@ -43,11 +43,8 @@ function calcFactorial (num) {
|
||||
range.forEach(function (i) {
|
||||
factorial = factorial * i
|
||||
})
|
||||
return 'The factorial of ' + num + ' is ' + factorial
|
||||
return `The factorial of ${num} is ${factorial}`
|
||||
}
|
||||
}
|
||||
|
||||
// Run `factorial` Function to find average of a list of numbers.
|
||||
|
||||
var num = console.log('Enter a number: ')
|
||||
console.log(calcFactorial(num))
|
||||
export { calcFactorial }
|
||||
|
16
Maths/Factors.js
Normal file
16
Maths/Factors.js
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Author: dephraiim
|
||||
* License: GPL-3.0 or later
|
||||
*
|
||||
* More on Factors:
|
||||
* https://www.mathsisfun.com/definitions/factor.html
|
||||
*
|
||||
*/
|
||||
|
||||
const factorsOfANumber = (number = 0) => {
|
||||
return Array.from(Array(number + 1).keys()).filter(
|
||||
(num) => number % num === 0
|
||||
)
|
||||
}
|
||||
|
||||
export { factorsOfANumber }
|
@ -66,18 +66,10 @@ const FibonacciDpWithoutRecursion = (number) => {
|
||||
for (var i = 2; i < number; ++i) {
|
||||
table.push(table[i - 1] + table[i - 2])
|
||||
}
|
||||
return (table)
|
||||
return table
|
||||
}
|
||||
|
||||
// testing
|
||||
|
||||
console.log(FibonacciIterative(5))
|
||||
// Output: [ 1, 1, 2, 3, 5 ]
|
||||
console.log(FibonacciRecursive(5))
|
||||
// Output: [ 1, 1, 2, 3, 5 ]
|
||||
|
||||
console.log(FibonacciRecursiveDP(5))
|
||||
// Output: 5
|
||||
|
||||
console.log(FibonacciDpWithoutRecursion(5))
|
||||
// Output: [ 1, 1, 2, 3, 5 ]
|
||||
export { FibonacciDpWithoutRecursion }
|
||||
export { FibonacciIterative }
|
||||
export { FibonacciRecursive }
|
||||
export { FibonacciRecursiveDP }
|
||||
|
@ -4,7 +4,7 @@
|
||||
https://en.wikipedia.org/wiki/Greatest_common_divisor
|
||||
*/
|
||||
|
||||
function findHCF (x, y) {
|
||||
const findHCF = (x, y) => {
|
||||
// If the input numbers are less than 1 return an error message.
|
||||
if (x < 1 || y < 1) {
|
||||
return 'Please enter values greater than zero.'
|
||||
@ -27,4 +27,5 @@ function findHCF (x, y) {
|
||||
// When the while loop finishes the minimum of x and y is the HCF.
|
||||
return Math.min(x, y)
|
||||
}
|
||||
console.log(findHCF(27, 36))
|
||||
|
||||
export { findHCF }
|
||||
|
@ -12,9 +12,19 @@
|
||||
'use strict'
|
||||
|
||||
// Find the LCM of two numbers.
|
||||
function findLcm (num1, num2) {
|
||||
var maxNum
|
||||
var lcm
|
||||
const findLcm = (num1, num2) => {
|
||||
// If the input numbers are less than 1 return an error message.
|
||||
if (num1 < 1 || num2 < 1) {
|
||||
return 'Please enter values greater than zero.'
|
||||
}
|
||||
|
||||
// If the input numbers are not integers return an error message.
|
||||
if (num1 !== Math.round(num1) || num2 !== Math.round(num2)) {
|
||||
return 'Please enter whole numbers.'
|
||||
}
|
||||
|
||||
let maxNum
|
||||
let lcm
|
||||
// Check to see whether num1 or num2 is larger.
|
||||
if (num1 > num2) {
|
||||
maxNum = num1
|
||||
@ -24,15 +34,10 @@ function findLcm (num1, num2) {
|
||||
lcm = maxNum
|
||||
|
||||
while (true) {
|
||||
if ((lcm % num1 === 0) && (lcm % num2 === 0)) {
|
||||
break
|
||||
}
|
||||
if (lcm % num1 === 0 && lcm % num2 === 0) break
|
||||
lcm += maxNum
|
||||
}
|
||||
return lcm
|
||||
}
|
||||
|
||||
// Run `findLcm` Function
|
||||
var num1 = 12
|
||||
var num2 = 76
|
||||
console.log(findLcm(num1, num2))
|
||||
export { findLcm }
|
||||
|
@ -40,17 +40,14 @@
|
||||
*/
|
||||
|
||||
const gridGetX = (columns, index) => {
|
||||
while ((index + 1) > columns) {
|
||||
while (index + 1 > columns) {
|
||||
index = index - columns
|
||||
}
|
||||
return (index + 1)
|
||||
return index + 1
|
||||
}
|
||||
|
||||
const gridGetY = (columns, index) => {
|
||||
return (Math.floor(index / columns)) + 1
|
||||
return Math.floor(index / columns) + 1
|
||||
}
|
||||
|
||||
console.log(`If a square array has 400 elements, then the value of x for the 27th element is ${gridGetX(Math.sqrt(400), 27)}`)
|
||||
console.log(`If an array has 7 columns and 3 rows, then the value of x for the 11th element is ${gridGetX(7, 11)}`)
|
||||
console.log(`If a square array has 400 elements, then the value of y for the 27th element is ${gridGetY(Math.sqrt(400), 27)}`)
|
||||
console.log(`If an array has 7 columns and 3 rows, then the value of y for the 11th element is ${gridGetY(7, 11)}`)
|
||||
export { gridGetX, gridGetY }
|
||||
|
91
Maths/MatrixMultiplication.js
Normal file
91
Maths/MatrixMultiplication.js
Normal file
@ -0,0 +1,91 @@
|
||||
// Wikipedia URL for General Matrix Multiplication Concepts: https://en.wikipedia.org/wiki/Matrix_multiplication
|
||||
|
||||
// This algorithm has multiple functions that ultimately check if the inputs are actually matrices and if two Matrices (that can be different sizes) can be multiplied together.
|
||||
// matrices that are of the same size [2x2]x[2x2], and the second is the multiplication of two matrices that are not the same size [2x3]x[3x2].
|
||||
|
||||
// MatrixCheck tests to see if all of the rows of the matrix inputted have similar size columns
|
||||
const matrixCheck = (matrix) => {
|
||||
let columnNumb
|
||||
for (let index = 0; index < matrix.length; index++) {
|
||||
if (index === 0) {
|
||||
columnNumb = matrix[index].length
|
||||
} else if (matrix[index].length !== columnNumb) {
|
||||
console.log('The columns in this array are not equal')
|
||||
} else {
|
||||
return columnNumb
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tests to see if the matrices have a like side, i.e. the row length on the first matrix matches the column length on the second matrix, or vise versa.
|
||||
const twoMatricesCheck = (first, second) => {
|
||||
const [firstRowLength, secondRowLength, firstColLength, secondColLength] = [first.length, second.length, matrixCheck(first), matrixCheck(second)]
|
||||
if (firstRowLength !== secondColLength || secondRowLength !== firstColLength) {
|
||||
console.log('These matrices do not have a common side')
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// returns an empty array that has the same number of rows as the left matrix being multiplied.
|
||||
// Uses Array.prototype.map() to loop over the first (or left) matrix and returns an empty array on each iteration.
|
||||
const initiateEmptyArray = (first, second) => {
|
||||
if (twoMatricesCheck(first, second)) {
|
||||
const emptyArray = first.map(() => {
|
||||
return ['']
|
||||
})
|
||||
return emptyArray
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, `matrixMult` uses `Array.prototype.push()`, multiple layers of nested `for` loops, the addition assignment `+=` operator and multiplication operator `*` to perform the dot product between two matrices of differing sizes.
|
||||
// Dot product, takes the row of the first matrix and multiplies it by the column of the second matrix, the `twoMatricesCheck` tested to see if they were the same size already.
|
||||
// The dot product for each iteration is then saved to its respective index into `multMatrix`.
|
||||
const matrixMult = (firstArray, secondArray) => {
|
||||
const multMatrix = initiateEmptyArray(firstArray, secondArray)
|
||||
for (let rm = 0; rm < firstArray.length; rm++) {
|
||||
const rowMult = []
|
||||
for (let col = 0; col < firstArray[0].length; col++) {
|
||||
rowMult.push(firstArray[rm][col])
|
||||
}
|
||||
for (let cm = 0; cm < firstArray.length; cm++) {
|
||||
const colMult = []
|
||||
for (let row = 0; row < secondArray.length; row++) {
|
||||
colMult.push(secondArray[row][cm])
|
||||
}
|
||||
let newNumb = 0
|
||||
for (let index = 0; index < rowMult.length; index++) {
|
||||
newNumb += rowMult[index] * colMult[index]
|
||||
}
|
||||
multMatrix[rm][cm] = newNumb
|
||||
}
|
||||
}
|
||||
return multMatrix
|
||||
}
|
||||
|
||||
const firstMatrix = [
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
]
|
||||
|
||||
const secondMatrix = [
|
||||
[5, 6],
|
||||
[7, 8]
|
||||
]
|
||||
|
||||
console.log(matrixMult(firstMatrix, secondMatrix)) // [ [ 19, 22 ], [ 43, 50 ] ]
|
||||
|
||||
const thirdMatrix = [
|
||||
[-1, 4, 1],
|
||||
[7, -6, 2]
|
||||
]
|
||||
const fourthMatrix = [
|
||||
[2, -2],
|
||||
[5, 3],
|
||||
[3, 2]
|
||||
]
|
||||
|
||||
console.log(matrixMult(thirdMatrix, fourthMatrix)) // [ [ 21, 16 ], [ -10, -28 ] ]
|
21
Maths/MeanSquareError.js
Normal file
21
Maths/MeanSquareError.js
Normal file
@ -0,0 +1,21 @@
|
||||
// Wikipedia: https://en.wikipedia.org/wiki/Mean_squared_error
|
||||
|
||||
const meanSquaredError = (predicted, expected) => {
|
||||
if (!Array.isArray(predicted) || !Array.isArray(expected)) {
|
||||
throw new TypeError('Argument must be an Array')
|
||||
}
|
||||
|
||||
if (predicted.length !== expected.length) {
|
||||
throw new TypeError('The two lists must be of equal length')
|
||||
}
|
||||
|
||||
let err = 0
|
||||
|
||||
for (let i = 0; i < expected.length; i++) {
|
||||
err += (expected[i] - predicted[i]) ** 2
|
||||
}
|
||||
|
||||
return err / expected.length
|
||||
}
|
||||
|
||||
export { meanSquaredError }
|
@ -19,13 +19,4 @@ const modularBinaryExponentiation = (a, n, m) => {
|
||||
}
|
||||
}
|
||||
|
||||
const main = () => {
|
||||
// binary_exponentiation(2, 10, 17)
|
||||
// > 4
|
||||
console.log(modularBinaryExponentiation(2, 10, 17))
|
||||
// binary_exponentiation(3, 9, 12)
|
||||
// > 3
|
||||
console.log(modularBinaryExponentiation(3, 9, 12))
|
||||
}
|
||||
|
||||
main()
|
||||
export { modularBinaryExponentiation }
|
||||
|
12
Maths/NumberOfDigits.js
Normal file
12
Maths/NumberOfDigits.js
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
*
|
||||
* Author: dephraiim
|
||||
* License: GPL-3.0 or later
|
||||
*
|
||||
* Returns the number of digits of a given integer
|
||||
*
|
||||
*/
|
||||
|
||||
const numberOfDigit = (n) => Math.abs(n).toString().length
|
||||
|
||||
export { numberOfDigit }
|
@ -14,7 +14,7 @@
|
||||
* @complexity: O(n)
|
||||
*/
|
||||
|
||||
function PalindromeRecursive (string) {
|
||||
const PalindromeRecursive = (string) => {
|
||||
// Base case
|
||||
if (string.length < 2) return true
|
||||
|
||||
@ -26,7 +26,7 @@ function PalindromeRecursive (string) {
|
||||
return PalindromeRecursive(string.slice(1, string.length - 1))
|
||||
}
|
||||
|
||||
function PalindromeIterative (string) {
|
||||
const PalindromeIterative = (string) => {
|
||||
const _string = string
|
||||
.toLowerCase()
|
||||
.replace(/ /g, '')
|
||||
@ -45,7 +45,4 @@ function PalindromeIterative (string) {
|
||||
return true
|
||||
}
|
||||
|
||||
// testing
|
||||
|
||||
console.log(PalindromeRecursive('Javascript Community'))
|
||||
console.log(PalindromeIterative('mom'))
|
||||
export { PalindromeIterative, PalindromeRecursive }
|
||||
|
@ -1,6 +1,16 @@
|
||||
const numRows = 5
|
||||
const addRow = (triangle) => {
|
||||
const previous = triangle[triangle.length - 1]
|
||||
const newRow = [1]
|
||||
for (let i = 0; i < previous.length - 1; i++) {
|
||||
const current = previous[i]
|
||||
const next = previous[i + 1]
|
||||
newRow.push(current + next)
|
||||
}
|
||||
newRow.push(1)
|
||||
return triangle.push(newRow)
|
||||
}
|
||||
|
||||
var generate = function (numRows) {
|
||||
const generate = (numRows) => {
|
||||
const triangle = [[1], [1, 1]]
|
||||
|
||||
if (numRows === 0) {
|
||||
@ -16,16 +26,5 @@ var generate = function (numRows) {
|
||||
}
|
||||
return triangle
|
||||
}
|
||||
var addRow = function (triangle) {
|
||||
const previous = triangle[triangle.length - 1]
|
||||
const newRow = [1]
|
||||
for (let i = 0; i < previous.length - 1; i++) {
|
||||
const current = previous[i]
|
||||
const next = previous[i + 1]
|
||||
newRow.push(current + next)
|
||||
}
|
||||
newRow.push(1)
|
||||
return triangle.push(newRow)
|
||||
}
|
||||
|
||||
generate(numRows)
|
||||
export { generate }
|
||||
|
9
Maths/PerfectCube.js
Normal file
9
Maths/PerfectCube.js
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Author: dephraiim
|
||||
* License: GPL-3.0 or later
|
||||
*
|
||||
*/
|
||||
|
||||
const perfectCube = (num) => Math.round(num ** (1 / 3)) ** 3 === num
|
||||
|
||||
export { perfectCube }
|
30
Maths/PerfectNumber.js
Normal file
30
Maths/PerfectNumber.js
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Author: dephraiim
|
||||
* License: GPL-3.0 or later
|
||||
*
|
||||
* == Perfect Number ==
|
||||
* In number theory, a perfect number is a positive integer that is equal to the sum of
|
||||
* its positive divisors(factors), excluding the number itself.
|
||||
* For example: 6 ==> divisors[1, 2, 3, 6]
|
||||
* Excluding 6, the sum(divisors) is 1 + 2 + 3 = 6
|
||||
* So, 6 is a Perfect Number
|
||||
* Other examples of Perfect Numbers: 28, 486, ...
|
||||
*
|
||||
* More on Perfect Number:
|
||||
* https://en.wikipedia.org/wiki/Perfect_number
|
||||
*
|
||||
*/
|
||||
|
||||
const factorsExcludingNumber = (n) => {
|
||||
return [...Array(n).keys()].filter((num) => n % num === 0)
|
||||
}
|
||||
|
||||
const perfectNumber = (n) => {
|
||||
const factorSum = factorsExcludingNumber(n).reduce((num, initialValue) => {
|
||||
return num + initialValue
|
||||
}, 0)
|
||||
|
||||
return factorSum === n
|
||||
}
|
||||
|
||||
export { perfectNumber }
|
9
Maths/PerfectSquare.js
Normal file
9
Maths/PerfectSquare.js
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Author: dephraiim
|
||||
* License: GPL-3.0 or later
|
||||
*
|
||||
*/
|
||||
|
||||
const perfectSquare = (num) => Math.sqrt(num) ** 2 === num
|
||||
|
||||
export { perfectSquare }
|
@ -1,7 +1,7 @@
|
||||
// Wikipedia: https://en.wikipedia.org/wiki/Monte_Carlo_method
|
||||
// Video Explaination: https://www.youtube.com/watch?v=ELetCV_wX_c
|
||||
|
||||
function piEstimation (iterations = 100000) {
|
||||
const piEstimation = (iterations = 100000) => {
|
||||
let circleCounter = 0
|
||||
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
@ -18,8 +18,4 @@ function piEstimation (iterations = 100000) {
|
||||
return pi
|
||||
}
|
||||
|
||||
function main () {
|
||||
console.log(piEstimation())
|
||||
}
|
||||
|
||||
main()
|
||||
export { piEstimation }
|
||||
|
63
Maths/Polynomial.js
Normal file
63
Maths/Polynomial.js
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Polynomials are algebraic expressions consisting of two or more algebraic terms.
|
||||
* Terms of a polynomial are:
|
||||
* 1. Coefficients e.g. 5, 4 in 5x^0, 4x^3 respectively
|
||||
* 2. Variables e.g. y in 3y^2
|
||||
* 3. Exponents e.g. 5 in y^5
|
||||
*
|
||||
* Class Polynomial constructs the polynomial using Array as an argument.
|
||||
* The members of array are coefficients and their indexes as exponents.
|
||||
*/
|
||||
class Polynomial {
|
||||
constructor (array) {
|
||||
this.coefficientArray = array // array of coefficients
|
||||
this.polynomial = '' // in terms of x e.g. (2x) + (1)
|
||||
this.construct()
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to construct the polynomial in terms of x using the coefficientArray
|
||||
*/
|
||||
construct () {
|
||||
this.polynomial = this.coefficientArray
|
||||
.map((coefficient, exponent) => {
|
||||
if (coefficient === 0) {
|
||||
return '0'
|
||||
}
|
||||
if (exponent === 0) {
|
||||
return `(${coefficient})`
|
||||
} else if (exponent === 1) {
|
||||
return `(${coefficient}x)`
|
||||
} else {
|
||||
return `(${coefficient}x^${exponent})`
|
||||
}
|
||||
})
|
||||
.filter((x) => {
|
||||
if (x !== '0') {
|
||||
return x
|
||||
}
|
||||
})
|
||||
.reverse()
|
||||
.join(' + ')
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to display polynomial in terms of x
|
||||
* @returns {String} of polynomial representation in terms of x
|
||||
*/
|
||||
display () {
|
||||
return this.polynomial
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to calculate the value of the polynomial by substituting variable x
|
||||
* @param {Number} value
|
||||
*/
|
||||
evaluate (value) {
|
||||
return this.coefficientArray.reduce((result, coefficient, exponent) => {
|
||||
return result + coefficient * Math.pow(value, exponent)
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
|
||||
export { Polynomial }
|
@ -9,6 +9,9 @@
|
||||
const PrimeCheck = (n) => {
|
||||
// input: n: int
|
||||
// output: boolean
|
||||
if (n === 1) return false
|
||||
if (n === 0) return false
|
||||
|
||||
for (let i = 2; i * i <= n; i++) {
|
||||
if (n % i === 0) {
|
||||
return false
|
||||
@ -17,13 +20,4 @@ const PrimeCheck = (n) => {
|
||||
return true
|
||||
}
|
||||
|
||||
const main = () => {
|
||||
// PrimeCheck(1000003)
|
||||
// > true
|
||||
console.log(PrimeCheck(1000003))
|
||||
// PrimeCheck(1000001)
|
||||
// > false
|
||||
console.log(PrimeCheck(1000001))
|
||||
}
|
||||
|
||||
main()
|
||||
export { PrimeCheck }
|
||||
|
33
Maths/ReversePolishNotation.js
Normal file
33
Maths/ReversePolishNotation.js
Normal file
@ -0,0 +1,33 @@
|
||||
// Wikipedia: https://en.wikipedia.org/wiki/Reverse_Polish_notation
|
||||
|
||||
const calcRPN = (expression) => {
|
||||
const operators = {
|
||||
'+': (a, b) => a + b,
|
||||
'-': (a, b) => a - b,
|
||||
'*': (a, b) => a * b,
|
||||
'/': (a, b) => b / a
|
||||
}
|
||||
|
||||
const tokens = expression.split(' ')
|
||||
|
||||
const stack = []
|
||||
|
||||
tokens.forEach((token) => {
|
||||
const operator = operators[token]
|
||||
|
||||
if (typeof operator === 'function') {
|
||||
const a = stack.pop()
|
||||
const b = stack.pop()
|
||||
|
||||
const result = operator(a, b)
|
||||
|
||||
stack.push(result)
|
||||
} else {
|
||||
stack.push(parseFloat(token))
|
||||
}
|
||||
})
|
||||
|
||||
return stack.pop()
|
||||
}
|
||||
|
||||
export { calcRPN }
|
@ -1,9 +1,9 @@
|
||||
function sieveOfEratosthenes (n) {
|
||||
const sieveOfEratosthenes = (n) => {
|
||||
/*
|
||||
* Calculates prime numbers till a number n
|
||||
* :param n: Number upto which to calculate primes
|
||||
* :return: A boolean list contaning only primes
|
||||
*/
|
||||
* Calculates prime numbers till a number n
|
||||
* :param n: Number upto which to calculate primes
|
||||
* :return: A boolean list contaning only primes
|
||||
*/
|
||||
const primes = new Array(n + 1)
|
||||
primes.fill(true) // set all as true initially
|
||||
primes[0] = primes[1] = false // Handling case for 0 and 1
|
||||
@ -18,14 +18,4 @@ function sieveOfEratosthenes (n) {
|
||||
return primes
|
||||
}
|
||||
|
||||
function main () {
|
||||
const n = 69 // number till where we wish to find primes
|
||||
const primes = sieveOfEratosthenes(n)
|
||||
for (let i = 2; i <= n; i++) {
|
||||
if (primes[i]) {
|
||||
console.log(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
export { sieveOfEratosthenes }
|
||||
|
15
Maths/isDivisible.js
Normal file
15
Maths/isDivisible.js
Normal file
@ -0,0 +1,15 @@
|
||||
// Checks if a number is divisible by another number.
|
||||
|
||||
const isDivisible = (num1, num2) => {
|
||||
if (isNaN(num1) || isNaN(num2) || num1 == null || num2 == null) {
|
||||
return 'All parameters have to be numbers'
|
||||
}
|
||||
if (num2 === 0) {
|
||||
return 'Not possible to divide by zero'
|
||||
}
|
||||
return num1 % num2 === 0
|
||||
}
|
||||
|
||||
console.log(isDivisible(10, 5)) // returns true
|
||||
console.log(isDivisible(123498175, 5)) // returns true
|
||||
console.log(isDivisible(99, 5)) // returns false
|
13
Maths/isOdd.js
Normal file
13
Maths/isOdd.js
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* function to check if number is odd
|
||||
* return true if number is odd
|
||||
* else false
|
||||
*/
|
||||
|
||||
const isOdd = (value) => {
|
||||
return !!((value & 1))
|
||||
}
|
||||
|
||||
// testing
|
||||
console.log(isOdd(2))
|
||||
console.log(isOdd(3))
|
13
Maths/test/Abs.test.js
Normal file
13
Maths/test/Abs.test.js
Normal file
@ -0,0 +1,13 @@
|
||||
import { absVal } from '../Abs'
|
||||
|
||||
describe('absVal', () => {
|
||||
it('should return an absolute value of a negative number', () => {
|
||||
const absOfNegativeNumber = absVal(-34)
|
||||
expect(absOfNegativeNumber).toBe(34)
|
||||
})
|
||||
|
||||
it('should return an absolute value of a positive number', () => {
|
||||
const absOfPositiveNumber = absVal(50)
|
||||
expect(absOfPositiveNumber).toBe(50)
|
||||
})
|
||||
})
|
99
Maths/test/Area.test.js
Normal file
99
Maths/test/Area.test.js
Normal file
@ -0,0 +1,99 @@
|
||||
import * as area from '../Area'
|
||||
|
||||
describe('Testing surfaceAreaCube calculations', () => {
|
||||
it('with natural number', () => {
|
||||
const surfaceAreaOfOne = area.surfaceAreaCube(1.2)
|
||||
const surfaceAreaOfThree = area.surfaceAreaCube(3)
|
||||
expect(surfaceAreaOfOne).toBe(8.64)
|
||||
expect(surfaceAreaOfThree).toBe(54)
|
||||
})
|
||||
it('with negative argument, expect throw', () => {
|
||||
expect(() => area.surfaceAreaCube(-1)).toThrow()
|
||||
})
|
||||
it('with non-numeric argument, expect throw', () => {
|
||||
expect(() => area.surfaceAreaCube('199')).toThrow()
|
||||
})
|
||||
})
|
||||
describe('Testing surfaceAreaSphere calculations', () => {
|
||||
it('with correct value', () => {
|
||||
const calculateArea = area.surfaceAreaSphere(5)
|
||||
const expected = 314.1592653589793
|
||||
expect(calculateArea).toBe(expected)
|
||||
})
|
||||
it('with negative value, expect throw', () => {
|
||||
expect(() => area.surfaceAreaSphere(-1)).toThrow()
|
||||
})
|
||||
})
|
||||
describe('Testing areaRectangle calculations', () => {
|
||||
it('with correct args', () => {
|
||||
const areaRectangle = area.areaRectangle(2.5, 2)
|
||||
expect(areaRectangle).toBe(5.0)
|
||||
})
|
||||
it('with incorrect args, expect throw', () => {
|
||||
expect(() => area.areaRectangle(-1, 20)).toThrow()
|
||||
expect(() => area.areaRectangle('1', 0)).toThrow()
|
||||
expect(() => area.areaRectangle(23, -1)).toThrow()
|
||||
expect(() => area.areaRectangle(23, 'zero')).toThrow()
|
||||
})
|
||||
})
|
||||
describe('Testing areaSquare calculations', () => {
|
||||
it('with correct args', () => {
|
||||
const areaSquare = area.areaSquare(2.5)
|
||||
expect(areaSquare).toBe(6.25)
|
||||
})
|
||||
it('with incorrect side length, expect throw', () => {
|
||||
expect(() => area.areaSquare(-1)).toThrow()
|
||||
expect(() => area.areaSquare('zero')).toThrow()
|
||||
})
|
||||
})
|
||||
describe('Testing areaTriangle calculations', () => {
|
||||
it('with correct args', () => {
|
||||
const areaTriangle = area.areaTriangle(1.66, 3.44)
|
||||
expect(areaTriangle).toBe(2.8552)
|
||||
})
|
||||
it('with incorrect base and height, expect throw', () => {
|
||||
expect(() => area.areaTriangle(-1, 1)).toThrow()
|
||||
expect(() => area.areaTriangle(9, 'zero')).toThrow()
|
||||
})
|
||||
})
|
||||
describe('Testing areaParallelogram calculations', () => {
|
||||
it('with correct args', () => {
|
||||
const areaParallelogram = area.areaParallelogram(1.66, 3.44)
|
||||
expect(areaParallelogram).toBe(5.7104)
|
||||
})
|
||||
it('with incorrect base and height, expect throw', () => {
|
||||
expect(() => area.areaParallelogram(-1, 1)).toThrow()
|
||||
expect(() => area.areaParallelogram(9, 'zero')).toThrow()
|
||||
})
|
||||
})
|
||||
describe('Testing areaTrapezium calculations', () => {
|
||||
it('with correct args', () => {
|
||||
const areaTrapezium = area.areaTrapezium(1.66, 2.41, 4.1)
|
||||
expect(areaTrapezium).toBe(8.3435)
|
||||
})
|
||||
it('with incorrect bases and height, expect throw', () => {
|
||||
expect(() => area.areaTrapezium(-1, 1, 0)).toThrow()
|
||||
expect(() => area.areaTrapezium(9, 'zero', 2)).toThrow()
|
||||
expect(() => area.areaTrapezium(9, 1, 'seven')).toThrow()
|
||||
})
|
||||
})
|
||||
describe('Testing areaCircle calculations', () => {
|
||||
it('with correct args', () => {
|
||||
const areaCircle = area.areaCircle(3.456)
|
||||
expect(areaCircle).toBe(37.52298159254666)
|
||||
})
|
||||
it('with incorrect diagonal, expect throw', () => {
|
||||
expect(() => area.areaCircle(-1)).toThrow()
|
||||
expect(() => area.areaCircle('zero')).toThrow()
|
||||
})
|
||||
})
|
||||
describe('Testing areaRhombus calculations', () => {
|
||||
it('with correct args', () => {
|
||||
const areaRhombus = area.areaRhombus(2.5, 2.0)
|
||||
expect(areaRhombus).toBe(2.5)
|
||||
})
|
||||
it('with incorrect diagonals, expect throw', () => {
|
||||
expect(() => area.areaRhombus(7, -1)).toThrow()
|
||||
expect(() => area.areaRhombus('zero', 2)).toThrow()
|
||||
})
|
||||
})
|
14
Maths/test/ArmstrongNumber.test.js
Normal file
14
Maths/test/ArmstrongNumber.test.js
Normal file
@ -0,0 +1,14 @@
|
||||
import { armstrongNumber } from '../ArmstrongNumber'
|
||||
|
||||
describe('ArmstrongNumber', () => {
|
||||
it('should return true for an armstrong number', () => {
|
||||
expect(armstrongNumber(371)).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should return false for a non-armstrong number', () => {
|
||||
expect(armstrongNumber(300)).toBeFalsy()
|
||||
})
|
||||
it('should return false for negative values', () => {
|
||||
expect(armstrongNumber(-2)).toBeFalsy()
|
||||
})
|
||||
})
|
11
Maths/test/AverageMean.test.js
Normal file
11
Maths/test/AverageMean.test.js
Normal file
@ -0,0 +1,11 @@
|
||||
import { mean } from '../AverageMean'
|
||||
|
||||
describe('Tests for average mean', () => {
|
||||
it('should be a function', () => {
|
||||
expect(typeof mean).toEqual('function')
|
||||
})
|
||||
it('should return the mean of an array of numbers', () => {
|
||||
const meanFunction = mean([1, 2, 4, 5])
|
||||
expect(meanFunction).toBe(3)
|
||||
})
|
||||
})
|
11
Maths/test/DigitSum.test.js
Normal file
11
Maths/test/DigitSum.test.js
Normal file
@ -0,0 +1,11 @@
|
||||
import { digitSum } from '../DigitSum'
|
||||
|
||||
describe('digitSum', () => {
|
||||
it('is a function', () => {
|
||||
expect(typeof digitSum).toEqual('function')
|
||||
})
|
||||
it('should return the sum of digits of a given number', () => {
|
||||
const sumOfNumber = digitSum(12345)
|
||||
expect(sumOfNumber).toBe(15)
|
||||
})
|
||||
})
|
35
Maths/test/Factorial.test.js
Normal file
35
Maths/test/Factorial.test.js
Normal file
@ -0,0 +1,35 @@
|
||||
import { calcFactorial } from '../Factorial'
|
||||
|
||||
describe('calcFactorial', () => {
|
||||
it('is a function', () => {
|
||||
expect(typeof calcFactorial).toEqual('function')
|
||||
})
|
||||
|
||||
it('should return a statement for value "0"', () => {
|
||||
expect(calcFactorial(0)).toBe('The factorial of 0 is 1.')
|
||||
})
|
||||
|
||||
it('should return a statement for "null" and "undefined"', () => {
|
||||
const nullFactorial = calcFactorial(null)
|
||||
const undefinedFactorial = calcFactorial(undefined)
|
||||
|
||||
expect(nullFactorial).toBe(
|
||||
'Sorry, factorial does not exist for null or undefined numbers.'
|
||||
)
|
||||
expect(undefinedFactorial).toBe(
|
||||
'Sorry, factorial does not exist for null or undefined numbers.'
|
||||
)
|
||||
})
|
||||
|
||||
it('should not support negative numbers', () => {
|
||||
const negativeFactorial = calcFactorial(-5)
|
||||
expect(negativeFactorial).toBe(
|
||||
'Sorry, factorial does not exist for negative numbers.'
|
||||
)
|
||||
})
|
||||
|
||||
it('should return the factorial of a positive number', () => {
|
||||
const positiveFactorial = calcFactorial(3)
|
||||
expect(positiveFactorial).toBe('The factorial of 3 is 6')
|
||||
})
|
||||
})
|
10
Maths/test/Factors.test.js
Normal file
10
Maths/test/Factors.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { factorsOfANumber } from '../Factors'
|
||||
|
||||
describe('Factors', () => {
|
||||
factorsOfANumber(50).forEach((num) => {
|
||||
it(`${num} is a factor of 50`, () => {
|
||||
const isFactor = 50 % num === 0
|
||||
expect(isFactor).toBeTruthy()
|
||||
})
|
||||
})
|
||||
})
|
30
Maths/test/Fibonacci.test.js
Normal file
30
Maths/test/Fibonacci.test.js
Normal file
@ -0,0 +1,30 @@
|
||||
import {
|
||||
FibonacciDpWithoutRecursion,
|
||||
FibonacciRecursiveDP,
|
||||
FibonacciIterative,
|
||||
FibonacciRecursive
|
||||
} from '../Fibonacci'
|
||||
|
||||
describe('Fibonanci', () => {
|
||||
it('should return an array of numbers for FibonnaciIterative', () => {
|
||||
expect(FibonacciIterative(5)).toEqual(
|
||||
expect.arrayContaining([1, 1, 2, 3, 5])
|
||||
)
|
||||
})
|
||||
|
||||
it('should return an array of numbers for FibonnaciRecursive', () => {
|
||||
expect(FibonacciRecursive(5)).toEqual(
|
||||
expect.arrayContaining([1, 1, 2, 3, 5])
|
||||
)
|
||||
})
|
||||
|
||||
it('should return number for FibonnaciRecursiveDP', () => {
|
||||
expect(FibonacciRecursiveDP(5)).toBe(5)
|
||||
})
|
||||
|
||||
it('should return an array of numbers for FibonacciDpWithoutRecursion', () => {
|
||||
expect(FibonacciDpWithoutRecursion(5)).toEqual(
|
||||
expect.arrayContaining([1, 1, 2, 3, 5])
|
||||
)
|
||||
})
|
||||
})
|
20
Maths/test/FindHcf.test.js
Normal file
20
Maths/test/FindHcf.test.js
Normal file
@ -0,0 +1,20 @@
|
||||
import { findHCF } from '../FindHcf'
|
||||
|
||||
describe('findHCF', () => {
|
||||
it('should throw a statement for values less than 1', () => {
|
||||
expect(findHCF(0, 0)).toBe('Please enter values greater than zero.')
|
||||
})
|
||||
|
||||
it('should throw a statement for one value less than 1', () => {
|
||||
expect(findHCF(0, 1)).toBe('Please enter values greater than zero.')
|
||||
expect(findHCF(1, 0)).toBe('Please enter values greater than zero.')
|
||||
})
|
||||
|
||||
it('should return an error for values non-integer values', () => {
|
||||
expect(findHCF(2.24, 4.35)).toBe('Please enter whole numbers.')
|
||||
})
|
||||
|
||||
it('should return the HCF of two given integers', () => {
|
||||
expect(findHCF(27, 36)).toBe(9)
|
||||
})
|
||||
})
|
20
Maths/test/FindLcm.test.js
Normal file
20
Maths/test/FindLcm.test.js
Normal file
@ -0,0 +1,20 @@
|
||||
import { findLcm } from '../FindLcm'
|
||||
|
||||
describe('findLcm', () => {
|
||||
it('should throw a statement for values less than 1', () => {
|
||||
expect(findLcm(0, 0)).toBe('Please enter values greater than zero.')
|
||||
})
|
||||
|
||||
it('should throw a statement for one value less than 1', () => {
|
||||
expect(findLcm(1, 0)).toBe('Please enter values greater than zero.')
|
||||
expect(findLcm(0, 1)).toBe('Please enter values greater than zero.')
|
||||
})
|
||||
|
||||
it('should return an error for values non-integer values', () => {
|
||||
expect(findLcm(4.564, 7.39)).toBe('Please enter whole numbers.')
|
||||
})
|
||||
|
||||
it('should return the LCM of two given integers', () => {
|
||||
expect(findLcm(27, 36)).toBe(108)
|
||||
})
|
||||
})
|
16
Maths/test/GridGet.test.js
Normal file
16
Maths/test/GridGet.test.js
Normal file
@ -0,0 +1,16 @@
|
||||
import { gridGetX, gridGetY } from '../GridGet'
|
||||
|
||||
describe('GridGet', () => {
|
||||
it('should have a value of x for the 27th element if the square array has 400 elements', () => {
|
||||
expect(gridGetX(Math.sqrt(400), 27)).toEqual(8)
|
||||
})
|
||||
it('should have a value of x for the 11th element if the square array has 7 columns and 3 rows', () => {
|
||||
expect(gridGetX(7, 11)).toEqual(5)
|
||||
})
|
||||
it('should have a value of y for the 27th element if the square array has 400 elements', () => {
|
||||
expect(gridGetY(Math.sqrt(400), 27)).toEqual(2)
|
||||
})
|
||||
it('should have a value of y for the 11th element if the square array has 7 columns and 3 rows ', () => {
|
||||
expect(gridGetX(7, 11)).toEqual(5)
|
||||
})
|
||||
})
|
21
Maths/test/MeanSquareError.test.js
Normal file
21
Maths/test/MeanSquareError.test.js
Normal file
@ -0,0 +1,21 @@
|
||||
import { meanSquaredError } from '../MeanSquareError'
|
||||
|
||||
describe('meanSquareError', () => {
|
||||
it('should throw an error on non-array arguments', () => {
|
||||
expect(() => meanSquaredError(1, 4)).toThrow('Argument must be an Array')
|
||||
})
|
||||
|
||||
it('should throw an error on non equal length ', () => {
|
||||
const firstArr = [1, 2, 3, 4, 5]
|
||||
const secondArr = [1, 2, 3]
|
||||
expect(() => meanSquaredError(firstArr, secondArr)).toThrow(
|
||||
'The two lists must be of equal length'
|
||||
)
|
||||
})
|
||||
|
||||
it('should return the mean square error of two equal length arrays', () => {
|
||||
const firstArr = [1, 2, 3, 4, 5]
|
||||
const secondArr = [1, 3, 5, 6, 7]
|
||||
expect(meanSquaredError(firstArr, secondArr)).toBe(2.6)
|
||||
})
|
||||
})
|
7
Maths/test/ModularBinaryExponentiationRecursive.test.js
Normal file
7
Maths/test/ModularBinaryExponentiationRecursive.test.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { modularBinaryExponentiation } from '../ModularBinaryExponentiationRecursive'
|
||||
|
||||
describe('modularBinaryExponentiation', () => {
|
||||
it('should return the binary exponentiation', () => {
|
||||
expect(modularBinaryExponentiation(2, 10, 17)).toBe(4)
|
||||
})
|
||||
})
|
11
Maths/test/NumberOfDigits.test.js
Normal file
11
Maths/test/NumberOfDigits.test.js
Normal file
@ -0,0 +1,11 @@
|
||||
import { numberOfDigit } from '../NumberOfDigits'
|
||||
|
||||
describe('NumberOfDigits', () => {
|
||||
it('should return the correct number of digits for an integer', () => {
|
||||
expect(numberOfDigit(1234000)).toBe(7)
|
||||
})
|
||||
|
||||
it('should return the correct number of digits for a negative number', () => {
|
||||
expect(numberOfDigit(-2346243)).toBe(7)
|
||||
})
|
||||
})
|
16
Maths/test/Palindrome.test.js
Normal file
16
Maths/test/Palindrome.test.js
Normal file
@ -0,0 +1,16 @@
|
||||
import { PalindromeRecursive, PalindromeIterative } from '../Palindrome'
|
||||
|
||||
describe('Palindrome', () => {
|
||||
it('should return true for a palindrome for PalindromeRecursive', () => {
|
||||
expect(PalindromeRecursive('mom')).toBeTruthy()
|
||||
})
|
||||
it('should return true for a palindrome for PalindromeIterative', () => {
|
||||
expect(PalindromeIterative('mom')).toBeTruthy()
|
||||
})
|
||||
it('should return false for a non-palindrome for PalindromeRecursive', () => {
|
||||
expect(PalindromeRecursive('Algorithms')).toBeFalsy()
|
||||
})
|
||||
it('should return true for a non-palindrome for PalindromeIterative', () => {
|
||||
expect(PalindromeIterative('JavaScript')).toBeFalsy()
|
||||
})
|
||||
})
|
20
Maths/test/PascalTriangle.test.js
Normal file
20
Maths/test/PascalTriangle.test.js
Normal file
@ -0,0 +1,20 @@
|
||||
import { generate } from '../PascalTriangle'
|
||||
|
||||
describe('Pascals Triangle', () => {
|
||||
it('should have the the same length as the number', () => {
|
||||
const pascalsTriangle = generate(5)
|
||||
expect(pascalsTriangle.length).toEqual(5)
|
||||
})
|
||||
it('should have same length as its index in the array', () => {
|
||||
const pascalsTriangle = generate(5)
|
||||
pascalsTriangle.forEach((arr, index) => {
|
||||
expect(arr.length).toEqual(index + 1)
|
||||
})
|
||||
})
|
||||
it('should return an array of arrays', () => {
|
||||
const pascalsTriangle = generate(3)
|
||||
expect(pascalsTriangle).toEqual(
|
||||
expect.arrayContaining([[1], [1, 1], [1, 2, 1]])
|
||||
)
|
||||
})
|
||||
})
|
10
Maths/test/PerfectCube.test.js
Normal file
10
Maths/test/PerfectCube.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { perfectCube } from '../PerfectCube'
|
||||
|
||||
describe('PerfectCube', () => {
|
||||
it('should return true for a perfect cube', () => {
|
||||
expect(perfectCube(125)).toBeTruthy()
|
||||
})
|
||||
it('should return false for a non perfect cube', () => {
|
||||
expect(perfectCube(100)).toBeFalsy()
|
||||
})
|
||||
})
|
10
Maths/test/PerfectNumber.test.js
Normal file
10
Maths/test/PerfectNumber.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { perfectNumber } from '../PerfectNumber'
|
||||
|
||||
describe('PerfectNumber', () => {
|
||||
it('should return true for a perfect cube', () => {
|
||||
expect(perfectNumber(28)).toBeTruthy()
|
||||
})
|
||||
it('should return false for a non perfect cube', () => {
|
||||
expect(perfectNumber(10)).toBeFalsy()
|
||||
})
|
||||
})
|
10
Maths/test/PerfectSquare.test.js
Normal file
10
Maths/test/PerfectSquare.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { perfectSquare } from '../PerfectSquare'
|
||||
|
||||
describe('PerfectSquare', () => {
|
||||
it('should return true for a perfect cube', () => {
|
||||
expect(perfectSquare(16)).toBeTruthy()
|
||||
})
|
||||
it('should return false for a non perfect cube', () => {
|
||||
expect(perfectSquare(10)).toBeFalsy()
|
||||
})
|
||||
})
|
9
Maths/test/PiApproximationMonteCarlo.test.js
Normal file
9
Maths/test/PiApproximationMonteCarlo.test.js
Normal file
@ -0,0 +1,9 @@
|
||||
import { piEstimation } from '../PiApproximationMonteCarlo'
|
||||
|
||||
describe('PiApproximationMonteCarlo', () => {
|
||||
it('should be between the range of 2 to 4', () => {
|
||||
const pi = piEstimation()
|
||||
const piRange = pi >= 2 && pi <= 4
|
||||
expect(piRange).toBeTruthy()
|
||||
})
|
||||
})
|
37
Maths/test/Polynomial.test.js
Normal file
37
Maths/test/Polynomial.test.js
Normal file
@ -0,0 +1,37 @@
|
||||
import { Polynomial } from '../Polynomial'
|
||||
|
||||
describe('Polynomial', () => {
|
||||
it('should not return a expression for zero', () => {
|
||||
const polynomial = new Polynomial([0])
|
||||
expect(polynomial.display()).toBe('')
|
||||
})
|
||||
it('should not return an expression for zero values', () => {
|
||||
const polynomial = new Polynomial([0, 0, 0, 0, 0])
|
||||
expect(polynomial.display()).toBe('')
|
||||
})
|
||||
it('should return an expression for single a non zero value', () => {
|
||||
const polynomial = new Polynomial([9])
|
||||
expect(polynomial.display()).toBe('(9)')
|
||||
})
|
||||
it('should return an expression for two values', () => {
|
||||
const polynomial = new Polynomial([3, 2])
|
||||
expect(polynomial.display()).toBe('(2x) + (3)')
|
||||
})
|
||||
it('should return an expression for values including zero', () => {
|
||||
const polynomial = new Polynomial([0, 2])
|
||||
expect(polynomial.display()).toBe('(2x)')
|
||||
})
|
||||
it('should return an expression and evaluate it', () => {
|
||||
const polynomial = new Polynomial([1, 2, 3, 4])
|
||||
expect(polynomial.display()).toBe('(4x^3) + (3x^2) + (2x) + (1)')
|
||||
expect(polynomial.evaluate(2)).toEqual(49)
|
||||
})
|
||||
it('should evaluate 0 for zero values', () => {
|
||||
const polynomial = new Polynomial([0, 0, 0, 0])
|
||||
expect(polynomial.evaluate(5)).toEqual(0)
|
||||
})
|
||||
it('should evaluate for negative values', () => {
|
||||
const polynomial = new Polynomial([-1, -3, -4, -7])
|
||||
expect(polynomial.evaluate(-5)).toBe(789)
|
||||
})
|
||||
})
|
14
Maths/test/PrimeCheck.test.js
Normal file
14
Maths/test/PrimeCheck.test.js
Normal file
@ -0,0 +1,14 @@
|
||||
import { PrimeCheck } from '../PrimeCheck'
|
||||
|
||||
describe('PrimeCheck', () => {
|
||||
it('should return true for Prime Numbers', () => {
|
||||
expect(PrimeCheck(1000003)).toBeTruthy()
|
||||
})
|
||||
it('should return false for Non Prime Numbers', () => {
|
||||
expect(PrimeCheck(1000001)).toBeFalsy()
|
||||
})
|
||||
it('should return false for 1 and 0', () => {
|
||||
expect(PrimeCheck(1)).toBeFalsy()
|
||||
expect(PrimeCheck(0)).toBeFalsy()
|
||||
})
|
||||
})
|
11
Maths/test/ReversePolishNotation.test.js
Normal file
11
Maths/test/ReversePolishNotation.test.js
Normal file
@ -0,0 +1,11 @@
|
||||
import { calcRPN } from '../ReversePolishNotation'
|
||||
|
||||
describe('ReversePolishNotation', () => {
|
||||
it('should evaluate correctly for two values', () => {
|
||||
expect(calcRPN('2 3 +')).toEqual(5)
|
||||
})
|
||||
it("should evaluate' for multiple values", () => {
|
||||
expect(calcRPN('2 2 2 * +')).toEqual(6)
|
||||
expect(calcRPN('6 9 7 + 2 / + 3 *')).toEqual(42)
|
||||
})
|
||||
})
|
14
Maths/test/SieveOfEratosthenes.test.js
Normal file
14
Maths/test/SieveOfEratosthenes.test.js
Normal file
@ -0,0 +1,14 @@
|
||||
import { sieveOfEratosthenes } from '../SieveOfEratosthenes'
|
||||
import { PrimeCheck } from '../PrimeCheck'
|
||||
|
||||
describe('should return an array of prime booleans', () => {
|
||||
it('should have each element in the array as a prime boolean', () => {
|
||||
const n = 30
|
||||
const primes = sieveOfEratosthenes(n)
|
||||
primes.forEach((primeBool, index) => {
|
||||
if (primeBool) {
|
||||
expect(PrimeCheck(index)).toBeTruthy()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
32
Navigation/Haversine.js
Normal file
32
Navigation/Haversine.js
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
Calculate the distance between two coordinates using the haversine formula
|
||||
More about: https://pt.wikipedia.org/wiki/F%C3%B3rmula_de_Haversine
|
||||
@Param {number} latitude1
|
||||
@Param {number} latitude2
|
||||
@Param {number} longitude1
|
||||
@Param {number} longitude2
|
||||
*/
|
||||
const haversineDistance = (latitude1 = 0, longitude1 = 0, latitude2 = 0, longitude2 = 0) => {
|
||||
validateLatOrLong(latitude1)
|
||||
validateLatOrLong(latitude2)
|
||||
validateLatOrLong(longitude1)
|
||||
validateLatOrLong(longitude2)
|
||||
const earthRadius = 6371e3 // 6,371km
|
||||
const pi = Math.PI
|
||||
const cos1 = latitude1 * pi / 180.0
|
||||
const cos2 = latitude2 * pi / 180.0
|
||||
const deltaLatitude = (latitude2 - latitude1) * pi / 180.0
|
||||
const deltaLongitude = (longitude2 - longitude1) * pi / 180.0
|
||||
|
||||
const alpha = Math.sin(deltaLatitude / 2) * Math.sin(deltaLatitude / 2) + Math.cos(cos1) * Math.cos(cos2) * Math.sin(deltaLongitude / 2) * Math.sin(deltaLongitude / 2)
|
||||
const constant = 2 * Math.atan2(Math.sqrt(alpha), Math.sqrt(1 - alpha))
|
||||
return earthRadius * constant
|
||||
}
|
||||
|
||||
const validateLatOrLong = value => {
|
||||
if (typeof value !== 'number') {
|
||||
throw new TypeError('The value of latitude or longitude should be a number')
|
||||
}
|
||||
}
|
||||
|
||||
export { haversineDistance }
|
11
Navigation/Haversine.test.js
Normal file
11
Navigation/Haversine.test.js
Normal file
@ -0,0 +1,11 @@
|
||||
import { haversineDistance } from './Haversine'
|
||||
|
||||
describe('Testing the haversine distance calculator', () => {
|
||||
it('Calculate distance', () => {
|
||||
const distance = haversineDistance(64.1265, -21.8174, 40.7128, -74.0060)
|
||||
expect(distance).toBe(4208198.758424171)
|
||||
})
|
||||
it('Test validation, expect throw', () => {
|
||||
expect(() => haversineDistance(64.1265, -21.8174, 40.7128, '74.0060')).toThrow()
|
||||
})
|
||||
})
|
27
Project-Euler/Problem1.js
Normal file
27
Project-Euler/Problem1.js
Normal file
@ -0,0 +1,27 @@
|
||||
// https://projecteuler.net/problem=1
|
||||
/* Multiples of 3 and 5
|
||||
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.
|
||||
Find the sum of all the multiples of 3 or 5 below the provided parameter value number.
|
||||
*/
|
||||
|
||||
const readline = require('readline')
|
||||
|
||||
const multiplesThreeAndFive = (num) => {
|
||||
let total = 0
|
||||
// total for calculating the sum
|
||||
for (let i = 0; i < num; i++) {
|
||||
if (i % 3 === 0 || i % 5 === 0) {
|
||||
total += i
|
||||
}
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
})
|
||||
rl.question('Enter a number: ', function (num) {
|
||||
console.log(multiplesThreeAndFive(num)) // multiples3_5 function to calculate the sum of multiples of 3 and 5 within num
|
||||
rl.close()
|
||||
})
|
13
Project-Euler/Problem2.js
Normal file
13
Project-Euler/Problem2.js
Normal file
@ -0,0 +1,13 @@
|
||||
// https://projecteuler.net/problem=2
|
||||
const SQ5 = 5 ** 0.5 // Square root of 5
|
||||
const PHI = (1 + SQ5) / 2 // definition of PHI
|
||||
|
||||
// theoretically it should take O(1) constant amount of time as long
|
||||
// arithmetic calculations are considered to be in constant amount of time
|
||||
const EvenFibonacci = (limit) => {
|
||||
const highestIndex = Math.floor(Math.log(limit * SQ5) / Math.log(PHI))
|
||||
const n = Math.floor(highestIndex / 3)
|
||||
return ((PHI ** (3 * n + 3) - 1) / (PHI ** 3 - 1) -
|
||||
((1 - PHI) ** (3 * n + 3) - 1) / ((1 - PHI) ** 3 - 1)) / SQ5
|
||||
}
|
||||
console.log(EvenFibonacci(4e6)) // Sum of even Fibonacci upto 4 Million
|
20
Project-Euler/Problem3.js
Normal file
20
Project-Euler/Problem3.js
Normal file
@ -0,0 +1,20 @@
|
||||
// https://projecteuler.net/problem=3
|
||||
const problem = 600851475143
|
||||
|
||||
const largestPrime = (num) => {
|
||||
let newnumm = num
|
||||
let largestFact = 0
|
||||
let counter = 2
|
||||
while (counter * counter <= newnumm) {
|
||||
if (newnumm % counter === 0) {
|
||||
newnumm = newnumm / counter
|
||||
} else {
|
||||
counter++
|
||||
}
|
||||
}
|
||||
if (newnumm > largestFact) {
|
||||
largestFact = newnumm
|
||||
}
|
||||
return largestFact
|
||||
}
|
||||
console.log(largestPrime(problem))
|
46
Project-Euler/Problem4.js
Normal file
46
Project-Euler/Problem4.js
Normal file
@ -0,0 +1,46 @@
|
||||
// https://projecteuler.net/problem=4
|
||||
/* A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
|
||||
Find the largest palindrome made from the product of two 3-digit numbers.
|
||||
*/
|
||||
const largestPalindromic = (digits) => {
|
||||
let i
|
||||
let n
|
||||
let m
|
||||
let d
|
||||
let limit
|
||||
let number = 0
|
||||
|
||||
for (i = 1; i < digits; i++) {
|
||||
number = 10 * number + 9
|
||||
}
|
||||
const inf = number // highest (digits - 1) number, in this example highest 2 digit number
|
||||
const sup = 10 * number + 9 // highest (digits) number, in this example highest 3 digit number
|
||||
|
||||
const isPalindromic = (n) => {
|
||||
let p = 0
|
||||
const q = n
|
||||
let r
|
||||
while (n > 0) {
|
||||
r = n % 10
|
||||
p = 10 * p + r
|
||||
n = Math.floor(n / 10)
|
||||
}
|
||||
return p === q // returning whether the number is palindromic or not
|
||||
}
|
||||
|
||||
for (n = sup * sup, m = inf * inf; n > m; n--) {
|
||||
if (isPalindromic(n)) {
|
||||
limit = Math.ceil(Math.sqrt(n))
|
||||
d = sup
|
||||
while (d >= limit) {
|
||||
if (n % d === 0 && n / d > inf) {
|
||||
return n
|
||||
}
|
||||
d -= 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return NaN // returning not a number, if any such case arise
|
||||
}
|
||||
|
||||
console.log(largestPalindromic(3))
|
15
Project-Euler/Problem6.js
Normal file
15
Project-Euler/Problem6.js
Normal file
@ -0,0 +1,15 @@
|
||||
// https://projecteuler.net/problem=6
|
||||
|
||||
const num = 100 // number we are checking; change to 10 to check 10 from example
|
||||
|
||||
const squareDifference = (num) => {
|
||||
let sumOfSquares = 0
|
||||
let sums = 0
|
||||
for (let i = 1; i <= num; i++) {
|
||||
sumOfSquares += i ** 2 // add squares to the sum of squares
|
||||
sums += i // add number to sum to square later
|
||||
}
|
||||
return (sums ** 2) - sumOfSquares // difference of square of the total sum and sum of squares
|
||||
}
|
||||
|
||||
console.log(squareDifference(num))
|
31
Project-Euler/Problem7.js
Normal file
31
Project-Euler/Problem7.js
Normal file
@ -0,0 +1,31 @@
|
||||
// https://projecteuler.net/problem=7
|
||||
// My approach does not use the Sieve of Eratosthenes but that is another common way to approach this problem. Sieve of Atkin is another possibility as well.
|
||||
|
||||
const num = 10001
|
||||
const primes = [2, 3, 5, 7, 11, 13] // given list of primes you start with
|
||||
|
||||
const calculatePrime = (num) => {
|
||||
// Calculate each next prime by checking each number to see what it's divisible by
|
||||
let count = primes.length // count number of primes calculated
|
||||
let current = primes[count - 1] + 1 // current number being assessed if prime
|
||||
while (count < num) { // repeat while we haven't reached goal number of primes
|
||||
// go through each prime and see if divisible by the previous primes
|
||||
let prime = false
|
||||
primes.some((n, i) => {
|
||||
if (current % n === 0) {
|
||||
return true
|
||||
}
|
||||
if (i === count - 1) {
|
||||
prime = true
|
||||
}
|
||||
})
|
||||
if (prime) { // if prime, add to prime list and increment count
|
||||
primes.push(current)
|
||||
count += 1
|
||||
}
|
||||
current += 1
|
||||
}
|
||||
return primes[num - 1]
|
||||
}
|
||||
|
||||
console.log(calculatePrime(num))
|
29
Recursive/BinarySearch.js
Normal file
29
Recursive/BinarySearch.js
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
// https://en.wikipedia.org/wiki/Binary_search_algorithm
|
||||
// Search the integer inside the sorted integers array using Binary Search Algorithm
|
||||
|
||||
const BinarySearch = (intArr, searchQuery) => {
|
||||
if (searchQuery === null || searchQuery === undefined || intArr.length === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
const middleIndex = intArr.length === 1 ? 0 : Math.ceil(intArr.length / 2)
|
||||
|
||||
if (intArr[middleIndex] === searchQuery) {
|
||||
return true
|
||||
} else if (intArr.length > 1) {
|
||||
return intArr[middleIndex] < searchQuery ? BinarySearch(intArr.slice(1, middleIndex)) : BinarySearch(intArr.slice(middleIndex))
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// testing
|
||||
(() => {
|
||||
console.log('Number Present with odd array length: 5 = ', BinarySearch([1, 2, 3, 4, 5, 6, 7], 5))
|
||||
console.log('Number Present with even array length: 5 = ', BinarySearch([1, 2, 4, 5, 6], 5))
|
||||
console.log('Number Present with only single element: 5 = ', BinarySearch([5], 5))
|
||||
console.log('Number Not Present: 0 = ', BinarySearch([1, 2, 3, 4, 5], 0))
|
||||
console.log('Undefined number search query = ', BinarySearch([1, 2, 3, 4, 5]))
|
||||
console.log('With Empty array = ', BinarySearch([], 1))
|
||||
})()
|
13
Recursive/FibonacciNumberRecursive.js
Normal file
13
Recursive/FibonacciNumberRecursive.js
Normal file
@ -0,0 +1,13 @@
|
||||
// https://en.wikipedia.org/wiki/Fibonacci_number
|
||||
|
||||
const fibonacci = (N) => {
|
||||
if (N === 0 || N === 1) return N
|
||||
|
||||
return fibonacci(N - 2) + fibonacci(N - 1)
|
||||
}
|
||||
|
||||
// testing
|
||||
(() => {
|
||||
const number = 5
|
||||
console.log(number + 'th Fibonacci number is ' + fibonacci(number))
|
||||
})()
|
30
Recursive/Palindrome.js
Normal file
30
Recursive/Palindrome.js
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
// Check whether the given string is Palindrome or not
|
||||
const Palindrome = (str) => {
|
||||
if (typeof str !== 'string') {
|
||||
str = str.toString()
|
||||
}
|
||||
|
||||
if (str === null || str === undefined) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (str.length === 1 || str.length === 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (str[0] !== str[str.length - 1]) {
|
||||
return false
|
||||
} else {
|
||||
return Palindrome(str.slice(1, str.length - 1))
|
||||
}
|
||||
};
|
||||
|
||||
// testing
|
||||
(() => {
|
||||
console.log('Palindrome: String: a = ', Palindrome('a'))
|
||||
console.log('Palindrome: String: abba = ', Palindrome('abba'))
|
||||
console.log('Palindrome: String: ababa = ', Palindrome('ababa'))
|
||||
console.log('Not Palindrome: String: abbxa = ', Palindrome('abbxa'))
|
||||
console.log('Not Palindrome: String: abxa = ', Palindrome('abxa'))
|
||||
})()
|
16
Recursive/factorial.js
Normal file
16
Recursive/factorial.js
Normal file
@ -0,0 +1,16 @@
|
||||
// function to find factorial using recursion
|
||||
// example :
|
||||
// 5! = 1*2*3*4*5 = 120
|
||||
// 2! = 1*2 = 2
|
||||
|
||||
const factorial = (n) => {
|
||||
if (n === 0) {
|
||||
return 1
|
||||
}
|
||||
return n * factorial(n - 1)
|
||||
}
|
||||
|
||||
// testing
|
||||
console.log(factorial(4))
|
||||
console.log(factorial(15))
|
||||
console.log(factorial(0))
|
77
Search/FibonacciSearch.js
Normal file
77
Search/FibonacciSearch.js
Normal file
@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
* Fibonacci Search JavaScript Implementation
|
||||
* Author Alhassan Atama Isiaka
|
||||
* Version v1.0.0
|
||||
* Copyright 2020
|
||||
* https://github.com/komputarist
|
||||
*
|
||||
* This implementation is based on Generalizing the Fibonacci search we
|
||||
* define the Fibonacci search of degree K. Like the Fibonacci search,
|
||||
* which it reduces to for K = 2, the Fibonacci search of degree K
|
||||
* involves only addition and subtraction.
|
||||
* Capocelli R.M. (1991) A Generalization of the Fibonacci Search. In:
|
||||
* Bergum G.E., Philippou A.N., Horadam A.F. (eds) Applications of Fibonacci
|
||||
* Numbers. Springer, Dordrecht. https://doi.org/10.1007/978-94-011-3586-3_9
|
||||
*
|
||||
* This snippet is free. Feel free to improve on it
|
||||
*
|
||||
* We define a function fibonacciSearch() that takes an array of numbers,
|
||||
* the item (number) to be searched for and the length of the items in the array
|
||||
****************************************************************************/
|
||||
|
||||
const fibonacciSearch = (arr, x, n) => {
|
||||
let fib2 = 0 // (K-2)'th Fibonacci Number
|
||||
let fib1 = 1 // (K-1)'th Fibonacci Number.
|
||||
let fibK = fib2 + fib1 // Kth Fibonacci
|
||||
|
||||
/* We want to store the smallest fibonacci number smaller such that
|
||||
number is greater than or equal to n, we use fibK for this */
|
||||
while (fibK < n) {
|
||||
fib2 = fib1
|
||||
fib1 = fibK
|
||||
fibK = fib2 + fib1
|
||||
}
|
||||
// This marks the eliminated range from front
|
||||
let offset = -1
|
||||
|
||||
/* while there are elements to be checked. We compare arr[fib2] with x.
|
||||
When fibM becomes 1, fib2 becomes 0 */
|
||||
|
||||
while (fibK > 1) {
|
||||
// Check if fibK is a valid location
|
||||
const i = Math.min(offset + fib2, n - 1)
|
||||
|
||||
/* If x is greater than the value at
|
||||
index fib2, Partition the subarray array
|
||||
from offset to i */
|
||||
if (arr[i] < x) {
|
||||
fibK = fib1
|
||||
fib1 = fib2
|
||||
fib2 = fibK - fib1
|
||||
offset = i
|
||||
/* If x is greater than the value at
|
||||
index fib2, cut the subarray array
|
||||
from offset to i */
|
||||
} else if (arr[i] > x) {
|
||||
fibK = fib2
|
||||
fib1 = fib1 - fib2
|
||||
fib2 = fibK - fib1
|
||||
} else {
|
||||
// return index for found element
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
// comparing the last element with x */
|
||||
if (fib1 && arr[offset + 1] === x) {
|
||||
return offset + 1
|
||||
}
|
||||
// element not found. return -1
|
||||
return -1
|
||||
}
|
||||
// Example
|
||||
const myArray = [10, 22, 35, 40, 45, 50, 80, 82, 85, 90, 100]
|
||||
const n = myArray.length
|
||||
const x = 90
|
||||
const fibFinder = fibonacciSearch(myArray, x, n)
|
||||
console.log('Element found at index:', fibFinder)
|
83
Search/StringSearch.js
Normal file
83
Search/StringSearch.js
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* String Search
|
||||
*/
|
||||
|
||||
function makeTable (str) {
|
||||
// create a table of size equal to the length of `str`
|
||||
// table[i] will store the prefix of the longest prefix of the substring str[0..i]
|
||||
const table = new Array(str.length)
|
||||
let maxPrefix = 0
|
||||
// the longest prefix of the substring str[0] has length
|
||||
table[0] = 0
|
||||
|
||||
// for the substrings the following substrings, we have two cases
|
||||
for (let i = 1; i < str.length; i++) {
|
||||
// case 1. the current character doesn't match the last character of the longest prefix
|
||||
while (maxPrefix > 0 && str.charAt(i) !== str.charAt(maxPrefix)) {
|
||||
// if that is the case, we have to backtrack, and try find a character that will be equal to the current character
|
||||
// if we reach 0, then we couldn't find a chracter
|
||||
maxPrefix = table[maxPrefix - 1]
|
||||
}
|
||||
// case 2. The last character of the longest prefix matches the current character in `str`
|
||||
if (str.charAt(maxPrefix) === str.charAt(i)) {
|
||||
// if that is the case, we know that the longest prefix at position i has one more character.
|
||||
// for example consider `.` be any character not contained in the set [a.c]
|
||||
// str = abc....abc
|
||||
// consider `i` to be the last character `c` in `str`
|
||||
// maxPrefix = will be 2 (the first `c` in `str`)
|
||||
// maxPrefix now will be 3
|
||||
maxPrefix++
|
||||
// so the max prefix for table[9] is 3
|
||||
}
|
||||
table[i] = maxPrefix
|
||||
}
|
||||
return table
|
||||
}
|
||||
|
||||
// Find all the words that matches in a given string `str`
|
||||
function stringSearch (str, word) {
|
||||
// find the prefix table in O(n)
|
||||
const prefixes = makeTable(word)
|
||||
const matches = []
|
||||
|
||||
// `j` is the index in `P`
|
||||
let j = 0
|
||||
// `i` is the index in `S`
|
||||
let i = 0
|
||||
while (i < str.length) {
|
||||
// Case 1. S[i] == P[j] so we move to the next index in `S` and `P`
|
||||
if (str.charAt(i) === word.charAt(j)) {
|
||||
i++
|
||||
j++
|
||||
}
|
||||
// Case 2. `j` is equal to the length of `P`
|
||||
// that means that we reached the end of `P` and thus we found a match
|
||||
// Next we have to update `j` because we want to save some time
|
||||
// instead of updating to j = 0 , we can jump to the last character of the longest prefix well known so far.
|
||||
// j-1 means the last character of `P` because j is actually `P.length`
|
||||
// e.g.
|
||||
// S = a b a b d e
|
||||
// P = `a b`a b
|
||||
// we will jump to `a b` and we will compare d and a in the next iteration
|
||||
// a b a b `d` e
|
||||
// a b `a` b
|
||||
if (j === word.length) {
|
||||
matches.push(i - j)
|
||||
j = prefixes[j - 1]
|
||||
// Case 3.
|
||||
// S[i] != P[j] There's a mismatch!
|
||||
} else if (str.charAt(i) !== word.charAt(j)) {
|
||||
// if we found at least a character in common, do the same thing as in case 2
|
||||
if (j !== 0) {
|
||||
j = prefixes[j - 1]
|
||||
} else {
|
||||
// else j = 0, and we can move to the next character S[i+1]
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matches
|
||||
}
|
||||
|
||||
console.log(stringSearch('Hello search the position of me', 'pos'))
|
69
Sorts/BeadSort.js
Normal file
69
Sorts/BeadSort.js
Normal file
@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Bead sort (also known as Gravity sort)
|
||||
* https://en.wikipedia.org/wiki/Bead_sort
|
||||
*
|
||||
* Does counting sort of provided array according to
|
||||
* the digit represented by exp.
|
||||
* Only works for arrays of positive integers.
|
||||
*/
|
||||
|
||||
// > beadSort([-1, 5, 8, 4, 3, 19])
|
||||
// ! RangeError: Sequence must be a list of positive integers!
|
||||
// > beadSort([5, 4, 3, 2, 1])
|
||||
// [1, 2, 3, 4, 5]
|
||||
// > beadSort([7, 9, 4, 3, 5])
|
||||
// [3, 4, 5, 7, 9]
|
||||
|
||||
function beadSort (sequence) {
|
||||
// first, let's check that our sequence consists
|
||||
// of positive integers
|
||||
if (sequence.some((integer) => integer < 0)) {
|
||||
throw RangeError('Sequence must be a list of positive integers!')
|
||||
}
|
||||
|
||||
const sequenceLength = sequence.length
|
||||
const max = Math.max(...sequence)
|
||||
|
||||
// set initial grid
|
||||
const grid = sequence.map(number => {
|
||||
const maxArr = new Array(max)
|
||||
|
||||
for (let i = 0; i < number; i++) {
|
||||
maxArr[i] = '*'
|
||||
}
|
||||
|
||||
return maxArr
|
||||
})
|
||||
|
||||
// drop the beads!
|
||||
for (let col = 0; col < max; col++) {
|
||||
let beadsCount = 0
|
||||
|
||||
for (let row = 0; row < sequenceLength; row++) {
|
||||
if (grid[row][col] === '*') {
|
||||
beadsCount++
|
||||
}
|
||||
}
|
||||
|
||||
for (let row = sequenceLength - 1; row > -1; row--) {
|
||||
if (beadsCount) {
|
||||
grid[row][col] = '*'
|
||||
beadsCount--
|
||||
} else {
|
||||
grid[row][col] = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// and, finally, let's turn our bead rows into their respective numbers
|
||||
const sortedSequence = grid.map((beadArray) => {
|
||||
const beadsArray = beadArray.filter(bead => bead === '*')
|
||||
|
||||
return beadsArray.length
|
||||
})
|
||||
|
||||
return sortedSequence
|
||||
}
|
||||
|
||||
// implementation
|
||||
console.log(beadSort([5, 4, 3, 2, 1]))
|
@ -1,11 +1,40 @@
|
||||
/* Bubble Sort is a algorithm to sort an array. It
|
||||
* compares adjacent element and swaps thier position
|
||||
* The big O on bubble sort in worst and best case is O(N^2).
|
||||
* Not efficient.
|
||||
/* Bubble Sort is an algorithm to sort an array. It
|
||||
* compares adjacent element and swaps thier position
|
||||
* The big O on bubble sort in worst and best case is O(N^2).
|
||||
* Not efficient.
|
||||
*
|
||||
* In bubble sort, we keep iterating while something was swapped in
|
||||
* the previous inner-loop iteration. By swapped I mean, in the
|
||||
* inner loop iteration, we check each number if the number proceeding
|
||||
* it is greater than itself, if so we swap them.
|
||||
*
|
||||
* Wikipedia: https://en.wikipedia.org/wiki/Bubble_sort
|
||||
*/
|
||||
|
||||
/*
|
||||
* Doctests
|
||||
*
|
||||
* > bubbleSort([5, 4, 1, 2, 3])
|
||||
* [1, 2, 3, 4, 5]
|
||||
* > bubbleSort([])
|
||||
* []
|
||||
* > bubbleSort([1, 2, 3])
|
||||
* [1, 2, 3]
|
||||
*
|
||||
* > alternativeBubbleSort([5, 4, 1, 2, 3])
|
||||
* [1, 2, 3, 4, 5]
|
||||
* > alternativeBubbleSort([])
|
||||
* []
|
||||
* > alternativeBubbleSort([1, 2, 3])
|
||||
* [1, 2, 3]
|
||||
*/
|
||||
|
||||
/*
|
||||
* Using 2 for loops
|
||||
*/
|
||||
function bubbleSort (items) {
|
||||
const length = items.length
|
||||
|
||||
for (let i = (length - 1); i > 0; i--) {
|
||||
// Number of passes
|
||||
for (let j = (length - i); j > 0; j--) {
|
||||
@ -16,31 +45,28 @@ function bubbleSort (items) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
// Implementation of bubbleSort
|
||||
|
||||
var ar = [5, 6, 7, 8, 1, 2, 12, 14]
|
||||
// Array before Sort
|
||||
console.log('-----before sorting-----')
|
||||
console.log(ar)
|
||||
bubbleSort(ar)
|
||||
// Array after sort
|
||||
console.log('-----after sorting-----')
|
||||
console.log(ar)
|
||||
|
||||
/* alternative implementation of bubble sort algorithm.
|
||||
Using a while loop instead. For educational purposses only
|
||||
*/
|
||||
/*
|
||||
*In bubble sort, we keep iterating while something was swapped in
|
||||
*the previous inner-loop iteration. By swapped I mean, in the
|
||||
*inner loop iteration, we check each number if the number proceeding
|
||||
*it is greater than itself, if so we swap them.
|
||||
* Implementation of 2 for loops method
|
||||
*/
|
||||
var array1 = [5, 6, 7, 8, 1, 2, 12, 14]
|
||||
// Before Sort
|
||||
console.log('\n- Before Sort | Implementation using 2 for loops -')
|
||||
console.log(array1)
|
||||
// After Sort
|
||||
console.log('- After Sort | Implementation using 2 for loops -')
|
||||
console.log(bubbleSort(array1))
|
||||
console.log('\n')
|
||||
|
||||
/*
|
||||
* Using a while loop and a for loop
|
||||
*/
|
||||
function alternativeBubbleSort (arr) {
|
||||
let swapped = true
|
||||
|
||||
while (swapped) {
|
||||
swapped = false
|
||||
for (let i = 0; i < arr.length - 1; i++) {
|
||||
@ -50,12 +76,18 @@ function alternativeBubbleSort (arr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return arr
|
||||
}
|
||||
|
||||
// test
|
||||
console.log('-----before sorting-----')
|
||||
var array = [10, 5, 3, 8, 2, 6, 4, 7, 9, 1]
|
||||
console.log(array)
|
||||
console.log('-----after sorting-----')
|
||||
console.log(alternativeBubbleSort(array))
|
||||
/*
|
||||
* Implementation of a while loop and a for loop method
|
||||
*/
|
||||
var array2 = [5, 6, 7, 8, 1, 2, 12, 14]
|
||||
// Before Sort
|
||||
console.log('\n- Before Sort | Implementation using a while loop and a for loop -')
|
||||
console.log(array2)
|
||||
// After Sort
|
||||
console.log('- After Sort | Implementation using a while loop and a for loop -')
|
||||
console.log(alternativeBubbleSort(array2))
|
||||
console.log('\n')
|
||||
|
@ -13,6 +13,27 @@
|
||||
* @param {Array} list2 - sublist to break down
|
||||
* @return {Array} merged list
|
||||
*/
|
||||
/*
|
||||
* Doctests
|
||||
* > merge([5, 4],[ 1, 2, 3])
|
||||
* [1, 2, 3, 5, 4]
|
||||
* > merge([],[1, 2])
|
||||
* [1, 2]
|
||||
* > merge([1, 2, 3], [1])
|
||||
* [1, 1, 2, 3]
|
||||
* > merge([], [])
|
||||
* []
|
||||
*
|
||||
* > mergeSort([5, 4])
|
||||
* [4, 5]
|
||||
* > mergeSort([8, 4, 10, 15, 9])
|
||||
* [4, 8, 9, 10, 15]
|
||||
* > mergeSort([1, 2, 3])
|
||||
* [1, 2, 3]
|
||||
* > mergeSort([ ])
|
||||
* [ ]
|
||||
*/
|
||||
|
||||
function merge (list1, list2) {
|
||||
var results = []
|
||||
|
||||
|
@ -2,6 +2,20 @@
|
||||
* Quick sort is a comparison sorting algorithm that uses a divide and conquer strategy.
|
||||
* For more information see here: https://en.wikipedia.org/wiki/Quicksort
|
||||
*/
|
||||
|
||||
/*
|
||||
* Doctests
|
||||
*
|
||||
* > quickSort([5, 4, 3, 10, 2, 1])
|
||||
* [1, 2, 3, 4, 5, 10]
|
||||
* > quickSort([])
|
||||
* []
|
||||
* > quickSort([5, 4])
|
||||
* [4, 5]
|
||||
* > quickSort([1, 2, 3])
|
||||
* [1, 2, 3]
|
||||
*/
|
||||
|
||||
function quickSort (items) {
|
||||
var length = items.length
|
||||
|
||||
|
@ -8,12 +8,19 @@
|
||||
*from the unsorted subarray is picked and moved to the sorted subarray.
|
||||
*/
|
||||
|
||||
function selectionSort (items) {
|
||||
var length = items.length
|
||||
for (var i = 0; i < length - 1; i++) {
|
||||
const selectionSort = (list) => {
|
||||
if (!Array.isArray(list)) {
|
||||
throw new TypeError('Given input is not an array')
|
||||
}
|
||||
const items = [...list] // We don't want to modify the original array
|
||||
const length = items.length
|
||||
for (let i = 0; i < length - 1; i++) {
|
||||
if (typeof items[i] !== 'number') {
|
||||
throw new TypeError('One of the items in your array is not a number')
|
||||
}
|
||||
// Number of passes
|
||||
var min = i // min holds the current minimum number position for each pass; i holds the Initial min number
|
||||
for (var j = i + 1; j < length; j++) { // Note that j = i + 1 as we only need to go through unsorted array
|
||||
let min = i // min holds the current minimum number position for each pass; i holds the Initial min number
|
||||
for (let j = i + 1; j < length; j++) { // Note that j = i + 1 as we only need to go through unsorted array
|
||||
if (items[j] < items[min]) { // Compare the numbers
|
||||
min = j // Change the current min number position if a smaller num is found
|
||||
}
|
||||
@ -21,16 +28,23 @@ function selectionSort (items) {
|
||||
if (min !== i) {
|
||||
// After each pass, if the current min num != initial min num, exchange the position.
|
||||
// Swap the numbers
|
||||
[items[i], items[min]] = [items[min], [items[i]]]
|
||||
[items[i], items[min]] = [items[min], items[i]]
|
||||
}
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
// Implementation of Selection Sort
|
||||
/* Implementation of Selection Sort
|
||||
|
||||
var ar = [5, 6, 7, 8, 1, 2, 12, 14]
|
||||
// Array before Sort
|
||||
console.log(ar)
|
||||
selectionSort(ar)
|
||||
// Array after sort
|
||||
console.log(ar)
|
||||
(() => {
|
||||
let array = [5, 6, 7, 8, 1, 2, 12, 14]
|
||||
// Array before Sort
|
||||
console.log(array)
|
||||
array = selectionSort(array)
|
||||
// Array after sort
|
||||
console.log(array)
|
||||
})()
|
||||
|
||||
*/
|
||||
|
||||
export { selectionSort }
|
||||
|
22
Sorts/SelectionSort.test.js
Normal file
22
Sorts/SelectionSort.test.js
Normal file
@ -0,0 +1,22 @@
|
||||
import { selectionSort } from './SelectionSort'
|
||||
|
||||
describe('selectionSort', () => {
|
||||
it('expects to return the array sorted in ascending order', () => {
|
||||
var toSort = [5, 6, 7, 8, 1, 2, 12, 14]
|
||||
const expected = [1, 2, 5, 6, 7, 8, 12, 14]
|
||||
|
||||
expect(selectionSort(toSort)).toEqual(expected)
|
||||
})
|
||||
|
||||
it('expects to throw if it is not a valid array', () => {
|
||||
expect(() => selectionSort('abc')).toThrow('Given input is not an array')
|
||||
expect(() => selectionSort(123)).toThrow('Given input is not an array')
|
||||
expect(() => selectionSort({})).toThrow('Given input is not an array')
|
||||
expect(() => selectionSort(null)).toThrow('Given input is not an array')
|
||||
expect(() => selectionSort()).toThrow('Given input is not an array')
|
||||
})
|
||||
|
||||
it('expects to throw if one of the elements in the array is not a number', () => {
|
||||
expect(() => selectionSort([1, 'x', 2])).toThrow('One of the items in your array is not a number')
|
||||
})
|
||||
})
|
110
Sorts/TimSort.js
Normal file
110
Sorts/TimSort.js
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @function Timsort is a hybrid stable sorting algorithm, derived from merge sort and insertion sort,
|
||||
* designed to perform well on many kinds of real-world data.
|
||||
* It was implemented by Tim Peters in 2002 for use in the Python programming language.
|
||||
* It is also used to sort arrays of non-primitive type in Java SE 7,
|
||||
* on the Android platform, in GNU Octave, on V8, Swift and Rust.
|
||||
* 1) It sorts small partitions using Insertion Sort.
|
||||
* 2) Merges the partition using Merge Sort.
|
||||
* @see [Timsort](https://en.wikipedia.org/wiki/Timsort)
|
||||
* @param {Array} array
|
||||
*/
|
||||
|
||||
const Timsort = (array) => {
|
||||
// Default size of a partition
|
||||
const RUN = 32
|
||||
const n = array.length
|
||||
// Sorting the partitions using Insertion Sort
|
||||
for (let i = 0; i < n; i += RUN) {
|
||||
InsertionSort(array, i, Math.min(i + RUN - 1, n - 1))
|
||||
}
|
||||
for (let size = RUN; size < n; size *= 2) {
|
||||
for (let left = 0; left < n; left += 2 * size) {
|
||||
const mid = left + size - 1
|
||||
const right = Math.min(left + 2 * size - 1, n - 1)
|
||||
Merge(array, left, mid, right)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function performs insertion sort on the partition
|
||||
* @param {Array} array array to be sorted
|
||||
* @param {Number} left left index of partiton
|
||||
* @param {Number} right right index of partition
|
||||
*/
|
||||
|
||||
const InsertionSort = (array, left, right) => {
|
||||
for (let i = left + 1; i <= right; i++) {
|
||||
const key = array[i]
|
||||
let j = i - 1
|
||||
while (j >= left && array[j] > key) {
|
||||
array[j + 1] = array[j]
|
||||
j--
|
||||
}
|
||||
array[j + 1] = key
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function merges two sorted partitions
|
||||
* @param {Array} array array to be sorted
|
||||
* @param {Number} left left index of partition
|
||||
* @param {Number} mid mid index of partition
|
||||
* @param {Number} right right index of partition
|
||||
*/
|
||||
|
||||
const Merge = (array, left, mid, right) => {
|
||||
if (mid >= right) return
|
||||
const len1 = mid - left + 1
|
||||
const len2 = right - mid
|
||||
const larr = Array(len1)
|
||||
const rarr = Array(len2)
|
||||
for (let i = 0; i < len1; i++) {
|
||||
larr[i] = array[left + i]
|
||||
}
|
||||
for (let i = 0; i < len2; i++) {
|
||||
rarr[i] = array[mid + 1 + i]
|
||||
}
|
||||
let i = 0; let j = 0; let k = left
|
||||
while (i < larr.length && j < rarr.length) {
|
||||
if (larr[i] < rarr[j]) {
|
||||
array[k++] = larr[i++]
|
||||
} else {
|
||||
array[k++] = rarr[j++]
|
||||
}
|
||||
}
|
||||
while (i < larr.length) {
|
||||
array[k++] = larr[i++]
|
||||
}
|
||||
while (j < rarr.length) {
|
||||
array[k++] = rarr[j++]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @example Test of Timsort functions.
|
||||
* Data is randomly generated.
|
||||
* Prints "RIGHT" if it works as expected,
|
||||
* otherwise "FAULTY"
|
||||
*/
|
||||
(() => {
|
||||
const size = 1000000
|
||||
const data = Array(size)
|
||||
for (let i = 0; i < size; i++) {
|
||||
data[i] = Math.random() * Number.MAX_SAFE_INTEGER
|
||||
}
|
||||
const isSorted = function (array) {
|
||||
const n = array.length
|
||||
for (let i = 0; i < n - 1; i++) {
|
||||
if (array[i] > array[i + 1]) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
Timsort(data)
|
||||
if (isSorted(data)) {
|
||||
console.log('RIGHT')
|
||||
} else {
|
||||
console.log('FAULTY')
|
||||
}
|
||||
})()
|
@ -8,7 +8,7 @@ const checkAnagram = (str1, str2) => {
|
||||
|
||||
// If both strings have not same lengths then they can not be anagram.
|
||||
if (str1.length !== str2.length) {
|
||||
return 'Not Anagram'
|
||||
return 'Not anagrams'
|
||||
}
|
||||
|
||||
// Use hashmap to keep count of characters in str1
|
||||
@ -44,7 +44,4 @@ const checkAnagram = (str1, str2) => {
|
||||
return 'Anagrams'
|
||||
}
|
||||
|
||||
console.log(checkAnagram('abcd', 'bcad')) // should print anagram
|
||||
console.log(checkAnagram('abcd', 'abef')) // should print not anagram
|
||||
console.log(checkAnagram(10, 'abcd'))// should print Not String(s).
|
||||
console.log(checkAnagram('abs', 'abds'))// should print not anagram
|
||||
export { checkAnagram }
|
||||
|
@ -21,5 +21,4 @@ const checkPalindrome = (str) => {
|
||||
return 'Palindrome'
|
||||
}
|
||||
|
||||
console.log(checkPalindrome('madam'))
|
||||
console.log(checkPalindrome('abcd'))
|
||||
export { checkPalindrome }
|
||||
|
22
String/CheckPangram.js
Normal file
22
String/CheckPangram.js
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
Pangram is a sentence that contains all the letters in the alphabet
|
||||
https://en.wikipedia.org/wiki/Pangram
|
||||
*/
|
||||
|
||||
const checkPangram = (string) => {
|
||||
if (typeof string !== 'string') {
|
||||
throw new TypeError('The given value is not a string')
|
||||
}
|
||||
|
||||
const frequency = new Set()
|
||||
|
||||
for (const letter of string.toLowerCase()) {
|
||||
if (letter >= 'a' && letter <= 'z') {
|
||||
frequency.add(letter)
|
||||
}
|
||||
}
|
||||
|
||||
return frequency.size === 26
|
||||
}
|
||||
|
||||
export { checkPangram }
|
31
String/CheckRearrangePalindrome.js
Normal file
31
String/CheckRearrangePalindrome.js
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* What is a palindrome? https://en.wikipedia.org/wiki/Palindrome
|
||||
* Receives a string and returns whether it can be rearranged to become a palindrome or not
|
||||
* The string can only be a palindrome if the count of ALL characters is even or if the ONLY ONE character count is odd
|
||||
* Input is a string
|
||||
*
|
||||
**/
|
||||
|
||||
const palindromeRearranging = (str) => {
|
||||
// check that input is a string
|
||||
if (typeof str !== 'string') {
|
||||
return 'Not a string'
|
||||
}
|
||||
// Check if is a empty string
|
||||
if (str.length === 0) {
|
||||
return 'Empty string'
|
||||
}
|
||||
|
||||
// First obtain the character count for each character in the string and store it in an object.
|
||||
// Filter the object's values to only the odd character counts.
|
||||
const charCounts = [...str].reduce((counts, char) => {
|
||||
counts[char] = counts[char] ? counts[char] + 1 : 1
|
||||
return counts
|
||||
}, {})
|
||||
// If the length of the resulting array is 0 or 1, the string can be a palindrome.
|
||||
return Object.values(charCounts).filter(count => count % 2 !== 0).length <= 1
|
||||
}
|
||||
|
||||
// testing
|
||||
console.log(palindromeRearranging('aaeccrr')) // true
|
||||
console.log(palindromeRearranging('leve')) // false
|
21
String/CheckVowels.js
Normal file
21
String/CheckVowels.js
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
Given a string of words or phrases, count the number of vowels.
|
||||
Example: input = "hello world" return 3
|
||||
*/
|
||||
|
||||
const checkVowels = (value) => {
|
||||
if (typeof value !== 'string') {
|
||||
throw new TypeError('The first param should be a string')
|
||||
}
|
||||
const vowels = ['a', 'e', 'i', 'o', 'u']
|
||||
let countVowels = 0
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const char = value[i].toLowerCase()
|
||||
if (vowels.includes(char)) {
|
||||
countVowels++
|
||||
}
|
||||
}
|
||||
return countVowels
|
||||
}
|
||||
|
||||
export { checkVowels }
|
12
String/CheckVowels.test.js
Normal file
12
String/CheckVowels.test.js
Normal file
@ -0,0 +1,12 @@
|
||||
import { checkVowels } from './CheckVowels'
|
||||
|
||||
describe('Test the checkVowels function', () => {
|
||||
it('expect throws on use wrong param', () => {
|
||||
expect(() => checkVowels(0)).toThrow()
|
||||
})
|
||||
it('count the vowels in a string', () => {
|
||||
const value = 'Mad World'
|
||||
const countVowels = checkVowels(value)
|
||||
expect(countVowels).toBe(2)
|
||||
})
|
||||
})
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user