├── .prettierrc ├── .gitignore ├── jest.config.js ├── package.json ├── LICENSE.md ├── CONTRIBUTING.md ├── src ├── hashing-functions.js ├── datastructures.js └── algorithms.js ├── ReadMe.md ├── testSites ├── testSite3.js └── testSite.js └── __test__ ├── data-structure.spec.js └── algorithms.spec.js /.prettierrc: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.env 2 | /dist 3 | /node_modules -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('jest').Config} */ 2 | const config = { 3 | verbose: true, 4 | testEnvironment: "jest-environment-node", 5 | transform: {}, 6 | }; 7 | 8 | // module.exports = config; 9 | export default config; 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AlgoData", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "./src/algorithms.js", 6 | "type": "module", 7 | "scripts": { 8 | "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/Nosa-Drexx/AlgoData.git" 13 | }, 14 | "author": "", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/Nosa-Drexx/AlgoData/issues" 18 | }, 19 | "homepage": "https://github.com/Nosa-Drexx/AlgoData#readme", 20 | "devDependencies": { 21 | "jest": "^29.3.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Egharevba Nosa 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | First of all, thank you for taking the time to contribute to this project. We've tried to this documentation upderstandable and working. You can help us do more. 3 | 4 | ## Getting started 5 | 6 | ### Writing some code! 7 | 8 | Contributing to a project on Github is pretty straight forward. If this is you're first time, these are the steps you should take. 9 | 10 | - Fork this repo. 11 | 12 | Create and issue or take up and open issue, 13 | 14 | And that's it!, create a new branch and Read the code available and change the part you don't like! Your change should not break the existing code and should pass the tests. 15 | 16 | If you're adding a new algorithm or datastructure, start from the branch **main**. It would be a better practice to create a new branch and work in there. 17 | 18 | When you're done, submit a pull request to *AlgoData/main** branch for one of the maintainers to check it out. We would let you know if there is any problem or any changes that should be considered. 19 | 20 | ### Documentation 21 | 22 | Every chunk of code that may be hard to understand has some comments above it. If you write some new code or change some part of the existing code in a way that it would not be functional without changing it's usages, it needs to be documented. 23 | -------------------------------------------------------------------------------- /src/hashing-functions.js: -------------------------------------------------------------------------------- 1 | export const hash1 = (range) => { 2 | var cache = {}; 3 | return function h1(string) { 4 | var stringArr = string.split(""); 5 | const alphabets = "abcdefghijklmnopqrstuvwxyz".split(""); 6 | var calculate = new Array(26); 7 | for (let i = 0; i < calculate.length; i += 2) { 8 | // fills up the array with 0s and 1s alternatingly. 9 | calculate[i] = 0; 10 | calculate[i + 1] = 1; 11 | } 12 | var sum = 0; 13 | if (string in cache) { 14 | return cache[string]; 15 | } 16 | stringArr.forEach((elem) => { 17 | const notCaseSensitive = elem.toLowerCase(); 18 | for (let i = 0; i < alphabets.length; i++) { 19 | if (alphabets[i] === notCaseSensitive) { 20 | return (sum += calculate[i]); 21 | } 22 | } 23 | }); 24 | const random = Math.floor(Math.random() * (range - sum)); 25 | cache[string] = random; 26 | return random; 27 | }; 28 | }; 29 | 30 | export const hash2 = (range) => { 31 | var cache = {}; 32 | return function hash3(string) { 33 | if (string in cache) { 34 | return cache[string]; 35 | } 36 | var random = Math.floor(Math.random() * range); 37 | cache[string] = random; 38 | return random; 39 | }; 40 | }; 41 | 42 | export const hash3 = (range) => { 43 | var cache = {}; 44 | return function hash3(string) { 45 | if (string in cache) { 46 | return cache[string]; 47 | } 48 | var random = Math.floor(Math.random() * range); 49 | cache[string] = random; 50 | return random; 51 | }; 52 | }; 53 | 54 | export const hash = (string, range) => { 55 | var stringArr = string.split(""); 56 | const alphabets = "abcdefghijklmnopqrstuvwxyz".split(""); 57 | var calculate = new Array(26); 58 | for (let i = 0; i < calculate.length; i += 2) { 59 | // fills up the array with 0s and 1s alternatingly. 60 | calculate[i] = 0; 61 | calculate[i + 1] = 1; 62 | } 63 | var sum = 0; 64 | 65 | stringArr.forEach((elem) => { 66 | const notCaseSensitive = elem.toLowerCase(); 67 | for (let i = 0; i < alphabets.length; i++) { 68 | if (alphabets[i] === notCaseSensitive) { 69 | return (sum += calculate[i]); 70 | } 71 | } 72 | }); 73 | if (sum === 0) sum = 13; 74 | const random = Math.floor(range / sum); 75 | 76 | return random; 77 | }; 78 | 79 | export const _hash = (str, range) => { 80 | let sum = 0; 81 | for (let i = 0; i < str.length; i++) { 82 | sum += str.charCodeAt(i) * 3; 83 | } 84 | return sum % range; 85 | }; 86 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # 👋 AlgoData -- Datastructures and Algorithms 2 | 3 | A list of datastructures and algorithms I've personally written in **_JavaScript_** over my years of programming including: 4 | 5 | - Algorithms to some javascript Inbuilt functions. 6 | - Algorithms to some lodash functions. 7 | - Algorithms to some common interview/coding challenges. 8 | - Datastructures. 9 | 10 | Some algorithms have different variant which will be listed below 11 | 12 | Nb: All code can be found in the src folder "algorithms.js, "datastructure.js", "hashing-functions.js" files on the root of this repo, check file for more info and uses of algorithms 13 | 14 | See full content below 15 | 16 | ## ❗ Disclaimer 17 | 18 | Links referenced in files are courtesy of Frontend Masters instructors 19 | 20 | ### 📌 status 21 | 22 | This repo is open source, feel free to star, fork or contribute. 23 | 24 | To contribute please read the CONTRIBUTING.md files on the root of this repo 25 | 26 | #### Clone project 27 | 28 | ```sh 29 | git clone https://github.com/Nosa-Drexx/AlgoData.git # or 'git@github.com:Nosa-Drexx/AlgoData.git' for ssh 30 | cd AlgoData 31 | ``` 32 | 33 | #### Setup 34 | 35 | ```sh 36 | npm i # install packages 37 | npm test # run tests 38 | ``` 39 | 40 | ### 📋 List of Content: 41 | 42 | - ➡️ 🖨️ **_Algorithms_** 43 | 44 | - ➡️ Map 45 | - ➡️ isEven 46 | - ➡️ isEven2 47 | - ➡️ isPrime 48 | - ➡️ isPrime2 49 | - ➡️ isPrime3 50 | - ➡️ delay 51 | - ➡️ reverse 52 | - ➡️ reverse2 53 | - ➡️ lottery 54 | - ➡️ isPalindrome 55 | - ➡️ pipe2 56 | - ➡️ filterIn 57 | - ➡️ uniqueElemArr 58 | - ➡️ uniqueArr2 59 | - ➡️ reduceArr 60 | - ➡️ reduceObj 61 | - ➡️ mapWithExplicitReduceFunction 62 | - ➡️ filterWithExplicitReduceFunction 63 | - ➡️ curryN 64 | - ➡️ compose 65 | - ➡️ pipe 66 | - ➡️ convertNumberToDifferentBase 67 | - ➡️ concatAll 68 | - ➡️ zip 69 | - ➡️ bubbleSort 70 | - ➡️ insertionSort 71 | - ➡️ nestedAdd 72 | - ➡️ factorial 73 | - ➡️ factorial2 74 | - ➡️ mergeSort 75 | - ➡️ quickSort 76 | - ➡️ radixSort 77 | - ➡️ binarySearch 78 | - ➡️ binarySearch2 79 | - ➡️ linearSearch 80 | - ➡️ preoder (preoder trevarsal through binary trees) 81 | - ➡️ postorder (postorder trevarsal through binary trees) 82 | - ➡️ inorder (inorder trevarsal through binary trees) 83 | - ➡️ breadth (breadthfirst trevarsal through binary trees) 84 | - ➡️ heapSort 85 | - ➡️ connect (trevse through a graph; based on data in "testSite2.js") 86 | - ➡️ hash1 (hashing functions) 87 | - ➡️ hash2 (hashing functions) 88 | - ➡️ hash3 (hashing functions) 89 | - ➡️ \_hash (hashing functions) 90 | - ➡️ uniqueArr 91 | - ➡️ uniqueArr3 92 | - ➡️ preOrderTraverse 93 | - ➡️ inOrderTraverse 94 | - ➡️ postOrderTraverse 95 | - ➡️ depthFirstTraversal 96 | - ➡️ breadthFirstTraversal 97 | - ➡️ sortArrayRandomly 98 | - ➡️ isValidSubsequence 99 | - ➡️ id 100 | - ➡️ randomNumberBetween 101 | - ➡️ fibonacciSeries 102 | - ➡️ randomPasswordGen 103 | - ➡️ MostOccuringNumberInAnArray 104 | - ➡️ staircase 105 | - ➡️ mergeMutate 106 | - ➡️ divisibleSumPairs 107 | - ➡️ sliceJS 108 | - ➡️ joinJS 109 | - ➡️ splitJS 110 | - ➡️ factorsOf 111 | - ➡️ LCM 112 | - ➡️ HCF 113 | - ➡️ someJS 114 | - ➡️ everyJS 115 | - ➡️ pushJS 116 | - ➡️ fillJS 117 | - ➡️ combination 118 | - ➡️ permutation 119 | - ➡️ allLetters 120 | - ➡️ prefixCalc 121 | - ➡️ postfixCalc 122 | - ➡️ prefixCalc2 123 | 124 | - ➡️ **_DataStructures_** 125 | 126 | All dataStructures were implemented using **_JavaScript_** classes 127 | 128 | - ➡️ ArrayList 129 | - ➡️ Node 130 | - ➡️ BloomFilter 131 | - ➡️ Queue 132 | - ➡️ Linkedlist 133 | - ➡️ HashTable 134 | - ➡️ BinaryTree 135 | - ➡️ Graph 136 | - ➡️ Stack 137 | -------------------------------------------------------------------------------- /testSites/testSite3.js: -------------------------------------------------------------------------------- 1 | function sortArrayRandomly(array) { 2 | const arr = [...array]; 3 | for (let i = 0; i < arr.length; i++) { 4 | var temp = arr[i]; 5 | const randomPosition = Math.floor(Math.random() * (arr.length - 1)); 6 | arr[i] = arr[randomPosition]; 7 | arr[randomPosition] = temp; 8 | } 9 | return arr; 10 | } 11 | 12 | var randomArr = sortArrayRandomly([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); 13 | // console.log(randomArr); 14 | 15 | function mergeSort(array) { 16 | const arr = [...array]; 17 | const half = arr.length / 2; 18 | 19 | function merge(left, right) { 20 | var mergedArr = []; 21 | while (left.length && right.length) { 22 | if (left[0] < right[0]) { 23 | mergedArr.push(left.shift()); 24 | } else { 25 | mergedArr.push(right.shift()); 26 | } 27 | } 28 | return mergedArr.concat(left, right); 29 | } 30 | if (arr.length > 1) { 31 | var left = mergeSort(arr.splice(0, half)); 32 | var right = mergeSort(arr); 33 | return merge(left, right); 34 | } 35 | return arr; 36 | } 37 | 38 | // console.log(mergeSort(randomArr)); 39 | 40 | function isValidSubsequence(array, sequence) { 41 | var arrC = [...array]; 42 | var arr = []; 43 | 44 | for (let i = 0; i < sequence.length; i++) { 45 | if (arrC.includes(sequence[i])) { 46 | arr.push(sequence[i]); 47 | arrC = arrC.splice(arrC.indexOf(sequence[i]) + 1, arrC.length); 48 | } 49 | } 50 | 51 | return arr.length === sequence.length ? true : false; 52 | } 53 | 54 | var array = [1, 1, 1, 1]; 55 | var sequence = [1, 1, 1]; 56 | // console.log(isValidSubsequence(array, sequence)); 57 | 58 | function id() { 59 | var randomId = "_"; 60 | const fakeIdGen = () => Math.floor(Math.random() * 9); 61 | for (let i = 0; i < 5; i++) { 62 | randomId += fakeIdGen(); 63 | } 64 | return randomId; 65 | } 66 | 67 | // console.log(id()); 68 | 69 | function randomNumberBetween(first, second) { 70 | if (typeof first !== "number" && typeof second !== "number") 71 | return "error expected type Number"; 72 | const firstVal = Number(first); 73 | const secondVal = Number(second); 74 | const diff = Math.abs(firstVal - secondVal) - 1; 75 | 76 | const randomDiff = Math.floor(Math.random() * diff); 77 | const bigger = firstVal > secondVal ? firstVal - 1 : secondVal - 1; 78 | return Math.abs(bigger - randomDiff); 79 | } 80 | // console.log(randomNumberBetween(30, 10)); 81 | 82 | function fibonacciSeries(value) { 83 | const cache = {}; 84 | function fibHelper(value) { 85 | if (value < 3) return 1; 86 | const prev = cache[value - 1] ? cache[value - 1] : fibHelper(value - 1); 87 | const secondPrev = cache[value - 2] 88 | ? cache[value - 2] 89 | : fibHelper(value - 2); 90 | const result = prev + secondPrev; 91 | if (!cache[value]) cache[value] = result; 92 | return result; 93 | } 94 | return fibHelper(value); 95 | } 96 | 97 | // const answer = fibonacciSeries(1000); 98 | // console.log(answer); 99 | function dayOfProgrammer(year) { 100 | // Write your code here 101 | const dayOfProgramming = 256; 102 | let otherMonthAddition = 215; 103 | const firstEightMonths = 104 | year % 4 === 0 ? otherMonthAddition + 29 : otherMonthAddition + 28; 105 | return `${dayOfProgramming - firstEightMonths}.09.${year}`; 106 | } 107 | 108 | // console.log(dayOfProgrammer(2100)); 109 | 110 | function helper(arr, count, index) { 111 | let accum = 0; 112 | const comp = arr.length; 113 | for (let i = index; i <= comp && arr[i] !== undefined; i = i + count) { 114 | accum += arr[i]; 115 | } 116 | return accum; 117 | } 118 | 119 | function formingMagicSquare(s) { 120 | // Write your code here 121 | const n = s.length; 122 | let allElemInArray = []; 123 | const magicContanst = 15; 124 | const choosenRow = {}; 125 | let result = 0; 126 | 127 | function flatMap(allElemInArray) { 128 | for (let elem of s) { 129 | allElemInArray.push(...elem); 130 | } 131 | } 132 | 133 | for (let subArray of s) { 134 | allElemInArray = []; 135 | flatMap(allElemInArray); 136 | const addAllElem = subArray.reduce((accum, num) => { 137 | return accum + num; 138 | }, 0); 139 | if (addAllElem !== magicContanst) { 140 | let index; 141 | let smallestElemIndex = 0; 142 | for (let i = 0; i < subArray.length; i++) { 143 | let columnAddition = helper(allElemInArray, subArray.length, i); 144 | if (subArray[smallestElemIndex] > subArray[i]) smallestElemIndex = i; 145 | if (columnAddition === addAllElem && !choosenRow[i]) { 146 | if (index === undefined) { 147 | choosenRow[i] = "choosen"; 148 | index = i; 149 | } 150 | if (subArray[index] < subArray[i]) { 151 | delete choosenRow[index]; 152 | index = i; 153 | choosenRow[i] = "choosen"; 154 | } 155 | } 156 | } 157 | 158 | if (index !== undefined) { 159 | const difference = magicContanst - addAllElem; 160 | result += Math.abs(subArray[index] - (subArray[index] + difference)); 161 | subArray[index] += difference; 162 | } else { 163 | if (addAllElem > magicContanst && index === undefined) { 164 | const difference = magicContanst - addAllElem; 165 | result += Math.abs( 166 | subArray[smallestElemIndex] - 167 | (subArray[smallestElemIndex] + difference) 168 | ); 169 | subArray[smallestElemIndex] += difference; 170 | } 171 | } 172 | } 173 | } 174 | return result; 175 | } 176 | 177 | const threeBythreeArray = [ 178 | [5, 3, 4], 179 | [1, 5, 8], 180 | [6, 4, 2], 181 | ]; 182 | 183 | const threeBythreeArray2 = [ 184 | [4, 9, 2], 185 | [3, 5, 7], 186 | [8, 1, 5], 187 | ]; 188 | 189 | const threeBythreeArray3 = [ 190 | [4, 8, 2], 191 | [4, 5, 7], 192 | [6, 1, 6], 193 | ]; 194 | 195 | console.log(formingMagicSquare(threeBythreeArray3)); 196 | 197 | console.log(threeBythreeArray3); 198 | -------------------------------------------------------------------------------- /__test__/data-structure.spec.js: -------------------------------------------------------------------------------- 1 | import { 2 | ArrayList, 3 | BloomFilter, 4 | Graph, 5 | HashTable, 6 | Linkedlist, 7 | Queue, 8 | Stack, 9 | } from "../src/datastructures"; 10 | 11 | describe("Test for array data-strucure", () => { 12 | const arrayDS = new ArrayList(); 13 | test("test push", () => { 14 | arrayDS.push(3); 15 | arrayDS.push(4); // {"0" : 3, "1" : 4, "length" :2} 16 | 17 | expect(arrayDS).toEqual({ 0: 3, 1: 4, length: 2 }); 18 | }); 19 | test("test pop", () => { 20 | arrayDS.pop(); 21 | 22 | expect(arrayDS).toEqual({ 0: 3, length: 1 }); 23 | }); 24 | test("get value by index", () => { 25 | const value = arrayDS.get(0); 26 | 27 | expect(value).toBe(3); 28 | }); 29 | test("shift", () => { 30 | arrayDS.shift(); 31 | 32 | expect(arrayDS).toEqual({ length: 0 }); 33 | }); 34 | test("delete", () => { 35 | arrayDS.push(4); // {0: 4, length: 1} 36 | arrayDS.delete(0); // {} 37 | 38 | expect(arrayDS).toEqual({ length: 0 }); 39 | }); 40 | }); 41 | 42 | describe("Test for BloomFilter", () => { 43 | const bloomFilterDS = new BloomFilter(); 44 | 45 | test("test", () => { 46 | expect(bloomFilterDS.contains("Nosa")).toBe(false); 47 | bloomFilterDS.add("Nosa"); 48 | expect(bloomFilterDS.contains("Nosa")).toBe(true); 49 | }); 50 | }); 51 | 52 | describe("Test for Queue", () => { 53 | const queueDS = new Queue(); 54 | test("Test enqueue", () => { 55 | queueDS.enqueue(1); 56 | queueDS.enqueue(9); 57 | queueDS.enqueue(7); 58 | 59 | expect(queueDS).toEqual({ 60 | 0: 1, 61 | 1: 9, 62 | 2: 7, 63 | _length: 3, 64 | _track: 0, 65 | }); 66 | }); 67 | 68 | test("Test dequeue", () => { 69 | queueDS.dequeue(); 70 | queueDS.dequeue(); 71 | 72 | expect(queueDS).toEqual({ 73 | 2: 7, 74 | _length: 1, 75 | _track: 2, 76 | }); 77 | }); 78 | 79 | test("Test peek", () => { 80 | const value = queueDS.peek(); 81 | 82 | expect(value).toBe(7); 83 | }); 84 | }); 85 | 86 | describe("Test for LinkedList Datastructure", () => { 87 | const linkedListDS = new Linkedlist(); 88 | test("Test Insert", () => { 89 | linkedListDS.insert(2); 90 | linkedListDS.insert(7); 91 | 92 | expect(linkedListDS.head.value).toBe(2); 93 | expect(linkedListDS.head.next.value).toBe(7); 94 | }); 95 | 96 | test("Test InsertNewHead", () => { 97 | linkedListDS.InsertNewHead(3); 98 | 99 | expect(linkedListDS.head.value).toBe(3); 100 | }); 101 | 102 | test("Test get", () => { 103 | const node = linkedListDS.get(2); 104 | //must be made a function because an error is been thrown "Jest rule" 105 | const node2 = () => { 106 | linkedListDS.get(10); 107 | }; 108 | 109 | expect(node.value).toBe(2); 110 | expect(node2).toThrow(Error); //expect to error out 111 | }); 112 | 113 | test("Test reverse", () => { 114 | linkedListDS.reverseList(); 115 | expect(linkedListDS.head).toEqual({ 116 | next: { 117 | next: { 118 | next: null, 119 | value: 3, 120 | }, 121 | value: 2, 122 | }, 123 | value: 7, 124 | }); 125 | 126 | //reverse back to previous state. 127 | linkedListDS.reverseList(); 128 | expect(linkedListDS.head).toEqual({ 129 | next: { 130 | next: { 131 | next: null, 132 | value: 7, 133 | }, 134 | value: 2, 135 | }, 136 | value: 3, 137 | }); 138 | }); 139 | 140 | test("Test remove", () => { 141 | const removed = linkedListDS.remove(2); 142 | const removed2 = () => { 143 | linkedListDS.remove(100); 144 | }; 145 | 146 | expect(removed.value).toBe(2); 147 | expect(removed2).toThrow(Error); 148 | }); 149 | 150 | test("Test insertIn", () => { 151 | linkedListDS.insertIn(3, 76); 152 | 153 | const node2 = linkedListDS.get(76); 154 | 155 | expect(node2.value).toEqual(76); 156 | }); 157 | 158 | test("Test removeTail", () => { 159 | const node = linkedListDS.removeTail(); 160 | 161 | expect(node.value).toBe(7); 162 | }); 163 | test("Test contains", () => { 164 | const value = linkedListDS.contains(76); 165 | const value2 = linkedListDS.contains(0); 166 | 167 | expect(value).toEqual(true); 168 | expect(value2).toEqual(false); 169 | }); 170 | }); 171 | 172 | describe("Test for HashTable", () => { 173 | const hashTableDS = new HashTable(100); 174 | test("Test insert", () => { 175 | hashTableDS.insert("Nosa"); 176 | hashTableDS.insert("Henry"); 177 | hashTableDS.insert("Fubar"); 178 | hashTableDS.insert( 179 | "The hungry lions went to play on an empty stomach, it ended up eating it's friends, such an irony it is, now the lion has no one to play with" 180 | ); 181 | 182 | expect(hashTableDS._length).toBe(4); 183 | }); 184 | 185 | test("Test remove", () => { 186 | const removed = hashTableDS.remove("Henry"); 187 | expect(removed).toContain("Henry"); 188 | }); 189 | 190 | test("Test retrieve", () => { 191 | const randomKeySearch = () => { 192 | //random number from one to five 193 | const random = Math.floor(Math.random * 6); 194 | 195 | hashTableDS.retrieve(random); 196 | }; 197 | 198 | const validKeySearch = hashTableDS.retrieve(3); 199 | 200 | expect(randomKeySearch).toThrow(Error); 201 | expect(validKeySearch).toEqual("Nosa"); 202 | }); 203 | }); 204 | 205 | describe("Test for Graph", () => { 206 | const graphDS = new Graph(7); 207 | test("Test AddNode", () => { 208 | graphDS.addNode(8); 209 | 210 | expect(graphDS[8]).toEqual({ 211 | connections: [], 212 | value: 8, 213 | }); 214 | }); 215 | 216 | test("Test addEdge", () => { 217 | graphDS.addEdge(7, 8, 10, 9, 11, 12, 13, 14); 218 | 219 | expect(graphDS[7].connections).toEqual([8, 10, 9, 11, 12, 13, 14]); 220 | }); 221 | 222 | test("Test removeNode", () => { 223 | const removed = graphDS.removeNode(8); 224 | const removed2 = () => { 225 | graphDS.removeNode(8); 226 | }; 227 | 228 | expect(removed.value).toBe(8); 229 | expect(removed2).toThrow(Error); 230 | }); 231 | }); 232 | 233 | describe("Test for Stack", () => { 234 | const stackDS = new Stack(); 235 | 236 | test("Test push", () => { 237 | const push = stackDS.push({ trial: "okay" }); 238 | const push2 = stackDS.push(["cool"]); 239 | 240 | expect(push).toEqual({ trial: "okay" }); 241 | expect(push2).toEqual(["cool"]); 242 | }); 243 | 244 | test("Test pop", () => { 245 | const remove = stackDS.pop(); 246 | 247 | expect(remove).toEqual(["cool"]); 248 | }); 249 | 250 | test("Test get", () => { 251 | expect(stackDS.length).toBe(1); 252 | }); 253 | }); 254 | -------------------------------------------------------------------------------- /__test__/algorithms.spec.js: -------------------------------------------------------------------------------- 1 | import { 2 | MostOccuringNumberInAnArray, 3 | fibonacciSeries, 4 | isPrime3, 5 | isEven, 6 | isEven2, 7 | map, 8 | isPrime, 9 | isPrime2, 10 | reverse, 11 | reverse2, 12 | isPalindrome, 13 | filterIn, 14 | uniqueElemArr, 15 | uniqueArr2, 16 | reduceObj, 17 | prefixCalc, 18 | postfixCalc, 19 | prefixCalc2, 20 | curryN, 21 | compose, 22 | pipe, 23 | convertNumberToDifferentBase, 24 | concatAll, 25 | zip, 26 | bubbleSort, 27 | insertionSort, 28 | nestedAdd, 29 | mergeSort, 30 | factorial, 31 | factorial2, 32 | quickSort, 33 | radixSort, 34 | binarySearch, 35 | nestedAdd2, 36 | linearSearch, 37 | preorder, 38 | postorder, 39 | inorder, 40 | tree, 41 | breadth, 42 | } from "../src/algorithms"; 43 | 44 | describe("Test map function", () => { 45 | const testArray = [3, 4, 6, 89, 10]; 46 | test("Expect result array to be [0, 1, 2, 3, 4] ", () => { 47 | const answer = map(testArray, (value, index, array) => index); 48 | 49 | expect(answer).toEqual([0, 1, 2, 3, 4]); 50 | }); 51 | test("Expect result array to be [4, 5, 7, 90, 11] ", () => { 52 | const answer = map(testArray, (value) => value + 1); 53 | 54 | expect(answer).toEqual([4, 5, 7, 90, 11]); 55 | }); 56 | test("Expect result array to be [[3], [4], [6], [89], [10]] ", () => { 57 | const answer = map(testArray, (value, index, array) => 58 | array.slice(index, index + 1) 59 | ); 60 | 61 | expect(answer).toEqual([[3], [4], [6], [89], [10]]); 62 | }); 63 | }); 64 | 65 | describe("Test Even number", () => { 66 | test("Expect 6 to an even number", () => { 67 | const testValue = 6; 68 | const answer = isEven(testValue); 69 | const answer2 = isEven2(testValue); 70 | 71 | expect(answer).toBe(true); 72 | expect(answer2).toBe(true); 73 | }); 74 | test("Expect 7 to an even number", () => { 75 | const testValue = 7; 76 | const answer = isEven(testValue); 77 | const answer2 = isEven2(testValue); 78 | 79 | expect(answer).toBe(false); 80 | expect(answer2).toBe(false); 81 | }); 82 | test("Expect 4 to an even number", () => { 83 | const testValue = 4; 84 | const answer = isEven(testValue); 85 | const answer2 = isEven2(testValue); 86 | 87 | expect(answer).toBe(true); 88 | expect(answer2).toBe(true); 89 | }); 90 | }); 91 | 92 | describe("Test MostOccuringNumberInAnArray", () => { 93 | test("Expect most occuring number to be 6", () => { 94 | const testValue = [1, 9, 4, 4, 5, 5, 9, 5, 9, 7, 4, 6, 7, 9, 7, 6, 6, 6, 6]; 95 | const answer = MostOccuringNumberInAnArray(testValue); 96 | 97 | expect(answer).toBe(6); 98 | }); 99 | 100 | test("Expect most occuring number to be an object '{ 6: 5, 9: 5 }'", () => { 101 | const testValue = [ 102 | 1, 9, 4, 9, 4, 5, 5, 9, 5, 9, 7, 4, 6, 7, 9, 7, 6, 6, 6, 6, 103 | ]; 104 | const answer = MostOccuringNumberInAnArray(testValue); 105 | 106 | expect(answer).toEqual({ 6: 5, 9: 5 }); 107 | }); 108 | 109 | test("Expect most occuring number to be an object '{ 4: 5, 6: 5, 9: 5 }'", () => { 110 | const testValue = [ 111 | 1, 9, 4, 9, 4, 5, 4, 5, 9, 5, 9, 7, 4, 6, 7, 9, 7, 6, 6, 6, 6, 4, 112 | ]; 113 | const answer = MostOccuringNumberInAnArray(testValue); 114 | 115 | expect(answer).toEqual({ 4: 5, 6: 5, 9: 5 }); 116 | }); 117 | }); 118 | 119 | describe("Test Fibonanci Series", () => { 120 | test("Expects answer to be 1", () => { 121 | const value = 0; 122 | const answer = fibonacciSeries(value); 123 | 124 | expect(answer).toBe(1); 125 | }); 126 | 127 | test("Expects answer to be 6765", () => { 128 | const value = 20; 129 | const answer = fibonacciSeries(value); 130 | 131 | expect(answer).toBe(6765); 132 | }); 133 | 134 | test("Expects answer to be 5", () => { 135 | const value = 5; 136 | const answer = fibonacciSeries(value); 137 | 138 | expect(answer).toBe(5); 139 | }); 140 | 141 | test("Expects answer to be Infinity", () => { 142 | const value = 10000; 143 | const answer = fibonacciSeries(value); 144 | 145 | expect(answer).toBe(Infinity); 146 | }); 147 | }); 148 | 149 | describe("Test Prime Number", () => { 150 | test("Expects answer to be true", () => { 151 | const n = 17; 152 | const answer = isPrime(n); 153 | const answer2 = isPrime2(n); 154 | const answer3 = isPrime3(n); 155 | 156 | expect(answer2).toBe(true); 157 | expect(answer3).toBe(true); 158 | }); 159 | 160 | test("Expects answer to be false", () => { 161 | const n = 18; 162 | const answer = isPrime(n); 163 | const answer2 = isPrime2(n); 164 | const answer3 = isPrime3(n); 165 | 166 | expect(answer).toBe(false); 167 | expect(answer2).toBe(false); 168 | expect(answer3).toBe(false); 169 | }); 170 | 171 | test("Expects answer to be false", () => { 172 | const n = 15; 173 | const answer = isPrime(n); 174 | const answer2 = isPrime2(n); 175 | const answer3 = isPrime3(n); 176 | 177 | expect(answer).toBe(false); 178 | expect(answer2).toBe(false); 179 | expect(answer3).toBe(false); 180 | }); 181 | }); 182 | 183 | describe("Test reverse array", () => { 184 | test("Expects reversed array to be [5, 4, 3, 2, 1]", () => { 185 | const answer = reverse([1, 2, 3, 4, 5]); 186 | const answer2 = reverse2([1, 2, 3, 4, 5]); 187 | 188 | expect(answer).toEqual([5, 4, 3, 2, 1]); 189 | expect(answer2).toEqual([5, 4, 3, 2, 1]); 190 | }); 191 | }); 192 | 193 | describe("Test isPalindrome", () => { 194 | test("Expects be '' to be true", () => { 195 | const answer = isPalindrome(""); 196 | 197 | expect(answer).toBe(true); 198 | }); 199 | 200 | test("Expects be 'aa' to be true", () => { 201 | const answer = isPalindrome("aa"); 202 | 203 | expect(answer).toBe(true); 204 | }); 205 | 206 | test("Expects be 'abba' to be true", () => { 207 | const answer = isPalindrome("abba"); 208 | 209 | expect(answer).toBe(true); 210 | }); 211 | 212 | test("Expects be 'abccba' to be true", () => { 213 | const answer = isPalindrome("abba"); 214 | 215 | expect(answer).toBe(true); 216 | }); 217 | }); 218 | 219 | describe("Test for filterIn", () => { 220 | const testArray = [1, 2, 3, 4, 5, 6, 8]; 221 | test("Expects [1, 2, 3, 4, 5, 6, 8] filters greater than 5 to be [6, 8]", () => { 222 | const answer = filterIn((value) => value > 5, testArray); 223 | 224 | expect(answer).toEqual([6, 8]); 225 | }); 226 | 227 | test("Expects [1, 2, 3, 4, 5, 6, 8] filters greater than or equals 5 to be [5,6, 8]", () => { 228 | const answer = filterIn((value) => value >= 5, testArray); 229 | 230 | expect(answer).toEqual([5, 6, 8]); 231 | }); 232 | 233 | test("Expects [1, 2, 3, 4, 5, 6, 8] filters less than 5 to be [1, 2, 3, 4]", () => { 234 | const answer = filterIn((value) => value < 5, testArray); 235 | 236 | expect(answer).toEqual([1, 2, 3, 4]); 237 | }); 238 | }); 239 | 240 | describe("Test for unique elements in array", () => { 241 | test("Expects [1,2,3,1,1,2,3,4,5,] to be reduces to [1,2,3,4,5]", () => { 242 | const testArray1 = [1, 2, 3, 1, 1, 2, 3, 4, 5]; 243 | const testArray2 = [1, 2, 3, 1, 1, 2, 3, 4, 5]; 244 | const answer1 = uniqueElemArr(testArray1); 245 | const answer2 = uniqueArr2(testArray2); 246 | 247 | expect(answer1).toEqual([1, 2, 3, 4, 5]); 248 | expect(answer2).toEqual([1, 2, 3, 4, 5]); 249 | }); 250 | }); 251 | 252 | describe("Test for reduce function", () => { 253 | test("Expects ['Nosa ' , 'Is ', 'A ', 'Genius'] to be Nosa Is A Genius", () => { 254 | let stringReduceTest = reduceObj( 255 | function (one, two) { 256 | return one + two; 257 | }, 258 | "", 259 | ["Nosa ", "Is ", "A ", "Genius"] 260 | ); 261 | 262 | expect(stringReduceTest).toEqual("Nosa Is A Genius"); 263 | }); 264 | }); 265 | 266 | describe("Test for prefix calculator", () => { 267 | test("Test prefix expressions", () => { 268 | const result1 = prefixCalc("0"); // 0 269 | const result2 = prefixCalc("+ 3 4"); // 7 270 | const result3 = prefixCalc("- 3 * 4 5"); //-17 271 | const result4 = prefixCalc("* + 3 4 5"); //35 272 | const result5 = prefixCalc("+ - 4 6 * 9 / 10 50"); //48.2 273 | const result6 = prefixCalc("+ * * + 2 3 4 5 + 6 7"); //113 274 | 275 | expect(result1).toBe(0); 276 | expect(result2).toBe(7); 277 | expect(result3).toBe(-17); 278 | expect(result4).toBe(35); 279 | expect(result5).toBe(48.2); 280 | expect(result6).toBe(113); 281 | }); 282 | }); 283 | 284 | describe("Test for second prefix calculator", () => { 285 | test("Test prefix expressions", () => { 286 | const result1 = prefixCalc2("0"); // 0 287 | const result2 = prefixCalc2("+ 3 4"); // 7 288 | const result3 = prefixCalc2("- 3 * 4 5"); //-17 289 | const result4 = prefixCalc2("* + 3 4 5"); //35 290 | const result6 = prefixCalc2("+ * * + 2 3 4 5 + 6 7"); //113 291 | 292 | expect(result1).toBe(0); 293 | expect(result2).toBe(7); 294 | expect(result3).toBe(-17); 295 | expect(result4).toBe(35); 296 | expect(result6).toBe(113); 297 | }); 298 | }); 299 | 300 | describe("Test for postfix calculator", () => { 301 | test("Test postfix expressions", () => { 302 | const result1 = postfixCalc("0"); // 0 303 | const result2 = postfixCalc("2 3 4 + * 5 6 7 8 + * + +"); // 109 304 | const result3 = postfixCalc("2 3 4 * 6 / +"); // 2.5 305 | const result4 = postfixCalc("5 7 + 1 *"); // 12 306 | 307 | expect(result1).toBe(0); 308 | expect(result2).toBe(109); 309 | expect(result3).toBe(2.5); 310 | expect(result4).toBe(12); 311 | }); 312 | }); 313 | 314 | describe('Test for curry function', ()=> { 315 | test("Test curry", ()=> { 316 | const addOneCurry = (x, y ,z) => { 317 | return x + y + z 318 | } 319 | 320 | const curryHolder = curryN(3, addOneCurry); 321 | expect(curryHolder(7)(7)(7)).toBe(21) 322 | }) 323 | }) 324 | 325 | describe("Test for compose function", ()=> { 326 | test('compose function test', ()=> { 327 | const add = (num) => num + 2 328 | const mul = (num) => num * 2 329 | 330 | 331 | const composed = compose(add, mul); 332 | 333 | expect(composed(9)).toBe(20); 334 | }) 335 | }); 336 | 337 | 338 | describe('Test for pipe function', ()=>{ 339 | test('compose function test', ()=> { 340 | const add = (num) => num + 2 341 | const mul = (num) => num * 2 342 | 343 | 344 | const piped = pipe(add, mul); 345 | 346 | expect(piped(9)).toBe(22); 347 | }) 348 | }) 349 | 350 | describe("Test convetToDifferentBase", ()=> { 351 | test('convert Number to base 2', ()=>{ 352 | const TwoToBase2 = convertNumberToDifferentBase(2, 2) 353 | const ThreeToBase2 = convertNumberToDifferentBase(3, 2) 354 | const EightToBase2 = convertNumberToDifferentBase(8, 2) 355 | 356 | expect(TwoToBase2).toEqual('10') 357 | expect(ThreeToBase2).toEqual('11') 358 | expect(EightToBase2).toEqual('1000') 359 | }) 360 | test('convert Number to base 8', ()=>{ 361 | const TwoToBase8 = convertNumberToDifferentBase(2, 8) 362 | const ThreeToBase8 = convertNumberToDifferentBase(10, 8) 363 | const EightToBase8 = convertNumberToDifferentBase(20, 8) 364 | 365 | expect(TwoToBase8).toEqual('2') 366 | expect(ThreeToBase8).toEqual('12') 367 | expect(EightToBase8).toEqual('24') 368 | }) 369 | }) 370 | 371 | describe('Test concatAll function', ()=> { 372 | test("Test concatAll Two dimenstional array", ()=> { 373 | const arr = [[1], [2, 3], [], [4]]; 374 | 375 | const result = concatAll(arr); 376 | expect(result).toEqual([1, 2, 3, 4]); 377 | }) 378 | }); 379 | 380 | describe('Test zip function', ()=> { 381 | test('test zip function', () => { 382 | 383 | const zipper = zip( 384 | [1, 2, 3], 385 | [4, 5, 6], 386 | function addElemOfBothArray(left, right) { 387 | return left + right; 388 | } 389 | ); 390 | 391 | expect(zipper).toEqual([5, 7, 9]); 392 | }) 393 | }); 394 | 395 | describe("Test sort algorithm", () => { 396 | const nums = [10, 5, 3, 8, 2, 6, 4, 7, 9, 1]; 397 | const supposedAnswer = [...nums].sort((a, b) => a- b) 398 | 399 | //Bubble sort test 400 | test("Test for bubble sort algorithm", ()=> { 401 | expect(bubbleSort(nums)).toEqual(supposedAnswer) 402 | }) 403 | 404 | //insertion sort test 405 | test("Test for insertion sort", ()=> { 406 | expect(insertionSort(nums)).toEqual(supposedAnswer) 407 | }) 408 | 409 | //merge sort test 410 | test("Test for merge sort",()=> { 411 | expect(mergeSort(nums)).toEqual(supposedAnswer) 412 | }); 413 | 414 | //quick sort test 415 | // test("Test for quick sort", ()=> { 416 | // expect(quickSort(nums)).toEqual(supposedAnswer) 417 | // }); 418 | 419 | // //radix sort test 420 | // test("Test for radix sort", ()=> { 421 | // expect(radixSort(nums)).toEqual(supposedAnswer) 422 | // }) 423 | }); 424 | 425 | describe("Test for nested array", ()=> { 426 | test("Test nested function", ()=> { 427 | const nested = [1, 2, 3]; 428 | const nested2 = [1, [2], 3]; 429 | const nested3 = [[[[[[[[[[[[[[[[[[[[5]]]]]]]]]]]]]]]]]]]]; 430 | const nested4 = [10, [12, 14, [1], [16, [20]]], 10, 11]; 431 | 432 | expect(nestedAdd(nested)).toBe(6) 433 | expect(nestedAdd(nested2)).toBe(6) 434 | expect(nestedAdd(nested3)).toBe(5) 435 | expect(nestedAdd(nested4)).toBe(94) 436 | //nestedAdd2 function 437 | expect(nestedAdd2(nested)).toBe(6) 438 | expect(nestedAdd2(nested2)).toBe(6) 439 | expect(nestedAdd2(nested3)).toBe(5) 440 | expect(nestedAdd2(nested4)).toBe(94) 441 | }) 442 | }); 443 | 444 | describe("Test for factorial function", ()=> { 445 | test("factorial function test", ()=> { 446 | expect(factorial(5)).toBe(120); 447 | expect(factorial2(5)).toBe(120); 448 | }) 449 | }); 450 | 451 | describe("Test for search algorithms", ()=> { 452 | const data = [0, 5, 10, 12, 15, 19, 21, 22, 24, 30]; 453 | const dataObj = [ 454 | { id: 1, name: "Sam" }, 455 | { id: 3, name: "Sarah" }, 456 | { id: 5, name: "John" }, 457 | { id: 6, name: "Burke" }, 458 | { id: 10, name: "Simona" }, 459 | { id: 12, name: "Asim" }, 460 | { id: 13, name: "Niki" }, 461 | { id: 15, name: "Aysegul" }, 462 | { id: 17, name: "Kyle" }, 463 | { id: 18, name: "Jem" }, 464 | { id: 19, name: "Marc" }, 465 | { id: 21, name: "Chris" }, 466 | ] 467 | test("binary search test",()=> { 468 | expect(binarySearch(12, data)).toBe(12); 469 | expect(binarySearch(3, dataObj)).toEqual({ id: 3, name: "Sarah" }); 470 | expect(binarySearch(100, data)).toBe('not found') 471 | }); 472 | 473 | test("linear search test", ()=> { 474 | expect(linearSearch(12, data)).toBe(12); 475 | expect(linearSearch(3, dataObj)).toEqual({id: 3, name: "Sarah"}); 476 | expect(linearSearch(100, data)).toBe("not found") 477 | }); 478 | }) 479 | 480 | describe("Test for tree trevarsa algorithms", ()=> { 481 | //Test for preorder 482 | test("Test for preorder algorithm", ()=> { 483 | expect(preorder(tree, [])).toEqual([8,4,3,2,5,7,6,12,10,9,11]) 484 | }) 485 | 486 | //Test postorder 487 | test("Test for postorder algorithm", () => { 488 | expect(postorder(tree, [])).toEqual([2,3,6,7, 5,4, 9, 11, 10, 12, 8]) 489 | }); 490 | 491 | //Test inorder 492 | test("Test for inorder algorithm", () => { 493 | expect(inorder(tree, [])).toEqual([2,3,4,5,6,7, 6, 8,9,10,11,12]); 494 | }); 495 | 496 | //Test breadth 497 | test("Test for breadth algorithm", ()=> { 498 | expect(breadth([tree], [])).toEqual([8,4,12,3,5,10,2,7,9,11,6]) 499 | }) 500 | }) -------------------------------------------------------------------------------- /src/datastructures.js: -------------------------------------------------------------------------------- 1 | //--------------ARRAY LIST ALGORITHM USING JAVASCRIPT OBJECT------------- 2 | 3 | export class ArrayList { 4 | constructor() { 5 | this.length = 0; 6 | } 7 | push(num) { 8 | this[this.length] = num; 9 | this.length++; 10 | } 11 | pop() { 12 | var last = this[this.length - 1]; 13 | delete this[this.length - 1]; 14 | this.length--; 15 | return last; 16 | } 17 | get(index) { 18 | return this[index]; 19 | } 20 | shift() { 21 | if (this.length > 0) { 22 | var answer = this[0]; 23 | this[0] = null; 24 | for (let i = 0; i < this.length; i++) { 25 | this[i] = this[i + 1]; 26 | } 27 | delete this[this.length - 1]; 28 | this.length--; 29 | return answer; 30 | } 31 | return null; 32 | } 33 | delete(index) { 34 | var removedItem = this[index]; 35 | this.length--; 36 | delete this[index]; 37 | if (index !== this.length) { 38 | for (let i = index; i < this.length; i++) { 39 | this[i] = this[i + 1]; 40 | delete this[i + 1]; 41 | } 42 | } 43 | return removedItem; 44 | } 45 | } 46 | 47 | var test = new ArrayList(); 48 | 49 | // test.push(3); 50 | // test.push(4); 51 | // test.push(8); 52 | // test.push(9); 53 | // //// console.log(test.length); 54 | // //// console.log(test); 55 | // //// console.log(test.delete(1)); 56 | // //// console.log(test); 57 | 58 | export class Node { 59 | constructor(arr) { 60 | this.arr = arr; 61 | } 62 | complete(string) { 63 | var answer = []; 64 | var findcheck = string.toLowerCase(); 65 | this.arr.forEach((elem) => { 66 | var check = elem.toLowerCase(); 67 | if (findcheck[0] == check[0] && check.includes(findcheck)) { 68 | if (answer.length < 3) { 69 | answer.push(check); 70 | } 71 | } 72 | }); 73 | return answer; 74 | } 75 | } 76 | 77 | import { hash1, hash2, hash3 } from "./hashing-functions.js"; //personal coded hashing functions 78 | var h1 = hash1(100); 79 | var h2 = hash2(100); 80 | var h3 = hash3(100); 81 | 82 | export class BloomFilter { 83 | constructor() { 84 | this.array = new Array(100).fill(0); // makes an array of 100 elements and fill them all up with 0 i.e [0,0, 0,...] 85 | this.h1 = h1; 86 | this.h2 = h2; 87 | this.h3 = h3; 88 | } 89 | 90 | add(string) { 91 | var h1 = this.h1(string); 92 | var h2 = this.h2(string); 93 | var h3 = this.h3(string); 94 | this.array[h1] = 1; 95 | this.array[h2] = 1; 96 | this.array[h3] = 1; 97 | } 98 | contains(string) { 99 | var h1 = this.h1(string); 100 | var h2 = this.h2(string); 101 | var h3 = this.h3(string); 102 | 103 | if (this.array[h1] === 0 || this.array[h2] === 0 || this.array[h3] === 0) { 104 | return false; 105 | } else { 106 | return true; 107 | } 108 | } 109 | } 110 | 111 | var bf = new BloomFilter(); 112 | // // console.log(bf.contains("Brian")); //false 113 | // // console.log(bf.contains("semona")); //false 114 | // // console.log(bf.contains("serah")); //false 115 | // bf.add("Brian"); 116 | // // console.log(bf.contains("Brian")); //true 117 | // // console.log(bf.contains("semona")); //false 118 | // // console.log(bf.contains("serah")); //false 119 | 120 | //-------------- QUEUE (DATA STRUCTURE) ALGORITHM ------------- 121 | 122 | export class Queue { 123 | constructor() { 124 | this._length = 0; 125 | this._track = 0; 126 | } 127 | enqueue(value) { 128 | this[this._length + this._track] = value; 129 | this._length++; 130 | } 131 | dequeue() { 132 | var answer = this[this._track]; 133 | delete this[this._track]; 134 | this._track++; 135 | this._length--; 136 | return answer; 137 | } 138 | peek() { 139 | return this[this._track]; 140 | } 141 | } 142 | 143 | // const queue = new Queue(); 144 | // queue.enqueue(1); 145 | // queue.enqueue(9); 146 | // queue.enqueue(7); 147 | // queue.enqueue(6); 148 | // queue.enqueue(100); 149 | // queue.dequeue(); 150 | // queue.enqueue(78); 151 | // queue.dequeue(); 152 | 153 | // // console.log(queue.peek()); 154 | // // console.log(queue); 155 | 156 | //ALL ABOVE METHODS IN THE QUEUE OBJ ALL HAVE A CONSTANT TIME COMPLEXITY 157 | 158 | //-------------- LINKED LIST (DATA STRUCTURE) ALGORITHM ------------- 159 | 160 | export class Linkedlist { 161 | constructor() { 162 | this.head = null; 163 | this._pointer = this.head; 164 | this._length = 0; 165 | } 166 | insert(elem) { 167 | this._length++; 168 | if (this.head === null) { 169 | this.head = { 170 | value: elem, 171 | next: this._pointer, 172 | }; 173 | this._pointer = this.head; 174 | } else if (this._pointer.next === null) { 175 | if (this.contains(elem)) return "value already exists"; //Avoid repeatition of values; 176 | // this.previous = { ...this._pointer }; 177 | this._pointer.next = { 178 | value: elem, 179 | next: null, 180 | }; 181 | // // console.log(this.previous); 182 | this._pointer = this._pointer.next; 183 | } 184 | } 185 | insertIn(position, value) { 186 | var currentNode = this.head; 187 | if (!this.contains(position)) 188 | throw new Error(`${position}: position to be inserted doesn't exist`); 189 | if (position === this._pointer.value) { 190 | this.insert(value); 191 | } else { 192 | if (this.contains(value)) 193 | throw new Error(`${value}: value already exist`); // Avoid duplicated values 194 | while (currentNode.value !== position) { 195 | currentNode = currentNode.next; 196 | } 197 | var temp = { ...currentNode.next }; 198 | currentNode.next = { 199 | value, 200 | next: temp, 201 | }; 202 | this._length++; 203 | } 204 | } 205 | InsertNewHead(value) { 206 | if (this.contains(value)) return "value already exist"; 207 | var temp = { ...this.head }; 208 | this.head = { 209 | value, 210 | next: temp, 211 | }; 212 | this._length++; 213 | } 214 | isHead(node) { 215 | node === this.head ? true : false; 216 | } 217 | isTail(node) { 218 | node === this._pointer ? true : false; 219 | } 220 | get(value) { 221 | if (!this.contains(value)) 222 | throw new Error(`${value} : value doesn't exist`); 223 | var currentNode = this.head; 224 | if (currentNode.value === value) { 225 | return currentNode; 226 | } else if (this._pointer.value === value) { 227 | return this._pointer; 228 | } else { 229 | while (currentNode.value !== value) { 230 | currentNode = currentNode.next; 231 | } 232 | } 233 | return currentNode; 234 | } 235 | contains(value) { 236 | var check = this.head; 237 | if (check === null) return false; 238 | if (check.value === value) return true; 239 | 240 | while (check.next !== null) { 241 | check = check.next; 242 | if (check.value === value) return true; 243 | } 244 | return false; 245 | } 246 | removeHead() { 247 | this.head = this.head.next; 248 | this._length--; 249 | } 250 | remove(value) { 251 | var currentNode = this.head; 252 | var temp = null; 253 | 254 | if (!this.contains(value)) 255 | throw new Error(`${value} : value doesn't exist`); 256 | if (value === this._pointer.value) { 257 | this.removeTail(); 258 | } else if (this.head.value === value) { 259 | this.removeHead(); 260 | } else { 261 | while (currentNode["next"].value !== value) { 262 | currentNode = currentNode.next; 263 | } 264 | var removed = { ...currentNode.next }; 265 | temp = { ...currentNode["next"].next }; 266 | currentNode.next = null; 267 | currentNode.next = temp; 268 | this._length--; 269 | return removed; 270 | } 271 | } 272 | reverseList() { 273 | var currentNode = { ...this.head }; 274 | var reverse = this.head; 275 | var counter = 0; 276 | while (currentNode.next !== null) { 277 | var temp1 = { ...reverse }; 278 | var temp2 = { ...currentNode.next }; 279 | reverse = temp2; 280 | reverse.next = temp1; 281 | currentNode = currentNode.next; 282 | } 283 | var test = reverse; 284 | while (counter < this._length - 1) { 285 | test = test.next; 286 | counter++; 287 | } 288 | test.next = null; 289 | this._pointer = test; 290 | this.head = reverse; 291 | } 292 | removeTail() { 293 | this._length--; 294 | var loop = this.head; 295 | var self = this; 296 | function rmLastNode(loop) { 297 | if (loop["next"]["next"] !== null) { 298 | return rmLastNode(loop["next"]); 299 | } else if (loop["next"]["next"] === null) { 300 | var temp = loop["next"]; 301 | loop["next"] = null; 302 | self._pointer = loop; 303 | return temp; 304 | } 305 | } 306 | return rmLastNode(loop); 307 | } 308 | } 309 | 310 | var test23 = new Linkedlist(); 311 | // test23.insert(2); 312 | // test23.insert(7); 313 | // test23.InsertNewHead(3); 314 | // test23.insert(99); 315 | // // console.log(test23.get(2)); 316 | // test23.reverseList(); 317 | // test23.remove(10); 318 | // test23.insertIn(2, 76); 319 | // // console.log(test23.removeTail()); 320 | // // console.log(test23.contains(10)); 321 | // // console.log(test23.removeTail()); 322 | // test23.insert(100); 323 | // // console.log(test23); 324 | 325 | //-------------- HASHTABLE (DATA STRUCTURE) ALGORITHM ------------- 326 | 327 | import { _hash } from "./hashing-functions.js"; 328 | 329 | export class HashTable { 330 | constructor(range) { 331 | this._storage = {}; 332 | this._range = range; 333 | this._length = 0; 334 | } 335 | insert(string) { 336 | var random = _hash(string, this._range); 337 | if (random in this._storage && this._storage[random] !== string) { 338 | if (!Array.isArray(this._storage[random])) { 339 | this._storage[random] = [this._storage[random]]; 340 | } 341 | if (Array.isArray(this._storage[random])) { 342 | this._storage[random].push(string); 343 | } 344 | } else if (!(random in this._storage)) { 345 | this._storage[random] = string; 346 | this._length++; 347 | } 348 | if (this._length === Math.floor(this._range / 2)) this._range *= 2; 349 | return random; 350 | } 351 | remove(string) { 352 | var answer; 353 | for (let keys in this._storage) { 354 | if (this._storage[keys] === string) { 355 | answer = `key: ${keys} | value: ${string}`; 356 | delete this._storage[keys]; 357 | this._length--; 358 | return answer; 359 | } 360 | if (Array.isArray(this._storage[keys])) { 361 | this._storage[keys].forEach((elem, index) => { 362 | if (elem === string) { 363 | this._storage[keys].splice(index, 1); 364 | answer = `key: ${keys} | value: ${elem}`; 365 | } 366 | }); 367 | } 368 | } 369 | answer = "not found"; 370 | return answer; 371 | } 372 | retrieve(key) { 373 | if (key in this._storage) { 374 | return this._storage[key]; 375 | } 376 | throw new Error(`${key} not found`); 377 | } 378 | } 379 | 380 | // var hashtable = new HashTable(100); 381 | // hashtable.insert("kemi"); 382 | // hashtable.insert("tunde"); 383 | // hashtable.insert("shola"); 384 | // hashtable.insert("tope"); 385 | // hashtable.insert("kemi"); 386 | // hashtable.insert("advise"); 387 | // hashtable.insert("compromise"); 388 | // hashtable.insert("abc"); 389 | // // console.log(hashtable.retrieve(8)); 390 | // // console.log(hashtable); 391 | 392 | // // console.log(hashtable.remove("abc")); 393 | // // console.log(hashtable); 394 | 395 | //-------------- GRAPH (DATA STRUCTURE) ALGORITHM ------------- 396 | 397 | export class Graph { 398 | constructor(value) { 399 | this[value] = { value, connections: [] }; 400 | } 401 | addNode(value) { 402 | if (!(value in this)) { 403 | this[value] = { value, connections: [] }; 404 | } 405 | } 406 | addEdge(nodeA, ...rest) { 407 | const nodeB = [...rest]; 408 | for (let i = 0; i < nodeB.length; i++) { 409 | if (nodeA in this && nodeB[i] in this) { 410 | if (!this[nodeA].connections.includes(nodeB[i])) 411 | this[nodeA].connections.push(nodeB[i]); 412 | if (!this[nodeB[i]].connections.includes(nodeA)) 413 | this[nodeB[i]].connections.push(nodeA); 414 | } else { 415 | this.addNode(nodeA); 416 | this.addNode(nodeB[i]); 417 | this.addEdge(nodeA, nodeB[i]); 418 | } 419 | } 420 | } 421 | removeNode(node) { 422 | var temp = { ...this[node] }; 423 | if (node in this) { 424 | for (let i = 0; i < this[node].connections.length; i++) { 425 | const nodeConnections = this[node].connections[i]; 426 | const connectedNodes = this[nodeConnections].connections; 427 | const index = connectedNodes.indexOf(node); 428 | connectedNodes.splice(index, 1); 429 | } 430 | delete this[node]; 431 | return temp; 432 | } 433 | throw new Error(`requested node does not exist! 434 | Expected to find ${node}`); 435 | } 436 | 437 | depthFirstTraversal(value) { 438 | const visited = {}; 439 | const graph = this; 440 | function depthFirst(value, arr) { 441 | if (!(value in visited)) { 442 | visited[value] = true; 443 | arr.push(value); 444 | const connectedNodes = graph[value].connections; 445 | for (let i = 0; i < connectedNodes.length; i++) { 446 | depthFirst(connectedNodes[i], arr); 447 | } 448 | } 449 | return arr; 450 | } 451 | return depthFirst(value, []); 452 | } 453 | 454 | breadthFirstTraversal(value) { 455 | const visited = {}; 456 | const arr = [...graph[value].connections]; 457 | visited[value] = true; 458 | const result = [value]; 459 | 460 | for (let i = 0; i < arr.length; i++) { 461 | if (!(arr[i] in visited)) { 462 | visited[arr[i]] = true; 463 | var temp = arr[i]; 464 | result.push(arr[i]); 465 | arr.push(...this[temp].connections); 466 | } 467 | } 468 | return result; 469 | } 470 | } 471 | 472 | const graph = new Graph(7); 473 | graph.addNode(8); 474 | graph.addEdge(7, 8, 10, 9, 11, 12, 13, 14); 475 | graph.removeNode(12); 476 | graph.addNode(10); 477 | graph.addEdge(7, 8); 478 | graph.addEdge(7, 9); 479 | graph.addEdge(8, 9); 480 | graph.addEdge(9, 100); 481 | graph.addEdge(10, 24); 482 | graph.addEdge(12, 25); 483 | // console.log(graph); 484 | // console.log(graph.depthFirstTraversal(7)); 485 | // console.log(graph.breadthFirstTraversal(7)); 486 | 487 | //Stack Datastructure 488 | 489 | export class Stack { 490 | #length; 491 | constructor() { 492 | this.#length = 0; 493 | } 494 | push(item) { 495 | this[this.#length] = item; 496 | this.#length++; 497 | return item; 498 | } 499 | pop() { 500 | if (this.#length === 0) { 501 | throw new Error( 502 | "Empty Stack; There is nothing in this Stack, push first" 503 | ); 504 | } 505 | const result = this[this.#length - 1]; 506 | delete this[this.#length - 1]; 507 | this.#length--; 508 | return result; 509 | } 510 | get length() { 511 | return this.#length; 512 | } 513 | } 514 | 515 | const stackDS = new Stack(); 516 | // console.log(stackDS.push({ trial: "okay" })); //{ trial: "okay" } 517 | // console.log(stackDS.push(["cool"])); //["cool"] 518 | // console.log(stackDS.push("working")); //"working" 519 | // console.log(stackDS.length); //3 520 | // console.log(stackDS.pop()); //"working" 521 | // console.log(stackDS.length); //2 522 | // console.log(stackDS.pop()); //["cool"] 523 | // console.log(stackDS.pop()); //{ trial: "okay" } 524 | // console.log(stackDS.pop()); // "Empty Stack; There is nothing in this Stack, push first" 525 | -------------------------------------------------------------------------------- /testSites/testSite.js: -------------------------------------------------------------------------------- 1 | function times10(n) { 2 | return n * 10; 3 | } 4 | function memoize(cb) { 5 | const cache = {}; 6 | 7 | return function memoTimes10(n) { 8 | if (`${n} * 10` in cache) { 9 | console.log(`Fetching value from cache ${n} * 10`); 10 | return cache[`${n} * 10`]; 11 | } 12 | console.log("Not cached, Calculating and chaching value"); 13 | return (cache[`${n} * 10`] = cb(n)); 14 | }; 15 | } 16 | 17 | const memoClosureTimes10 = memoize(times10); 18 | // console.log(memoClosureTimes10(9)); 19 | // console.log(memoClosureTimes10(9)); 20 | function memo() { 21 | var cache = {}; 22 | return function factorial(n) { 23 | if (`${n}!` in cache) { 24 | return cache[`${n}!`]; 25 | } 26 | if (n <= 1) { 27 | return 1; 28 | } 29 | var result = n * factorial(n - 1); 30 | cache[`${n}!`] = result; 31 | return result; 32 | }; 33 | } 34 | const factorial = memo(); 35 | // console.log(factorial(5)); 36 | // console.log(factorial(6)); 37 | 38 | function linearSearch(array, find) { 39 | result = "not found"; 40 | array.forEach((elem, i) => { 41 | if (elem === find) { 42 | return (result = `${elem} at index ${i}`); 43 | } 44 | }); 45 | return result; 46 | } 47 | // console.log(linearSearch([2, 6, 7, 90, 103], 90)); 48 | 49 | function binarySearch(array, find) { 50 | var half = Math.floor(array.length / 2); 51 | 52 | if (array[half] == find) { 53 | return `${array[half]} at index ${half}`; 54 | } else if (array.length === 1 && array[0] !== find) { 55 | return "not found"; 56 | } else if (find < array[half]) { 57 | return binarySearch(array.slice(0, half), find); 58 | } else if (find > array[half]) { 59 | return binarySearch(array.slice(half + 1, array.length), find); 60 | } 61 | } 62 | // console.log(binarySearch([2, 6, 7, 90, 103], 90)); 63 | 64 | function mergeSort(array) { 65 | var first; 66 | var second; 67 | var half = Math.floor(array.length / 2); 68 | 69 | function merge(left, right) { 70 | var result = []; 71 | while (left.length && right.length) { 72 | if (left[0] < right[0]) { 73 | result.push(left.shift()); 74 | } else { 75 | result.push(right.shift()); 76 | } 77 | } 78 | return result.concat(left, right); 79 | } 80 | 81 | if (array.length > 1) { 82 | first = mergeSort(array.slice(0, half)); 83 | second = mergeSort(array.slice(half, array.length)); 84 | return merge(first, second); 85 | } 86 | return array; 87 | } 88 | 89 | // console.log(mergeSort([1, 5, 7, 4, 2, 3, 6])); 90 | class Linkedlist { 91 | constructor() { 92 | this.head = null; 93 | this._pointer = this.head; 94 | this._length = 0; 95 | } 96 | insert(elem) { 97 | this._length++; 98 | if (this.head === null) { 99 | this.head = { 100 | value: elem, 101 | next: this._pointer, 102 | }; 103 | this._pointer = this.head; 104 | } else if (this._pointer.next === null) { 105 | if (this.contains(elem)) return "value already exists"; //Avoid repeatition of values; 106 | // this.previous = { ...this._pointer }; 107 | this._pointer.next = { 108 | value: elem, 109 | next: null, 110 | }; 111 | // console.log(this.previous); 112 | this._pointer = this._pointer.next; 113 | } 114 | } 115 | insertIn(position, value) { 116 | var currentNode = this.head; 117 | if (!this.contains(position)) 118 | return "position to be inserted doesn't exist"; 119 | if (position === this._pointer.value) { 120 | this.insert(value); 121 | } else { 122 | if (this.contains(value)) return "value already exist"; // Avoid duplicated values 123 | while (currentNode.value !== position) { 124 | currentNode = currentNode.next; 125 | } 126 | var temp = { ...currentNode.next }; 127 | currentNode.next = { 128 | value, 129 | next: temp, 130 | }; 131 | this._length++; 132 | } 133 | } 134 | InsertNewHead(value) { 135 | if (this.contains(value)) return "value already exist"; 136 | var temp = { ...this.head }; 137 | this.head = { 138 | value, 139 | next: temp, 140 | }; 141 | this._length++; 142 | } 143 | isHead(node) { 144 | node === this.head ? true : false; 145 | } 146 | isTail(node) { 147 | node === this._pointer ? true : false; 148 | } 149 | get(value) { 150 | if (!this.contains(value)) return "value doesn't exist"; 151 | var currentNode = this.head; 152 | if (currentNode.value === value) { 153 | return currentNode; 154 | } else if (this._pointer.value === value) { 155 | return this._pointer; 156 | } else { 157 | while (currentNode.value !== value) { 158 | currentNode = currentNode.next; 159 | } 160 | } 161 | return currentNode; 162 | } 163 | contains(value) { 164 | var check = this.head; 165 | if (check === null) return false; 166 | if (check.value === value) return true; 167 | 168 | while (check.next !== null) { 169 | check = check.next; 170 | if (check.value === value) return true; 171 | } 172 | return false; 173 | } 174 | removeHead() { 175 | this.head = this.head.next; 176 | this._length--; 177 | } 178 | remove(value) { 179 | var currentNode = this.head; 180 | var temp = null; 181 | 182 | if (!this.contains(value)) return "value do not exit"; 183 | if (value === this._pointer.value) { 184 | this.removeTail(); 185 | } else if (this.head.value === value) { 186 | this.removeHead(); 187 | } else { 188 | while (currentNode["next"].value !== value) { 189 | currentNode = currentNode.next; 190 | } 191 | var removed = { ...currentNode.next }; 192 | temp = { ...currentNode["next"].next }; 193 | currentNode.next = null; 194 | currentNode.next = temp; 195 | this._length--; 196 | return removed; 197 | } 198 | } 199 | reverseList() { 200 | var currentNode = { ...this.head }; 201 | var reverse = this.head; 202 | var counter = 0; 203 | while (currentNode.next !== null) { 204 | var temp1 = { ...reverse }; 205 | var temp2 = { ...currentNode.next }; 206 | reverse = temp2; 207 | reverse.next = temp1; 208 | currentNode = currentNode.next; 209 | } 210 | var test = reverse; 211 | while (counter < this._length - 1) { 212 | test = test.next; 213 | counter++; 214 | } 215 | test.next = null; 216 | this._pointer = test; 217 | this.head = reverse; 218 | } 219 | removeTail() { 220 | this._length--; 221 | var loop = this.head; 222 | var self = this; 223 | function rmLastNode(loop) { 224 | if (loop["next"]["next"] !== null) { 225 | return rmLastNode(loop["next"]); 226 | } else if (loop["next"]["next"] === null) { 227 | var temp = loop["next"]; 228 | loop["next"] = null; 229 | self._pointer = loop; 230 | return temp; 231 | } 232 | } 233 | return rmLastNode(loop); 234 | } 235 | } 236 | 237 | var test23 = new Linkedlist(); 238 | // test23.insert(2); 239 | // test23.insert(7); 240 | // test23.InsertNewHead(3); 241 | // test23.insert(99); 242 | // console.log(test23.get(2)); 243 | // test23.reverseList(); 244 | // test23.remove(10); 245 | // test23.insertIn(2, 76); 246 | // console.log(test23.removeTail()); 247 | // console.log(test23.contains(10)); 248 | // console.log(test23.removeTail()); 249 | // test23.insert(100); 250 | // console.log(test23); 251 | 252 | class Queue { 253 | constructor() { 254 | this._length = 0; 255 | this._track = 0; 256 | } 257 | enqueue(value) { 258 | this[this._length + this._track] = value; 259 | this._length++; 260 | } 261 | dequeue() { 262 | var answer = this[this._track]; 263 | delete this[this._track]; 264 | this._track++; 265 | this._length--; 266 | return answer; 267 | } 268 | peek() { 269 | return this[this._track]; 270 | } 271 | } 272 | 273 | function tesfn() { 274 | return "ok"; 275 | } 276 | // const queue = new Queue(); 277 | // queue.enqueue(1); 278 | // queue.enqueue(9); 279 | // queue.enqueue(7); 280 | // queue.enqueue(6); 281 | // queue.enqueue(100); 282 | // queue.dequeue(); 283 | // queue.enqueue(78); 284 | // queue.dequeue(); 285 | 286 | // console.log(queue.peek()); 287 | // console.log(queue); 288 | const { hash, hash2, _hash } = require("./hashing functions"); 289 | 290 | class HashTable { 291 | constructor(range) { 292 | this._storage = {}; 293 | this._range = range; 294 | this._length = 0; 295 | } 296 | insert(string) { 297 | var random = _hash(string, this._range); 298 | if (random in this._storage && this._storage[random] !== string) { 299 | if (!Array.isArray(this._storage[random])) { 300 | this._storage[random] = [this._storage[random]]; 301 | } 302 | if (Array.isArray(this._storage[random])) { 303 | this._storage[random].push(string); 304 | } 305 | } else if (!(random in this._storage)) { 306 | this._storage[random] = string; 307 | this._length++; 308 | } 309 | if (this._length === Math.floor(this._range / 2)) this._range *= 2; 310 | return random; 311 | } 312 | remove(string) { 313 | var answer; 314 | for (let keys in this._storage) { 315 | if (this._storage[keys] === string) { 316 | answer = `key: ${keys} value: ${string}`; 317 | delete this._storage[keys]; 318 | this._length--; 319 | return answer; 320 | } 321 | if (Array.isArray(this._storage[keys])) { 322 | this._storage[keys].forEach((elem, index) => { 323 | if (elem === string) { 324 | this._storage[keys].splice(index, 1); 325 | answer = `key: ${keys} value: ${elem}`; 326 | } 327 | }); 328 | } 329 | } 330 | answer = "not found"; 331 | return answer; 332 | } 333 | retrieve(key) { 334 | if (key in this._storage) { 335 | return this._storage[key]; 336 | } 337 | return "not found"; 338 | } 339 | } 340 | 341 | // var hashtable = new HashTable(100); 342 | // hashtable.insert("kemi"); 343 | // hashtable.insert("tunde"); 344 | // hashtable.insert("shola"); 345 | // hashtable.insert("tope"); 346 | // hashtable.insert("kemi"); 347 | // hashtable.insert("advise"); 348 | // hashtable.insert("compromise"); 349 | // hashtable.insert("abc"); 350 | // console.log(hashtable.retrieve(8)); 351 | // console.log(hashtable); 352 | 353 | // console.log(hashtable.remove("abc")); 354 | // console.log(hashtable); 355 | 356 | class Tree { 357 | constructor(value) { 358 | this.value = value; 359 | this.children = []; 360 | } 361 | insertChild(value) { 362 | const newTree = new Tree(value); 363 | this.children.push(newTree); 364 | return newTree; 365 | } 366 | 367 | // Uses a Depth-First Traversal 368 | static traverse(tree, func = console.log) {} 369 | 370 | contains(searchValue) {} 371 | 372 | static size(tree) {} 373 | 374 | static find(tree, value) {} 375 | 376 | insert(parentTree, value) {} 377 | 378 | remove(value) { 379 | const search = this.children; 380 | for (let i = 0; i < search.length; i++) { 381 | if (search[i].value === value) { 382 | var temp = search[i]; 383 | search.splice(1, i); 384 | return temp; 385 | } 386 | } 387 | } 388 | 389 | reorder(node1, node2) {} 390 | } 391 | 392 | const tree = new Tree("Parent"); 393 | // tree.insertChild("son"); 394 | // // console.log( 395 | // const tree2 = tree.insertChild("Daughter"); 396 | // // ); 397 | // tree2.insertChild("Abduls"); 398 | // console.log(tree); 399 | 400 | class BinaryTree { 401 | constructor() { 402 | this.value = null; 403 | this.left = null; 404 | this.right = null; 405 | } 406 | insert(value) { 407 | if (this.value === null) this.value = value; 408 | if (this.left === null && value < this.value) { 409 | var left = new BinaryTree(); 410 | this.left = left; 411 | this.left.insert(value); 412 | } else if (this.right === null && value > this.value) { 413 | var right = new BinaryTree(); 414 | this.right = right; 415 | this.right.insert(value); 416 | } else if (this.left !== null && value < this.value) { 417 | this.left.insert(value); 418 | } else if (this.right !== null && value > this.value) { 419 | this.right.insert(value); 420 | } 421 | } 422 | preTraverse() { 423 | function preOrderTraverse(tree, arr) { 424 | arr.push(tree.value); 425 | if (tree.left !== null) preOrderTraverse(tree.left, arr); 426 | if (tree.right !== null) preOrderTraverse(tree.right, arr); 427 | return arr; 428 | } 429 | return preOrderTraverse(this, []); 430 | } 431 | sortedTraverse() { 432 | function inOrderTraverse(tree, arr) { 433 | if (tree.left !== null) inOrderTraverse(tree.left, arr); 434 | arr.push(tree.value); 435 | if (tree.right !== null) inOrderTraverse(tree.right, arr); 436 | return arr; 437 | } 438 | return inOrderTraverse(this, []); 439 | } 440 | postTraverse() { 441 | function postOrderTraverse(tree, arr) { 442 | if (tree.left !== null) postOrderTraverse(tree.left, arr); 443 | if (tree.right !== null) postOrderTraverse(tree.right, arr); 444 | arr.push(tree.value); 445 | return arr; 446 | } 447 | return postOrderTraverse(this, arr); 448 | } 449 | 450 | contains(value) { 451 | var result = false; 452 | function answer(tree) { 453 | if (tree.value === value) return (result = true); 454 | if (tree.left !== null) answer(tree.left); 455 | if (tree.right !== null) answer(tree.right); 456 | } 457 | answer(this); 458 | return result; 459 | } 460 | } 461 | 462 | // const btree = new BinaryTree(); 463 | // btree.insert(7); 464 | // btree.insert(9); 465 | // btree.insert(1); 466 | // btree.insert(10); 467 | // btree.insert(2); 468 | // btree.insert(0); 469 | // btree.insert(8); 470 | // btree.insert(11); 471 | // console.log(btree); 472 | // console.log(btree.contains(0)); 473 | // console.log(btree.sortedTraverse()); 474 | 475 | function preOrderTraverse(tree, arr) { 476 | arr.push(tree.value); 477 | if (tree.left !== null) preOrderTraverse(tree.left, arr); 478 | if (tree.right !== null) preOrderTraverse(tree.right, arr); 479 | return arr; 480 | } 481 | function inOrderTraverse(tree, arr) { 482 | if (tree.left !== null) inOrderTraverse(tree.left, arr); 483 | arr.push(tree.value); 484 | if (tree.right !== null) inOrderTraverse(tree.right, arr); 485 | return arr; 486 | } 487 | function postOrderTraverse(tree, arr) { 488 | if (tree.left !== null) postOrderTraverse(tree.left, arr); 489 | if (tree.right !== null) postOrderTraverse(tree.right, arr); 490 | arr.push(tree.value); 491 | return arr; 492 | } 493 | 494 | // var answer = preOrderTraverse(btree, []); 495 | // console.log(answer); 496 | 497 | class Graph { 498 | constructor(value) { 499 | this[value] = { value, connections: [] }; 500 | } 501 | addNode(value) { 502 | if (!(value in this)) { 503 | this[value] = { value, connections: [] }; 504 | } 505 | } 506 | addEdge(nodeA, ...rest) { 507 | const nodeB = [...rest]; 508 | for (let i = 0; i < nodeB.length; i++) { 509 | if (nodeA in this && nodeB[i] in this) { 510 | if (!this[nodeA].connections.includes(nodeB[i])) 511 | this[nodeA].connections.push(nodeB[i]); 512 | if (!this[nodeB[i]].connections.includes(nodeA)) 513 | this[nodeB[i]].connections.push(nodeA); 514 | } else { 515 | this.addNode(nodeA); 516 | this.addNode(nodeB[i]); 517 | this.addEdge(nodeA, nodeB[i]); 518 | } 519 | } 520 | } 521 | removeNode(node) { 522 | var temp = { ...this[node] }; 523 | if (node in this) { 524 | for (let i = 0; i < this[node].connections.length; i++) { 525 | const nodeConnections = this[node].connections[i]; 526 | const connectedNodes = this[nodeConnections].connections; 527 | const index = connectedNodes.indexOf(node); 528 | connectedNodes.splice(index, 1); 529 | } 530 | delete this[node]; 531 | return temp; 532 | } 533 | } 534 | } 535 | 536 | const graph = new Graph(7); 537 | graph.addNode(8); 538 | graph.addEdge(7, 8, 10, 9, 11, 12, 13, 14); 539 | graph.removeNode(12); 540 | graph.addNode(10); 541 | graph.addEdge(7, 8); 542 | graph.addEdge(7, 9); 543 | graph.addEdge(8, 9); 544 | graph.addEdge(9, 100); 545 | graph.addEdge(10, 24); 546 | graph.addEdge(12, 25); 547 | console.log(graph); 548 | 549 | function depthFirstTraversal(value, graph) { 550 | const visited = {}; 551 | function depthFirst(value, arr) { 552 | if (!(value in visited)) { 553 | visited[value] = true; 554 | arr.push(value); 555 | const connectedNodes = graph[value].connections; 556 | for (let i = 0; i < connectedNodes.length; i++) { 557 | depthFirst(connectedNodes[i], arr); 558 | } 559 | } 560 | return arr; 561 | } 562 | return depthFirst(value, []); 563 | } 564 | 565 | // console.log(depthFirstTraversal(7, graph)); 566 | 567 | function breadthFirstTraversal(value, graph) { 568 | const visited = {}; 569 | const arr = [...graph[value].connections]; 570 | visited[value] = true; 571 | const result = [value]; 572 | 573 | for (let i = 0; i < arr.length; i++) { 574 | if (!(arr[i] in visited)) { 575 | visited[arr[i]] = true; 576 | var temp = arr[i]; 577 | result.push(arr[i]); 578 | arr.push(...graph[temp].connections); 579 | } 580 | } 581 | return result; 582 | } 583 | 584 | // console.log(breadthFirstTraversal(7, graph)); 585 | -------------------------------------------------------------------------------- /src/algorithms.js: -------------------------------------------------------------------------------- 1 | export function map(value, cb) { 2 | var newArray = []; 3 | var index; 4 | if (Array.isArray(value) == true) { 5 | for (let indexValue of value) { 6 | index = value.indexOf(indexValue); 7 | cb(indexValue, index, value); 8 | 9 | newArray.push(cb(indexValue, index, value)); 10 | } 11 | } else if (typeof value == "object") { 12 | for (let key in value) { 13 | cb(value[key], key, value); 14 | newArray.push(cb(value[key], key, value)); 15 | } 16 | } else { 17 | //// console.log(`Please put in an array or an object`) 18 | } 19 | return newArray; 20 | } 21 | 22 | var test100 = map([9, 6, 9, 7, 7], function (value, index, array) { 23 | return index; 24 | }); 25 | // console.log(test100); 26 | ///// 27 | 28 | // function filter(predicateFn, array) { 29 | // if (array.length == 0) return []; 30 | // const firstItem = head(array); 31 | // const filteredFirst = predicateFn(firstItem) ? [firstItem] : []; 32 | // return concat(filteredFirst,filter(predicateFn,tail(array))); 33 | // } 34 | 35 | // var wholes = [0, 1 , 2, 3, 4, 5, 6, 7, 8, 9, 10]; 36 | 37 | // function that checkes if a number is even 38 | var n = 7; 39 | export function isEven(n) { 40 | var keep = n / 2; 41 | if (Number.isInteger(keep)) { 42 | return true; 43 | } else { 44 | return false; 45 | } 46 | } 47 | 48 | /// Or 49 | export function isEven2(n) { 50 | var keep = n % 2; 51 | if (keep === 0) { 52 | return true; 53 | } else { 54 | return false; 55 | } 56 | } 57 | ////// console.log(isEven2(n)); 58 | 59 | // Prime number tester using loops and if statement. 60 | 61 | export function isPrime(n) { 62 | var keep; 63 | for (let i = 2; i <= 13; i++) { 64 | if (n == 1 || n == 0) { 65 | keep = false; 66 | } else if ( 67 | n > i && 68 | n % i === 0 && 69 | typeof keep == "undefined" // prevent keep from being resigned 70 | ) { 71 | keep = false; 72 | } else if (n == i && typeof keep == "undefined") { 73 | keep = true; 74 | } 75 | } 76 | return keep; 77 | } 78 | ////// console.log(isPrime(15)); 79 | 80 | //isPrime using if statements. 81 | export function isPrime2(n) { 82 | if (n == 2) { 83 | return true; 84 | } 85 | if (!isEven(n)) { 86 | if (n == 3 || n == 5 || n == 7 || n == 11) { 87 | return true; 88 | } else if (n % 3 == 0 || n % 5 == 0 || n % 7 == 0 || n % 11 == 0) { 89 | return false; 90 | } 91 | return true; 92 | } 93 | return false; 94 | } 95 | 96 | ////// console.log(isPrime2(47)); 97 | 98 | // Prime Number testing in sqrt(n) time - Suitable for numbers upto <= 10^16 99 | export function isPrime3(n) { 100 | for (let i = 2; i * i <= n; i++) { 101 | if (n % i == 0) return false; 102 | } 103 | 104 | return true; 105 | } 106 | // console.log(isPrime3(15)); 107 | 108 | // Implementing a setTimeOut. 109 | function delay(func, wait) { 110 | var d = Date.now(); 111 | var currentDate; 112 | do { 113 | currentDate = Date.now(); 114 | } while (currentDate - d < wait); 115 | 116 | return func(); 117 | } 118 | 119 | export function reverse(arr) { 120 | var temp = []; 121 | for (let item of arr) { 122 | temp.unshift(item); 123 | } 124 | 125 | /*loops throught the temp array backwards so as to pop the last elements in the arr array while 126 | adding to the front of the arr array the elements in the temp array from backwards */ 127 | for (let item = temp.length - 1; item >= 0; item--) { 128 | arr.pop(); 129 | arr.unshift(temp[item]); 130 | } 131 | return arr; 132 | } 133 | 134 | export function reverse2(arr) { 135 | var tempArr = [...arr]; 136 | for (let data of tempArr) { 137 | arr.pop(); 138 | arr.unshift(data); 139 | } 140 | return arr; 141 | } 142 | 143 | // console.log(reverse([1, 2, 3, 4, 5])); //[3, 2, 1] 144 | // console.log(reverse2([1, 2, 3])); //[3, 2, 1] 145 | 146 | /*functions that input random numbers in an array and also sort the array in ascending 147 | order at the same time prevent reoccurence of numbers in the array. */ 148 | 149 | function lotteryNum() { 150 | return (Math.round(Math.random() * 100) % 58) + 1; 151 | } 152 | 153 | function pickNumber(luckyLotteryNumbers) { 154 | var num = 0; 155 | var k = 1; 156 | var keep = lotteryNum(); 157 | luckyLotteryNumbers.push(keep); 158 | luckyLotteryNumbers.sort(function (a, b) { 159 | if (a - b == 0) { 160 | // prevent recursion of same numbers. 161 | k = luckyLotteryNumbers.indexOf(a); 162 | num = 1; 163 | } 164 | return a - b; 165 | }); 166 | luckyLotteryNumbers.splice(k, num); //only removes a value if it reoccures hence (a-b) = 0 167 | } 168 | 169 | function lottery() { 170 | let luckyLotteryNumbers = []; 171 | 172 | while (luckyLotteryNumbers.length < 6) { 173 | pickNumber(luckyLotteryNumbers); 174 | } 175 | 176 | return luckyLotteryNumbers; 177 | } 178 | 179 | // console.log(lottery()); 180 | 181 | //A isPalindrome function that checks if the str is the same if called backwards 182 | export function isPalindrome(str) { 183 | var another = ""; 184 | for (let i = str.length - 1; i >= 0; i--) { 185 | // a loop to loop through the str parameter from the back. 186 | another += str[i]; 187 | } 188 | return another === str ? true : false; 189 | } 190 | 191 | // //// console.log( isPalindrome("") === true ); 192 | // //// console.log( isPalindrome("a") === true ); 193 | // //// console.log( isPalindrome("aa") === true ); 194 | // //// console.log( isPalindrome("aba") === true ); 195 | // //// console.log( isPalindrome("abba") === true ); 196 | // //// console.log( isPalindrome("abccba") === true ); 197 | 198 | // //// console.log( isPalindrome("ab") === false ); 199 | // //// console.log( isPalindrome("abc") === false ); 200 | // //// console.log( isPalindrome("abca") === false ); 201 | // //// console.log( isPalindrome("abcdba") === false ); 202 | 203 | function pipe2(...args) { 204 | return function piped(input) { 205 | for (item of args) { 206 | input = items(input); 207 | } 208 | return input; 209 | }; 210 | } 211 | 212 | /*Same functionality as the filter method on arrays */ 213 | export function filterIn(cb, arr) { 214 | var newArr = []; 215 | for (let elem of arr) { 216 | if (cb(elem)) { 217 | newArr = [...newArr, elem]; //used in place of the newArr.push(elem) as a form of functional progarmming style. 218 | //newArr.push(elem); 219 | } 220 | } 221 | return newArr; 222 | } 223 | 224 | var items = filterIn( 225 | function (value) { 226 | return value > 5; 227 | }, 228 | [1, 2, 3, 4, 5, 6, 8] 229 | ); 230 | 231 | //// console.log(items); 232 | 233 | //A function that prevent duplications in an array. 234 | export function uniqueElemArr(arr) { 235 | let item = []; 236 | for (let value of arr) { 237 | if (!item.includes(value)) { 238 | item = [...item, value]; /// equivalent to "item.push(value)" 239 | } 240 | } 241 | return item; 242 | } 243 | 244 | export function uniqueArr2(array) { 245 | var breadCrums = {}; 246 | var arr = []; 247 | array.forEach((elem) => { 248 | if (!breadCrums[elem]) { 249 | breadCrums[elem] = true; 250 | arr.push(elem); 251 | } 252 | }); 253 | array = [...arr]; 254 | return array.sort((a, b) => a - b); 255 | } 256 | 257 | ////// console.log( uniqueElemArr([1,2,3,1,1,2,3,4,5,]) ); 258 | //// console.log(uniqueArr2([1,2,3,1,1,2,3,4,5,])) // [1,2,3,4,5] 259 | 260 | /*Making a reduce function works for only arrays */ 261 | function reduceArr(cb, acc, arr) { 262 | // 263 | for (let elem of arr) { 264 | acc = cb(acc, elem); 265 | } 266 | return acc; 267 | } 268 | 269 | //reduce for both obj and arrays 270 | export function reduceObj(reducerFn, initialValue, o) { 271 | for (let key in o) { 272 | initialValue = reducerFn(initialValue, o[key]); 273 | } 274 | return initialValue; 275 | } 276 | 277 | var stringReduceTest = reduceObj( 278 | function (one, two) { 279 | return one + two; 280 | }, 281 | "", 282 | ["Nosa ", "Is ", "A ", "Genius"] 283 | ); 284 | 285 | ////// console.log(stringReduceTest); 286 | 287 | //making a map function with explicitly implemented reduce function 288 | function mapWithExplicitReduceFunction(arr, mappingFn) { 289 | return reduceObj( 290 | function (first, second) { 291 | first.push(mappingFn(second)); 292 | return first; 293 | }, 294 | [], 295 | arr 296 | ); 297 | } 298 | 299 | //making a filter function with explicitly implemented reduce function 300 | function filterWithExplicitReduceFunction(arr, filterFn) { 301 | return reduceObj( 302 | function (first, second) { 303 | if (filterFn(second)) { 304 | first.push(second); 305 | } 306 | return first; 307 | }, 308 | [], 309 | arr 310 | ); 311 | } 312 | 313 | // Implimenting the curry function 314 | export function curryN(no, fn) { 315 | var newArrHolder = []; 316 | var i = 1; 317 | return function curryHolder(v) { 318 | newArrHolder = [...newArrHolder, v]; 319 | if (i < no) { 320 | i++; 321 | return curryHolder; 322 | } 323 | return fn(...newArrHolder); 324 | }; 325 | } 326 | 327 | //Test for curry function. 328 | function addOneCurry(x, y, z) { 329 | return x + y + z; 330 | } 331 | function addOne(x) { 332 | return x + 1; 333 | } 334 | function mul(int) { 335 | return int * 2; 336 | } 337 | 338 | var holder = curryN(3, addOneCurry); 339 | // //// console.log(holder(7)(7)(7)); 340 | 341 | /*Implimenting the compose untility */ 342 | export function compose(...args) { 343 | const arr = [...args.reverse()]; 344 | return function composeHelper(input) { 345 | for (let elem of arr) { 346 | input = elem(input); 347 | } 348 | return input; 349 | }; 350 | } 351 | 352 | //Test for compose 353 | var ok = compose(addOne, mul); 354 | ////// console.log(ok(7)); 355 | 356 | //Another implimentation of pipe in term of compose. 357 | export function pipe(...args) { 358 | const arr = [...args]; 359 | return compose(...arr.reverse()); 360 | } 361 | 362 | //Test for compose 363 | var ok = pipe(addOne, mul); 364 | ////// console.log(ok(7)); 365 | 366 | //convert Numbers to different base. 367 | export function convertNumberToDifferentBase(value, converTo) { 368 | return value.toString(converTo); 369 | } 370 | 371 | //concatAll that flatens 2 dimentionsal array in to a single dimensional array 372 | var arr = [[1], [2, 3], [], [4]]; 373 | 374 | export function concatAll(arr) { 375 | var emp = []; 376 | arr.forEach((x) => { 377 | return x.forEach((x) => { 378 | emp = [...emp, x]; 379 | }); 380 | }); 381 | return emp; 382 | } 383 | concatAll(arr); 384 | 385 | // zips an two array and combine them 386 | export var zip = function (left, right, combinerFunction) { 387 | var counter, 388 | results = []; 389 | 390 | for (counter = 0; counter < Math.min(left.length, right.length); counter++) { 391 | //Math.min to avoid length difference in the two array,uses the length of the smallest array. 392 | results.push(combinerFunction(left[counter], right[counter])); 393 | 394 | // Add code here to apply the combinerFunction to the left and right-hand items in the respective arrays 395 | } 396 | 397 | return results; 398 | }; 399 | 400 | var zipper = zip( 401 | [1, 2, 3], 402 | [4, 5, 6], 403 | function addElemOfBothArray(left, right) { 404 | return left + right; 405 | } 406 | ); 407 | //// console.log(zipper); //[1,2,3] + [4,5,6] = [5,7,9] 408 | 409 | /* 410 | 411 | COMPUTER SCIENCE ALGORITHMS (BRIAN HOLT CLASS) 412 | check--- https://btholt.github.io/complete-intro-to-computer-science for detailed info 413 | more information about all algorithms can be found on the link above. 414 | 415 | */ 416 | ///MY PERSONAL ALGORITHMS: DIFFERENT WAYS TO SORT NUMBER :FOR THE SAKE OF HAVING A "CONSTANT SPATIAL COMPLEXITY" ('MOST OF THE ALGORITHM MUTATES THEIR INITIAL VALUE') 417 | 418 | var nums = [10, 5, 3, 8, 2, 6, 4, 7, 9, 1]; // GLOBAL ARRAY FOR ALL SORT FUNCTIONS 419 | 420 | //--------------BUBBLE SORT ALGORITHM------------- 421 | 422 | export function bubbleSort(nums) { 423 | // code goes here 424 | var swap = true; 425 | while (swap) { 426 | var swapDetails = "NO Swap"; 427 | for (let i = 0; i < nums.length - 1; i++) { 428 | if (nums[i] > nums[i + 1]) { 429 | var keep = nums[i]; 430 | nums[i] = nums[i + 1]; 431 | nums[i + 1] = keep; 432 | swapDetails = "Swap"; 433 | } 434 | if (swapDetails === "Swap") { 435 | swap = true; 436 | } else { 437 | swap = false; 438 | } 439 | } 440 | } 441 | return nums; 442 | } 443 | 444 | //bubble sort test 445 | // //// console.log(bubbleSort(nums)); //[1,2,3,4,5,6,7,8,9,10]; 446 | 447 | //BUBBLE SORT TIME COMPLEXITY == NSQUARE - QUADRATIC TIME COMPLEXITY (Because it requires 2 loops) 448 | // Takes estimatively about 0.12seconds to sort through the "NUMS" array . 449 | 450 | //--------------iNSERTION SORT ALGORITHM------------- 451 | 452 | export function insertionSort(nums) { 453 | // code goes here 454 | for (let i = 1; i < nums.length; i++) { 455 | for (let k = i; k >= 0; k--) { 456 | if (nums[k] < nums[k - 1]) { 457 | var temp = nums[k]; 458 | nums[k] = nums[k - 1]; 459 | nums[k - 1] = temp; 460 | } 461 | } 462 | } 463 | return nums; 464 | } 465 | 466 | //Insertion sort test 467 | //// console.log(insertionSort(nums)); //[1,2,3,4,5,6,7,8,9,10]; 468 | 469 | //INSERTION SORT TIME COMPLEXITY == NSQUARE - QUADRATIC TIME COMPLEXITY (Because it requires 2 loops) 470 | // Takes estimatively about 0.12seconds to sort through the "NUMS" array . 471 | 472 | //--------------RECURSION NESTATION ALGORITHM------------- 473 | //VARIABLES FOR RECURSION NESTATION TEST 474 | var nested = [1, 2, 3]; 475 | var nested2 = [1, [2], 3]; 476 | var nested3 = [[[[[[[[[[[[[[[[[[[[5]]]]]]]]]]]]]]]]]]]]; 477 | var nested4 = [10, [12, 14, [1], [16, [20]]], 10, 11]; 478 | 479 | export function nestedAdd(array) { 480 | if (array.length === 1) { 481 | if (Array.isArray(array[0])) { 482 | return nestedAdd(...array); 483 | } 484 | return array[0]; 485 | } 486 | 487 | var [first, second, ...rest] = array; 488 | 489 | if (Array.isArray(first)) { 490 | var flat = [...first]; 491 | return nestedAdd([...flat, second, ...rest]); 492 | } 493 | if (Array.isArray(second)) { 494 | var flat2 = [...second]; 495 | return nestedAdd([first, ...flat2, ...rest]); 496 | } 497 | 498 | var addUP = first + second; 499 | return nestedAdd([addUP, ...rest]); 500 | } 501 | 502 | //// console.log(nestedAdd(nested)); //6 503 | //// console.log(nestedAdd(nested2)); //6 504 | //// console.log(nestedAdd(nested3)); //5 505 | //// console.log(nestedAdd(nested4)); //94 506 | 507 | //THE ABOVE FUNCTION "nestedAdd" WILL PROBABLY NOT RUN INTO A "STACK OVERLOAD PROBLEM" FOR A SYSTEM THAT SUPPORT TAIL CALL BECAUSE IT UTILIZES THE TAIL CALL SYSTEM, HENCE WHEN A RECURSION OCCURS IT DOESN'T BUBBLE UP(ADD TO THE CALL STACK) BUT INSTEAD REPLACES THE POSITION OF IT PREVIOUS FUNCTION THAT CALLED IT. 508 | 509 | export function nestedAdd2(array) { 510 | let sum = 0; 511 | for (let i = 0; i < array.length; i++) { 512 | const current = array[i]; 513 | if (Array.isArray(current)) { 514 | sum += nestedAdd(current); 515 | } else { 516 | sum += current; 517 | } 518 | } 519 | return sum; 520 | } 521 | 522 | //// console.log(nestedAdd2(nested)); //6 523 | //// console.log(nestedAdd2(nested2)); //6 524 | //// console.log(nestedAdd2(nested3)); //5 525 | //// console.log(nestedAdd2(nested4)); //94 526 | //THE "nestedAdd2" FUCNTION WILL PROBABLY RUN IN A "STACK OVERLOAD PROBLEM" BECAUSE IT BUBBLES UP AND WILL TAKE MORE COMPUTATIONAL TIME IF THE INPUT HAVE A DIPPLY NESTED ARRAYS. 527 | 528 | //--------------RECURSION FACTORIAL ALGORITHM------------- 529 | 530 | export function factorial(fac) { 531 | var sum = fac; 532 | if (sum > 1) { 533 | sum *= factorial(fac - 1); 534 | } 535 | return sum; 536 | } 537 | //// console.log(factorial(5)); //120 538 | //THE FACTORIAL FUNCTION ABOVE WILL DEFINATELY RUN INTO A "STACK OVERLOAD PROBLEM" BECAUSE IT BUBBLES UP AND WILL TAKE MORE COMPUTATION TIME AND MORE SPACE ON THE STACK IF A LARGER NUMBER IS INPUTED I.E "10000 OR 10000000" (TRY USING THE FACTORIAL FUNCTION TO FIND THE FACTORIAL FOR THOSE NUMBER !WARNING: MIGHT CRASH YOUR CODE RUNNER, DO NOT RUN IN A BROWSER WILL DEFINATELY CRASH YOUR BROWSER). 539 | 540 | export function factorial2(num) { 541 | if (num < 2) return 1; 542 | return num * factorial2(num - 1); 543 | } 544 | //// console.log(factorial2(10000)); 545 | // THE FACTORIAL2 FUNCTION IS NOT TAILED CALLED SO WILL RUN INTO A "STACK OVERLOAD" BUT NOT AS QUICKLY AS THE FIRST FUCNTION ABOVE "FACTORIAL" . TRY RUNNING BOTH FUNCTIONS WITH THE VALUE "10000" AND SEE THE DIFFERENCE 546 | 547 | //--------------MERGE SORT RECURSION ALGORITHM------------- 548 | export function mergeSort(array) { 549 | var firstHolder; 550 | var secondHolder; 551 | 552 | function merge(left, right) { 553 | const results = []; 554 | 555 | // go until one list runs outs 556 | while (left.length && right.length) { 557 | if (left[0] <= right[0]) { 558 | // shift removes the first element in an array and returns it 559 | // it's like .pop() for the front 560 | results.push(left.shift()); 561 | } else { 562 | results.push(right.shift()); 563 | } 564 | } 565 | 566 | // either left or right will be empty so you can safely concat both 567 | return results.concat(left, right); 568 | } 569 | 570 | if (array.length > 1) { 571 | var splitArray = array.splice(0, Math.ceil(array.length / 2)); 572 | firstHolder = mergeSort(splitArray); 573 | secondHolder = mergeSort(array); 574 | return merge(firstHolder, secondHolder); 575 | } 576 | return array; 577 | } 578 | var keep = mergeSort([1, 5, 7, 4, 2, 3, 6]); 579 | //// console.log(keep); 580 | //THE MERGE SORT FUNCTION IS NOT TAIL CALL OPTIMIZED 581 | 582 | //--------------QUICK SORT RECURSION ALGORITHM------------- 583 | 584 | export function quickSort(arr) { 585 | var result = []; 586 | if (arr.length < 2) { 587 | return arr; 588 | } 589 | const last = arr[arr.length - 1]; 590 | var left = []; 591 | var right = []; 592 | for (let i = 0; i < arr.length - 1; i++) { 593 | if (arr[i] < last) { 594 | left.push(arr[i]); 595 | } else { 596 | right.push(arr[i]); 597 | } 598 | } 599 | var leftHolder = quickSort(left); 600 | var rightHolder = quickSort(right); 601 | 602 | return result.concat(...leftHolder, last, ...rightHolder); 603 | } 604 | //// console.log(quickSort([4,9,3,5])); 605 | //FUNCTION "QUICK SORT" NOT TAIL CALL OPTIMIZED 606 | 607 | //--------------RADIX SORT RECURSION ALGORITHM------------- 608 | 609 | export function radixSort(array) { 610 | var arr = [...array]; 611 | 612 | function getLongestNumber(array) { 613 | var longestNo = 0; 614 | array.forEach((elem) => { 615 | elem = elem.toString(); 616 | if (elem.length > longestNo) { 617 | longestNo = elem.length - 1; 618 | } 619 | }); 620 | return longestNo; 621 | } 622 | 623 | var longestNumber = getLongestNumber(array); 624 | var pointer = 1; 625 | 626 | while (longestNumber >= 0) { 627 | var bucket = new Array(10).fill().map((e) => []); // makes a new bucket on every invocation 628 | arr.forEach((elem) => { 629 | elem = elem.toString(); 630 | var track = elem.length - pointer; 631 | bucket = sortIntoBucket(elem, track, bucket); 632 | }); 633 | 634 | var temp = []; 635 | bucket.forEach((sorted) => { 636 | temp = temp.concat(sorted); 637 | arr = [...temp]; 638 | }); 639 | arr = arr.map((e) => Number(e)); //convers elements back to number 640 | pointer++; 641 | longestNumber--; 642 | } 643 | return arr; 644 | } 645 | 646 | //helper functions to help with function "radix sort" 647 | 648 | function sortIntoBucket(elem, number, bucket) { 649 | var bucketPlace = Number(elem[number]) || 0; //of number in each unit position of the elem and if it is undefined returns 0; 650 | bucket[bucketPlace].push(elem); 651 | //pushs the element into the same array as its unit number 652 | //i.e elem = "58" number = 0; elem[number] = 5; bucketplace = 5; on the "5th" array in the bucket push "elem" 653 | //if elem[number] is undefined the bucketPlace will return 0; 654 | return bucket; 655 | } 656 | 657 | //// console.log(radixSort([109,224,58,901])) //[58,109,224,901] 658 | const fill = 99; 659 | const value = new Array(fill) 660 | .fill() 661 | .map(() => Math.floor(Math.random() * 500000)); 662 | // //// console.log(value.length); //99 663 | // //// console.log(radixSort(value));// larger test sorts an array with 99 random numbers 664 | // //// console.log(radixSort(value).length) //99 665 | //// console.log(value.sort((a,b)=>a-b)); 666 | 667 | //OBSERVE THAT THE RADIX SORT FUNCITON DOES NOT COMPARE ANY ITEM TO ANOTHER RATHER SORT BY UNIT TEST OF EACH UNITS OF EACH NUMBERS IN THE INPUT ARRAY, 668 | //THE FUNCITON HAS AN N LEVEL SPARTIAL COMPLEXITY CAUSE IT CREATE A NEW ARRAY FOR EVERY UNIT TESTS ALSO HAS A TIME COMPLEXITY OF NSQUARE. 669 | 670 | //--------------BINARY SEARCH ALGORITHM------------- 671 | /*THE BINARYSEARCH FUNCTION CAN ONLY WORK WHEN THE ITEM GIVEN IS ALREADY SORTED(ACCENDING ORDER)*/ 672 | 673 | export function binarySearch(num, array) { 674 | var arr = [...array]; 675 | var splitArray = Math.floor(arr.length / 2); 676 | var result = "not found"; 677 | var answer = arr[splitArray]; 678 | var half; 679 | typeof arr[0] === "object" 680 | ? (half = arr[splitArray].id) 681 | : (half = arr[splitArray]); 682 | 683 | if (half === num) { 684 | return answer; 685 | } else if (arr.length === 1 && result === "not found") { 686 | return result; 687 | } else if (half > num) { 688 | var keep = arr.splice(0, splitArray); 689 | return binarySearch(num, keep); 690 | } else if (half < num) { 691 | arr.splice(0, splitArray); 692 | return binarySearch(num, arr); 693 | } 694 | } 695 | 696 | export function binarySearch2(num, array) { 697 | var arr = [...array]; 698 | var found = false; 699 | var result = "not found"; 700 | 701 | while (!found) { 702 | var splitArray = Math.floor(arr.length / 2); 703 | var answer = arr[splitArray]; 704 | var half; 705 | typeof arr[0] === "object" 706 | ? (half = arr[splitArray].id) 707 | : (half = arr[splitArray]); 708 | 709 | if (half === num) { 710 | found = true; 711 | } else if (arr.length === 1 && result === "not found") { 712 | return result; 713 | } else if (half > num) { 714 | var keep = arr.splice(0, splitArray); 715 | arr = keep; 716 | } else { 717 | arr.splice(0, splitArray); 718 | } 719 | } 720 | return answer; 721 | } 722 | 723 | // Test for both binarySearch and binarysearch2 function , OBSERVE THAT BINARYSEARCH FUNCTION WORKS FOR BOTH PRIMITIVE AND OBJECT TYPE ELEMENTS IN THE INPUT. 724 | var findobj = binarySearch(3, [ 725 | { id: 1, name: "Sam" }, 726 | { id: 3, name: "Sarah" }, 727 | { id: 5, name: "John" }, 728 | { id: 6, name: "Burke" }, 729 | { id: 10, name: "Simona" }, 730 | { id: 12, name: "Asim" }, 731 | { id: 13, name: "Niki" }, 732 | { id: 15, name: "Aysegul" }, 733 | { id: 17, name: "Kyle" }, 734 | { id: 18, name: "Jem" }, 735 | { id: 19, name: "Marc" }, 736 | { id: 21, name: "Chris" }, 737 | ]); 738 | 739 | var findnum = binarySearch(12, [0, 5, 10, 12, 15, 19, 21, 22, 24, 30]); 740 | // // console.log(findnum); 741 | //// console.log(findobj) 742 | 743 | var findobj = binarySearch2(3, [ 744 | { id: 1, name: "Sam" }, 745 | { id: 3, name: "Sarah" }, 746 | { id: 5, name: "John" }, 747 | { id: 6, name: "Burke" }, 748 | { id: 10, name: "Simona" }, 749 | { id: 12, name: "Asim" }, 750 | { id: 13, name: "Niki" }, 751 | { id: 15, name: "Aysegul" }, 752 | { id: 17, name: "Kyle" }, 753 | { id: 18, name: "Jem" }, 754 | { id: 19, name: "Marc" }, 755 | { id: 21, name: "Chris" }, 756 | ]); 757 | 758 | var findnum = binarySearch2(12, [0, 5, 10, 12, 15, 19, 21, 22, 24, 30]); 759 | 760 | //// console.log(findobj); 761 | 762 | //// console.log(findnum); 763 | 764 | /*THE BINARYSEARCH FUNCTION CAN ONLY WORK WHEN THE ITEM GIVEN IS ALREADY SORTED(ACCENDING ORDER)*/ 765 | 766 | //THE FIRST BINARYSEARCH "binarySearch" FUNCTION ABOVE USES RECUSION FOR ITS COMPUTATION AND IS TAIL CALL OPTIMIZED. THE SECOND BINARYSEARCH "binarySearch2" FUNCTION USES ITERATION(LOOP) FOR ITS COMPUTATION 767 | //FOR A SYSTEM THAT DOESN'T SUPPORT TAIL CALL, THE "binarySearch2" FUNCTION IS WILL BE BETTER FOR PERFORMANCE REASONS ESPECIALLY WHEN DEALING WITH LARGER INPUT 768 | 769 | //--------------LINEAR SEARCH ALGORITHM------------- 770 | /*THE LINEARSEARCH FUNCTION CAN WORK WITH ELEMENTS IN ANY ORDER (IT DOES ALMOST THE SAME THING AS THE ARRAY.INCLUDES() METHOD)*/ 771 | 772 | export function linearSearch(num, array) { 773 | var arr = [...array]; 774 | var result = "not found"; 775 | for (let counter = 0; counter < arr.length; counter++) { 776 | var check; 777 | typeof arr[0] === "object" 778 | ? (check = arr[counter].id) 779 | : (check = arr[counter]); 780 | if (check === num) { 781 | return (result = arr[counter]); 782 | } 783 | } 784 | 785 | return result; 786 | } 787 | var testobj = linearSearch(31, [ 788 | { id: 1, name: "Sam" }, 789 | { id: 11, name: "Sarah" }, 790 | { id: 21, name: "John" }, 791 | { id: 10, name: "Burke" }, 792 | { id: 13, name: "Simona" }, 793 | { id: 31, name: "Asim" }, 794 | { id: 6, name: "Niki" }, 795 | { id: 19, name: "Aysegul" }, 796 | { id: 25, name: "Kyle" }, 797 | { id: 18, name: "Jem" }, 798 | { id: 2, name: "Marc" }, 799 | { id: 51, name: "Chris" }, 800 | { id: 14, name: "Ben" }, 801 | ]); 802 | var testnum = linearSearch(6, [, 2, 3, 6, 5, 7]); 803 | // //// console.log(testobj); 804 | // //// console.log(testnum); 805 | 806 | //-------------- DIFFERENT ALGORITHM TO GET VALUES FROM A TREE IN DIFFERRENT ORDER (TRAVERSE) ------------- 807 | 808 | export const tree = { 809 | value: 8, 810 | left: { 811 | value: 4, 812 | left: { 813 | value: 3, 814 | left: { 815 | value: 2, 816 | left: null, 817 | right: null, 818 | }, 819 | right: null, 820 | }, 821 | right: { 822 | value: 5, 823 | left: null, 824 | right: { 825 | value: 7, 826 | left: { 827 | value: 6, 828 | left: null, 829 | right: null, 830 | }, 831 | }, 832 | }, 833 | }, 834 | right: { 835 | value: 12, 836 | left: { 837 | value: 10, 838 | left: { 839 | value: 9, 840 | left: null, 841 | right: null, 842 | }, 843 | right: { 844 | value: 11, 845 | left: null, 846 | right: null, 847 | }, 848 | }, 849 | }, 850 | }; 851 | 852 | // //GET ALL ELEMENTS IN THE LEFT OF EACH NODES STARTING FROM THE NODE ITSELF FIRST BEFOR GETTING THE ELEMENT IN THE RIGHT 853 | export function preorder(tree, node) { 854 | var current = tree; 855 | node.push(current.value); 856 | var leftHolder = current.left; 857 | var rightHolder = current.right; 858 | if (leftHolder == null && rightHolder == null) { 859 | return node; 860 | } else if (leftHolder == null && rightHolder != null) { 861 | node = preorder(rightHolder, node); 862 | } else { 863 | node = preorder(leftHolder, node); 864 | } 865 | if (rightHolder == null) { 866 | return node; 867 | } else if (!node.includes(rightHolder.value)) { 868 | node = preorder(rightHolder, node); 869 | } 870 | return node; 871 | } 872 | 873 | // //GET ALL ELEMENTS IN THE LEFT OF EACH NODES STARTING FROM THE LAST ELEMENT IN NODE ITSELF FIRST BEFOR GETTING THE ELEMENT IN THE RIGHT 874 | export function postorder(tree, node) { 875 | var current = tree; 876 | var leftHolder = current.left; 877 | var rightHolder = current.right; 878 | if (leftHolder == null && rightHolder == null) { 879 | node.push(current.value); 880 | return node; 881 | } else if (leftHolder == null && rightHolder != null) { 882 | node = postorder(rightHolder, node); 883 | } else { 884 | node = postorder(leftHolder, node); 885 | } 886 | if (rightHolder == null) { 887 | node.push(current.value); 888 | return node; 889 | } else if (!node.includes(rightHolder.value)) { 890 | node = postorder(rightHolder, node); 891 | } 892 | node.push(current.value); 893 | return node; 894 | } 895 | 896 | //GET ELEMENTS FROM THE TREE IN ACCEDING ORDER 897 | export function inorder(tree, node) { 898 | var current = tree; 899 | var leftHolder = current.left; 900 | var rightHolder = current.right; 901 | if (leftHolder == null && rightHolder == null) { 902 | node.push(current.value); 903 | return node; 904 | } else if (leftHolder == null && rightHolder != null) { 905 | node.push(current.value); 906 | node = inorder(rightHolder, node); 907 | } else { 908 | node = inorder(leftHolder, node); 909 | } 910 | 911 | if (!node.includes(current.value)) { 912 | node.push(current.value); 913 | } 914 | 915 | if (rightHolder == null) { 916 | return node; 917 | } else { 918 | node = inorder(rightHolder, node); 919 | } 920 | return node; 921 | } 922 | 923 | //TESTS 924 | var fingerCrossed = preorder(tree, []); 925 | //// console.log(fingerCrossed); // [8,4,3,2,5,7,6,12,10,9,11] 926 | 927 | var fingerCrossed2 = postorder(tree, []); 928 | //// console.log(fingerCrossed2); // [2,3,4,5,6,7,8,9,10,11,12] 929 | 930 | var fingerCrossed3 = inorder(tree, []); 931 | //// console.log(fingerCrossed3); //[2,3,4,5,6,7,8,9,10,11,12] 932 | 933 | //GET ELEMENT FROM THE CLOSE ELEMENT 934 | export function breadth(tree, node) { 935 | tree.forEach((elem) => { 936 | node.push(elem.value); 937 | 938 | tree.shift(); 939 | if (elem.left) tree.push(elem.left); 940 | if (elem.right) tree.push(elem.right); 941 | return breadth(tree, node); 942 | }); 943 | return node; 944 | } 945 | 946 | var fingerCrossed4 = breadth([tree], []); 947 | //// console.log(fingerCrossed4) //[8,4,12,3,5,10,2,7,9,11,6] 948 | 949 | //-------------- ALGORITHM TO CONVERT AN ARRAY TO A HEAP AND SORT THE HEAPED ARRAY ------------- 950 | 951 | const heapSort = (array) => { 952 | // code 953 | for (let i = Math.floor(array.length / 2) - 1; i >= 0; i--) { 954 | array = heapify(array, i, array.length); 955 | } 956 | //// console.log(array) uncomment to view heaped array. 957 | // heaped array will be [ 10, 9, 6, 8, 5, 3, 4, 7, 2, 1] 958 | for (let i = array.length - 1; i > 0; i--) { 959 | array = createMaxHeap(array, i); 960 | } 961 | //final anwser result in sorted heap array. [1,2,3,4,5,6,7,8,9,10] 962 | return array; 963 | }; 964 | 965 | const heapify = (array, i, heapSize) => { 966 | // turns the array into a heap 967 | // code 968 | var left = 2 * i + 1; 969 | var right = 2 * i + 2; 970 | var temp = i; 971 | 972 | if (heapSize > left && array[left] > array[temp]) { 973 | temp = left; 974 | } 975 | if (heapSize > right && array[right] > array[temp]) { 976 | temp = right; 977 | } 978 | 979 | if (temp !== i) { 980 | var keep = array[i]; 981 | array[i] = array[temp]; 982 | array[temp] = keep; 983 | 984 | heapify(array, temp, heapSize); 985 | } 986 | 987 | return array; 988 | }; 989 | const createMaxHeap = (array, i) => { 990 | // sorts the heap array in accending order 991 | // code 992 | var temp = array[0]; 993 | array[0] = array[i]; 994 | array[i] = temp; 995 | array = heapify(array, 0, i); 996 | return array; 997 | }; 998 | 999 | // var test = heapSort([2, 5, 3, 8, 10, 6, 4, 7, 9, 1]); //[1,2,3,4,5,6,7,8,9,10] 1000 | // // console.log(test); 1001 | 1002 | //-------------- ALGORITHM TO GRAPHS GETTING INFORMATION OUT GIVEN AN ID AND DEPTHS ------------- 1003 | import list from "../data/graphData.js"; 1004 | // GETS GRAPH DATA STRUCTURE FROM data.JS FILE 1005 | 1006 | function connect(id, depth) { 1007 | var getMostPopularjob = []; 1008 | var ArrayofAllJobs = []; 1009 | var mostPopularjob; 1010 | var scoreofMostPopularjob = 1; 1011 | 1012 | var connectionArray = []; 1013 | list.forEach((elem) => { 1014 | if (elem.id == id) { 1015 | connectionArray = [...connectionArray, ...elem.connections]; 1016 | getMostPopularjob.push({ job: elem.title, score: 1 }); 1017 | ArrayofAllJobs.push(elem.title); 1018 | mostPopularjob = elem.title; 1019 | } 1020 | }); 1021 | 1022 | for (let i = 1; i < depth; i++) { 1023 | connectionArray.forEach((connectionelem) => { 1024 | list.forEach((elem) => { 1025 | if (connectionelem == elem.id) { 1026 | elem.connections.forEach((connectedelem) => { 1027 | //avoid repetition of ids 1028 | if (!connectionArray.includes(connectedelem)) { 1029 | connectionArray.push(connectedelem); 1030 | } 1031 | }); 1032 | } 1033 | }); 1034 | }); 1035 | } 1036 | 1037 | connectionArray.forEach((elem) => { 1038 | list.forEach((elem2) => { 1039 | if (elem === elem2.id) { 1040 | getMostPopularjob.forEach((elemPopular) => { 1041 | // increase job of each scores for people with same jobs 1042 | if (elemPopular.job === elem2.title) { 1043 | elemPopular.score = elemPopular.score + 1; 1044 | if (elemPopular.score > scoreofMostPopularjob) { 1045 | // get most popular job by its score 1046 | scoreofMostPopularjob = elemPopular.score; 1047 | mostPopularjob = elemPopular.job; 1048 | } 1049 | } 1050 | }); 1051 | if (!ArrayofAllJobs.includes(elem2.title)) { 1052 | // Avoid repition of people with same jobs 1053 | ArrayofAllJobs.push(elem2.title); 1054 | getMostPopularjob.push({ job: elem2.title, score: 1 }); 1055 | } 1056 | } 1057 | }); 1058 | }); 1059 | return mostPopularjob; 1060 | } 1061 | 1062 | // var popular = connect(306, 4); 1063 | // // console.log(popular); 1064 | 1065 | //-------------- ALGORITHM TO BUILDING TRIES FOR MAKING SEARCHING AND AUTO COMPLETE BOXES RESTRICTING THE SEARCH TO ONLY 3 VALUES ------------- 1066 | // USING CLASSES 1067 | import { CITY_NAMES } from "../data/graphData.js"; 1068 | 1069 | import { Node } from "./datastructures.js"; 1070 | 1071 | const createTrie = (words) => { 1072 | // you do not have to do it this way; this is just how I did it 1073 | const root = new Node(words); 1074 | 1075 | // more code should go here 1076 | 1077 | return root; 1078 | }; 1079 | 1080 | const root = createTrie(CITY_NAMES.slice(0, 200)); 1081 | const completions = root.complete("new"); 1082 | // console.log(completions); //['new york', 'new orleans', 'newark'] 1083 | 1084 | //USING ONLY FUNCTIONS 1085 | 1086 | function search(arr, string) { 1087 | var answer = []; 1088 | var findcheck = string.toLowerCase(); 1089 | arr.forEach((elem) => { 1090 | var check = elem.toLowerCase(); 1091 | if (findcheck[0] == check[0] && check.includes(findcheck)) { 1092 | if (answer.length < 3) { 1093 | answer.push(check); 1094 | } 1095 | } 1096 | }); 1097 | return answer; 1098 | } 1099 | var result = search(CITY_NAMES.slice(0, 200), "new"); 1100 | // console.log(result); //['new york', 'new orleans', 'newark'] 1101 | 1102 | //-------------- BLOOM FILTER ALGORITHM ------------- 1103 | //Used to test if a value have been added before without having to deal with add the value to an array 1104 | //cause when so many values are added it might have performance issues on the system, bloom filter can really be effective though it is not some time correct but still effective it is a trade off between 100% certainty and (performance or memory). 1105 | 1106 | //Bloom filters works by passing a string through a hash function (functions that converts it string into a number i.e they are always consistent) read more on bloom filter here "https://btholt.github.io/complete-intro-to-computer-science/bloom-filters" 1107 | import { hash1, hash2, hash3 } from "./hashing-functions.js"; //personal coded hashing functions 1108 | var h1 = hash1(100); 1109 | var h2 = hash2(100); 1110 | var h3 = hash3(100); 1111 | 1112 | //These test uses hashing function found in the hashing functions.js file, they are just pesudohasing functions for the purpose of this test. 1113 | //CHECK "https://codesandbox.io/s/algorithms-exercises-forked-q2hhq8?file=/specs/bloom-filters/bloom-filters.test.js" TO VIEW A TEST OF BLOOM FILTER. SAME CODE AS ABOVE. 1114 | 1115 | /* 1116 | 1117 | COMPUTER SCIENCE ALGORITHMS (BIANCA GANDOLFO CLASS) 1118 | check--- https://slides.com/bgando/intro-to-algorithms#/ for detailed info 1119 | more information about all algorithms can be found on the link above. 1120 | 1121 | */ 1122 | 1123 | //Personal Algorithms 1124 | 1125 | //-------------- UNIQUE ARR ALGORITHM ------------- 1126 | 1127 | function uniqueArr(arr) { 1128 | let item = []; 1129 | for (let value of arr) { 1130 | if (!item.includes(value)) { 1131 | item = [...item, value]; /// equivalent to "item.push(value)" 1132 | } 1133 | } 1134 | return item; 1135 | } 1136 | 1137 | function uniqueArr3(array) { 1138 | var breadCrums = {}; 1139 | var arr = []; 1140 | array.forEach((elem) => { 1141 | if (!breadCrums[elem]) { 1142 | //restriction 1143 | breadCrums[elem] = true; 1144 | arr.push(elem); 1145 | } 1146 | }); 1147 | array = [...arr]; 1148 | return array.sort((a, b) => a - b); 1149 | } 1150 | 1151 | ////// console.log( uniqueArr([1,2,3,1,1,2,3,4,5,]) ); [1,2,3,4,5] 1152 | //// console.log(uniqueArr2([1,2,3,1,1,2,3,4,5,])) // [1,2,3,4,5] 1153 | 1154 | //THE FIRST UNIQUEARR FUNCTION ("uniqueArr") HAS A TIME COMPLEXITY OF NSQUARE (QUADRATIC) BECAUSE IT USES THE .INCULDES METHOD WHICH UNDER THE HOOD LOOPS THROUGH EVERY ELEMENT IN THE ARRAY AT WORST CASE SENERIO THEREFORE TWO NESTED LOOPS CREATING A TIME COMPLEXITY OF NSQUARE . IT ALSO HAS A SPATIAL COMPLEXITY OF N (LINEAR) CAUSE IT CREATE AND RETURNS A NEW ARRAY MAKING A NEW SPACE IN MEMORY. 1155 | 1156 | //THE SECOND UNIQUEARR FUNCTION ("uniqueArr2") HAS A TIME COMPLEXITY OF N (LINEAR), IT HAS NO NEXTATION OF LOOPS, IT ALSO HAS A CONSTANT SPATIAL COMPLEXITY CAUSE IT DOESN'T CREATE AND KEEP A NEW SPACE IN MEMORY 1157 | 1158 | //HENCE THE SECOND FUNCTION ("uniqueArr2") MIGHT BE BETTER FOR PERFORMANCE. BUT THE SECOND MIGHT BE BETTER FOR READABILITY. 1159 | 1160 | //-------------- BINARYTREE (DATA STRUCTURE) ALGORITHM ------------- 1161 | 1162 | class BinaryTree { 1163 | constructor() { 1164 | this.value = null; 1165 | this.left = null; 1166 | this.right = null; 1167 | } 1168 | insert(value) { 1169 | if (this.value === null) this.value = value; 1170 | if (this.left === null && value < this.value) { 1171 | var left = new BinaryTree(); 1172 | this.left = left; 1173 | this.left.insert(value); 1174 | } else if (this.right === null && value > this.value) { 1175 | var right = new BinaryTree(); 1176 | this.right = right; 1177 | this.right.insert(value); 1178 | } else if (this.left !== null && value < this.value) { 1179 | this.left.insert(value); 1180 | } else if (this.right !== null && value > this.value) { 1181 | this.right.insert(value); 1182 | } 1183 | } 1184 | preTraverse() { 1185 | function preOrderTraverse(tree, arr) { 1186 | arr.push(tree.value); 1187 | if (tree.left !== null) preOrderTraverse(tree.left, arr); 1188 | if (tree.right !== null) preOrderTraverse(tree.right, arr); 1189 | return arr; 1190 | } 1191 | return preOrderTraverse(this, []); 1192 | } 1193 | sortedTraverse() { 1194 | function inOrderTraverse(tree, arr) { 1195 | if (tree.left !== null) inOrderTraverse(tree.left, arr); 1196 | arr.push(tree.value); 1197 | if (tree.right !== null) inOrderTraverse(tree.right, arr); 1198 | return arr; 1199 | } 1200 | return inOrderTraverse(this, []); 1201 | } 1202 | postTraverse() { 1203 | function postOrderTraverse(tree, arr) { 1204 | if (tree.left !== null) postOrderTraverse(tree.left, arr); 1205 | if (tree.right !== null) postOrderTraverse(tree.right, arr); 1206 | arr.push(tree.value); 1207 | return arr; 1208 | } 1209 | return postOrderTraverse(this, arr); 1210 | } 1211 | 1212 | contains(value) { 1213 | var result = false; 1214 | function answer(tree) { 1215 | if (tree.value === value) return (result = true); 1216 | if (tree.left !== null) return answer(tree.left); 1217 | if (tree.right !== null) return answer(tree.right); 1218 | } 1219 | answer(this); 1220 | return result; 1221 | } 1222 | } 1223 | // tests 1224 | const btree = new BinaryTree(); 1225 | // btree.insert(7); 1226 | // btree.insert(9); 1227 | // btree.insert(1); 1228 | // btree.insert(10); 1229 | // btree.insert(2); 1230 | // btree.insert(0); 1231 | // btree.insert(8); 1232 | // btree.insert(11); 1233 | // // console.log(btree); 1234 | // // console.log(btree.contains(0)); 1235 | // // console.log(btree.contains(1000)); 1236 | // // console.log(btree.sortedTraverse()); 1237 | 1238 | //-------------- DIFFERENT ALGORITHM TO TRAVERSE THROUGHT A TREE ------------- 1239 | 1240 | function preOrderTraverse(tree, arr) { 1241 | arr.push(tree.value); 1242 | if (tree.left !== null) preOrderTraverse(tree.left, arr); 1243 | if (tree.right !== null) preOrderTraverse(tree.right, arr); 1244 | return arr; 1245 | } 1246 | function inOrderTraverse(tree, arr) { 1247 | if (tree.left !== null) inOrderTraverse(tree.left, arr); 1248 | arr.push(tree.value); 1249 | if (tree.right !== null) inOrderTraverse(tree.right, arr); 1250 | return arr; 1251 | } 1252 | function postOrderTraverse(tree, arr) { 1253 | if (tree.left !== null) postOrderTraverse(tree.left, arr); 1254 | if (tree.right !== null) postOrderTraverse(tree.right, arr); 1255 | arr.push(tree.value); 1256 | return arr; 1257 | } 1258 | 1259 | //tests 1260 | // // console.log(preOrderTraverse(btree, [])); 1261 | // // console.log(inOrderTraverse(btree, [])); 1262 | // // console.log(postOrderTraverse(btree, [])); 1263 | 1264 | import { Graph } from "./datastructures.js"; 1265 | 1266 | const graph = new Graph(7); 1267 | graph.addNode(8); 1268 | graph.addEdge(7, 8, 10, 9, 11, 12, 13, 14); 1269 | graph.removeNode(12); 1270 | graph.addNode(10); 1271 | graph.addEdge(7, 8); 1272 | graph.addEdge(7, 9); 1273 | graph.addEdge(8, 9); 1274 | graph.addEdge(9, 100); 1275 | graph.addEdge(10, 24); 1276 | graph.addEdge(12, 25); 1277 | 1278 | //-------------- DEPTH FIRST TRAVERSAL THROUGH ABOVE GRAPH ALGORITHM ------------- 1279 | 1280 | function depthFirstTraversal(value, graph) { 1281 | const visited = {}; 1282 | function depthFirst(value, arr) { 1283 | if (!(value in visited)) { 1284 | visited[value] = true; 1285 | arr.push(value); 1286 | const connectedNodes = graph[value].connections; 1287 | for (let i = 0; i < connectedNodes.length; i++) { 1288 | depthFirst(connectedNodes[i], arr); 1289 | } 1290 | } 1291 | return arr; 1292 | } 1293 | return depthFirst(value, []); 1294 | } 1295 | 1296 | // // console.log(depthFirstTraversal(7, graph)); 1297 | 1298 | //-------------- BREADTH FIRST TRAVERSAL THROUGH ABOVE GRAPH ALGORITHM ------------- 1299 | 1300 | function breadthFirstTraversal(value, graph) { 1301 | const visited = {}; 1302 | const arr = [...graph[value].connections]; 1303 | visited[value] = true; 1304 | const result = [value]; 1305 | 1306 | for (let i = 0; i < arr.length; i++) { 1307 | if (!(arr[i] in visited)) { 1308 | visited[arr[i]] = true; 1309 | var temp = arr[i]; 1310 | result.push(arr[i]); 1311 | arr.push(...graph[temp].connections); 1312 | } 1313 | } 1314 | return result; 1315 | } 1316 | 1317 | // // console.log(breadthFirstTraversal(7, graph)); 1318 | 1319 | //-------------- ALGORITHM TO SORT AN ARRAY RANDOMLY ------------- 1320 | 1321 | function sortArrayRandomly(array) { 1322 | const arr = [...array]; 1323 | for (let i = 0; i < arr.length; i++) { 1324 | var temp = arr[i]; 1325 | const randomPosition = Math.floor(Math.random() * (arr.length - 1)); 1326 | arr[i] = arr[randomPosition]; 1327 | arr[randomPosition] = temp; 1328 | } 1329 | return arr; 1330 | } 1331 | 1332 | var randomArr = sortArrayRandomly([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); 1333 | // console.log(randomArr); 1334 | 1335 | //-------------- ALGORITHM TO VALIDATE SUBSEQUENCE OF AN ARRAY ------------- 1336 | // console.log(":"); 1337 | 1338 | function isValidSubsequence(array, sequence) { 1339 | var arrC = [...array]; 1340 | var arr = []; 1341 | 1342 | for (let i = 0; i < sequence.length; i++) { 1343 | if (arrC.includes(sequence[i])) { 1344 | arr.push(sequence[i]); 1345 | arrC = arrC.splice(arrC.indexOf(sequence[i]) + 1, arrC.length); 1346 | } 1347 | } 1348 | 1349 | return arr.length === sequence.length ? true : false; 1350 | } 1351 | 1352 | // tests; 1353 | // console.log(isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [1, 6, -1, 10])); // true 1354 | // console.log( 1355 | // isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [5, 1, 22, 25, 6, -1, 8, 10]) 1356 | // ); //true 1357 | // console.log( 1358 | // isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [5, 1, 22, 6, -1, 8, 10]) 1359 | // ); //true 1360 | // console.log(isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [1, 6, 10])); //true 1361 | // console.log(isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [5, 1, 22, 10])); //true 1362 | // console.log(isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [5, -1, 8, 10])); //true 1363 | // console.log(isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [25])); //true 1364 | // console.log(isValidSubsequence([1, 1, 1, 1, 1], [1, 1, 1])); //true 1365 | // console.log( 1366 | // isValidSubsequence( 1367 | // [5, 1, 22, 25, 6, -1, 8, 10], 1368 | // [5, 1, 22, 25, 6, -1, 8, 10, 12] 1369 | // ) 1370 | // ); //false 1371 | // console.log( 1372 | // isValidSubsequence( 1373 | // [5, 1, 22, 25, 6, -1, 8, 10], 1374 | // [4, 5, 1, 22, 25, 6, -1, 8, 10, 12] 1375 | // ) 1376 | // ); //false 1377 | // console.log( 1378 | // isValidSubsequence( 1379 | // [5, 1, 22, 25, 6, -1, 8, 10], 1380 | // [5, 1, 22, 23, 6, -1, 8, 10, 12] 1381 | // ) 1382 | // ); //false 1383 | // console.log( 1384 | // isValidSubsequence( 1385 | // [5, 1, 22, 25, 6, -1, 8, 10], 1386 | // [5, 1, 22, 22, 25, 6, -1, 8, 10, 12] 1387 | // ) 1388 | // ); //false 1389 | // console.log( 1390 | // isValidSubsequence( 1391 | // [5, 1, 22, 25, 6, -1, 8, 10], 1392 | // [5, 1, 22, 22, 6, -1, 8, 10, 12] 1393 | // ) 1394 | // ); //false 1395 | // console.log(isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [1, 6, -1, -1])); //false 1396 | // console.log( 1397 | // isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [1, 6, -1, -1, 10]) 1398 | // ); //false 1399 | // console.log(isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [1, 6, -1, -2])); //false 1400 | // console.log(isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [26])); //false 1401 | // console.log( 1402 | // isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [5, 1, 25, 22, 6, -1, 8, 10]) 1403 | // ); //false 1404 | // console.log(isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [5, 26, 22, 8])); //false 1405 | // console.log(isValidSubsequence([1, 1, 6, 1], [1, 1, 1, 6])); //false 1406 | // console.log( 1407 | // isValidSubsequence( 1408 | // [5, 1, 22, 25, 6, -1, 8, 10], 1409 | // [1, 6, -1, 10, 11, 11, 11, 11] 1410 | // ) 1411 | // ); //false 1412 | // console.log( 1413 | // isValidSubsequence( 1414 | // [5, 1, 22, 25, 6, -1, 8, 10], 1415 | // [5, 1, 22, 25, 6, -1, 8, 10, 10] 1416 | // ) 1417 | // ); //false 1418 | // console.log(isValidSubsequence([5, 1, 22, 25, 6, -1, 8, 10], [1, 6, -1, 5])); //false 1419 | 1420 | //-------------- ALGORITHM TO A RANDOM ID GENERATOR ------------- 1421 | 1422 | function id() { 1423 | var randomId = "_"; 1424 | const fakeIdGen = () => Math.floor(Math.random() * 9); 1425 | for (let i = 0; i < 5; i++) { 1426 | randomId += fakeIdGen(); 1427 | } 1428 | return randomId; 1429 | } 1430 | 1431 | // // console.log(id()); 1432 | 1433 | function randomNumberBetween(first, second) { 1434 | if (typeof first !== "number" && typeof second !== "number") 1435 | return "error expected type Number"; 1436 | const firstVal = Number(first); 1437 | const secondVal = Number(second); 1438 | const diff = Math.abs(firstVal - secondVal) - 1; 1439 | 1440 | const randomDiff = Math.floor(Math.random() * diff); 1441 | const bigger = firstVal > secondVal ? firstVal - 1 : secondVal - 1; 1442 | return Math.abs(bigger - randomDiff); 1443 | } 1444 | // // console.log(randomNumberBetween(20, 10)); 1445 | 1446 | //Optimized fibonacciSeries function 1447 | export function fibonacciSeries(value) { 1448 | if (value > 1500) return Infinity; 1449 | const cache = {}; 1450 | function fibHelper(value) { 1451 | if (value < 3) return 1; 1452 | const prev = cache[value - 1] ? cache[value - 1] : fibHelper(value - 1); 1453 | const secondPrev = cache[value - 2] 1454 | ? cache[value - 2] 1455 | : fibHelper(value - 2); 1456 | const result = prev + secondPrev; 1457 | if (!cache[value]) cache[value] = result; 1458 | return result; 1459 | } 1460 | const answer = fibHelper(value); 1461 | //// console.log(cache); 1462 | return answer; 1463 | } 1464 | 1465 | const answer = fibonacciSeries(5); 1466 | // console.log(answer); 1467 | 1468 | const randomPasswordGen = () => { 1469 | var use = "api-"; 1470 | for (let i = 0; i < 5; i++) { 1471 | use += String.fromCharCode(randomNumberBetween(97, 122)); 1472 | } 1473 | use += "-"; 1474 | for (let i = 0; i < 5; i++) { 1475 | const randomNo = Math.floor(Math.random() * 10); 1476 | use += randomNo; 1477 | } 1478 | return use; 1479 | }; 1480 | // console.log(randomPasswordGen()); 1481 | 1482 | export function MostOccuringNumberInAnArray(arr) { 1483 | let answer = null; 1484 | let noOfRepeation = null; 1485 | let cache = {}; 1486 | 1487 | for (var i = 0; i < arr.length; i++) { 1488 | if (cache[arr[i]]) { 1489 | cache[arr[i]] = ++cache[arr[i]]; 1490 | } else { 1491 | cache[arr[i]] = 1; 1492 | } 1493 | } 1494 | 1495 | for (var key in cache) { 1496 | if (!noOfRepeation) { 1497 | noOfRepeation = cache[key]; 1498 | answer = Number(key); 1499 | } else if (cache[key] > noOfRepeation) { 1500 | noOfRepeation = cache[key]; 1501 | answer = Number(key); 1502 | } else if (cache[key] === noOfRepeation) { 1503 | if (typeof answer === "object") { 1504 | answer = { ...answer, [key]: noOfRepeation }; 1505 | } else { 1506 | answer = { [answer]: noOfRepeation, [key]: noOfRepeation }; 1507 | } 1508 | } 1509 | } 1510 | 1511 | return answer; 1512 | } 1513 | 1514 | // const testArray = [ 1515 | // 1, 9, 4, 9, 4, 5, 4, 5, 9, 5, 9, 7, 4, 6, 7, 9, 7, 6, 6, 6, 6, 4, 1516 | // ]; 1517 | // const testArray2 = [1, 4, 9, 4, 5, 9, 5, 7, 4, 6, 7, 9, 7, 6, 6, 6, 6]; 1518 | const testArray2 = [1, 9, 4, 4, 5, 5, 9, 5, 9, 7, 4, 6, 7, 9, 7, 6, 6, 6, 6]; 1519 | 1520 | const reply = MostOccuringNumberInAnArray(testArray2); 1521 | // console.log(reply); 1522 | 1523 | function staircase(n) { 1524 | // Write your code here 1525 | var result = ""; 1526 | for (let data = 1; data <= n; data++) { 1527 | let hash = new Array(n).fill(` `); 1528 | for (let hashCount = 0; hashCount < data; hashCount++) { 1529 | hash[n - 1 - hashCount] = "#"; 1530 | } 1531 | result = `${result}${hash.join("")}${"\n"}`; 1532 | } 1533 | return result; 1534 | } 1535 | 1536 | //console.log(6) 1537 | 1538 | /* A function that takes 3 argument 1539 | -------- 1540 | first argument: First sorted array with blank spaces for addition of other array 1541 | 1542 | second argument: Length of first sorted array 1543 | 1544 | third argument: Second sorted array 1545 | 1546 | forth argument: Length of second sorted array 1547 | ---------- 1548 | merges two sorted array into one big sorted array, and mutates the first array.to answer. */ 1549 | 1550 | //Time Complexity: O(n) 1551 | const mergeMutate = function (firstArray, m, secondArray, n) { 1552 | const copyOfFirstArray = firstArray.splice(0, m); 1553 | const copyOfSecondArray = [...secondArray]; 1554 | let arrayLocationCounter = 0; 1555 | 1556 | while (copyOfFirstArray.length && copyOfSecondArray.length) { 1557 | if (copyOfFirstArray[0] < copyOfSecondArray[0]) { 1558 | firstArray[arrayLocationCounter] = copyOfFirstArray.shift(); 1559 | } else { 1560 | firstArray[arrayLocationCounter] = copyOfSecondArray.shift(); 1561 | } 1562 | arrayLocationCounter += 1; 1563 | } 1564 | 1565 | //In case of any remaining element in array 1566 | firstArray.push(...copyOfFirstArray, ...copyOfSecondArray); 1567 | }; 1568 | 1569 | let nums1 = [25, 40, 50, 55, 65, 0, 0, 0]; 1570 | let nums2 = [2, 10, 100]; 1571 | 1572 | mergeMutate(nums1, 5, nums2, 3); 1573 | 1574 | console.log(nums1); //expected anser: [2, 10, 25, 40, 50, 55, 65, 100] 1575 | 1576 | /*A function that takes 3 arguments 1577 | n: length of array, 1578 | k: number combinations should be divisible by 1579 | ar: array 1580 | 1581 | Finds the possible number of pairs/combinations for which can be divisible by argument k. 1582 | */ 1583 | 1584 | function divisibleSumPairs(n, k, ar) { 1585 | // Write your code here 1586 | let noOfRepeatation = 0; 1587 | 1588 | for (let i = 0; i < ar.length; i++) { 1589 | let mutateableArray = ar.slice(i + 1, ar.length); 1590 | for (let j = 0; j < mutateableArray.length; j++) { 1591 | (ar[i] + mutateableArray[j]) % k === 0 && ++noOfRepeatation; 1592 | } 1593 | } 1594 | return noOfRepeatation; 1595 | } 1596 | 1597 | /* 1598 | Test 1599 | n = 6, k = 3 ar = [1, 3, 2, 6, 1, 2]; 1600 | possible combinations divisible by k = 3 are: 1601 | ar[0] + ar[2] = 1 + 2 = 3 1602 | ar[0] + ar[5] = 1 + 2 = 3 1603 | ar[1] + ar[3] = 3 + 6 = 9 1604 | ar[2] + ar[4] = 2 + 1 = 3 1605 | ar[4] + ar[5] = 1 + 2 = 3 1606 | 1607 | Therefore ther are 5 possible combinations divisible by k = 3 1608 | answer = 5 1609 | */ 1610 | 1611 | console.log(divisibleSumPairs(6, 3, [1, 3, 2, 6, 1, 2])); //Answer: 5 1612 | 1613 | //Algorithm to Inbuilt Javascript slice array methos 1614 | function sliceJS(arr, startFrom, NoOfElements) { 1615 | const errorCheck = startFrom + NoOfElements; 1616 | if (errorCheck > arr.length) throw new Error(`Error in input values`); 1617 | let countCheck = 0; 1618 | const resultArr = []; 1619 | for (let i = 0; i < arr.length; i++) { 1620 | if (i >= startFrom && countCheck !== NoOfElements) { 1621 | resultArr.push(arr[i]); 1622 | countCheck++; 1623 | } 1624 | } 1625 | return resultArr; 1626 | } 1627 | // const sliceArrTest = [0, 2, 3]; 1628 | // console.log(sliceJS(sliceArrTest, 0, sliceArrTest.length)); //[0, 2, 3] 1629 | // console.log(sliceJS(sliceArrTest, 0, sliceArrTest.length - 1)); //[0, 2] 1630 | // console.log(sliceJS(sliceArrTest, 0, 1)); //[0,] 1631 | // console.log(sliceJS(sliceArrTest, 1, 3)); //Error 1632 | 1633 | //Javascript inbuilt join string method 1634 | function joinJS(arr, joinBy) { 1635 | let accumulator = ""; 1636 | for (let i = 0; i < arr.length; i++) { 1637 | //Error handling 1638 | if (typeof arr[i] !== "string") 1639 | throw new Error(`can only work on strings; 1640 | value input: ${arr[i]}`); 1641 | 1642 | if (i !== arr.length - 1) { 1643 | accumulator = `${accumulator}${arr[i]}${joinBy}`; 1644 | } else { 1645 | accumulator = `${accumulator}${arr[i]}`; 1646 | } 1647 | } 1648 | return accumulator; 1649 | } 1650 | const joinJSArrTest = ["me", "she"]; 1651 | console.log(joinJS(joinJSArrTest, "")); //meshe 1652 | console.log(joinJS(joinJSArrTest, " ")); //me she 1653 | console.log(joinJS(joinJSArrTest, "|")); //me|she 1654 | 1655 | //Javascript inbuilt split string method 1656 | function splitJS(string, splitBy) { 1657 | //Error handler 1658 | if (typeof string !== "string" || typeof splitBy !== "string") 1659 | throw new Error(`can only work on strings; 1660 | value input: ${string}`); 1661 | const resultArr = []; 1662 | let concatString = ""; 1663 | for (let i = 0; i < string.length; i++) { 1664 | if (splitBy === "") { 1665 | resultArr.push(string[i]); 1666 | } else if (string[i] === splitBy) { 1667 | resultArr.push(concatString); 1668 | concatString = ""; 1669 | } else { 1670 | concatString = `${concatString}${string[i]}`; 1671 | } 1672 | } 1673 | //push in what is left in concatString 1674 | resultArr.push(concatString); 1675 | return resultArr; 1676 | } 1677 | 1678 | console.log(splitJS("me|she|me", "|")); //['me', 'she', 'me'] 1679 | console.log(splitJS("me she me", " ")); //['me', 'she', 'me'] 1680 | console.log(splitJS("me she me", "|")); //['me she me'] 1681 | console.log(splitJS("me she me", "")); //['m', 'e' ' ', 's', 'h', 'e', ' ', 'm', 'e'] 1682 | 1683 | //factors of a number 1684 | 1685 | function factorsOf(number) { 1686 | if (typeof number !== "number") 1687 | throw new Error(`Expected a number 1688 | received: 1689 | ${typeof number} : ${number}`); 1690 | const resultOBJ = {}; 1691 | let counter = 1; 1692 | while (counter <= number) { 1693 | if (!resultOBJ[counter]) { 1694 | if (number % counter === 0) { 1695 | const factorKey = number / counter; 1696 | resultOBJ[counter] = `${counter} * ${factorKey}`; 1697 | resultOBJ[factorKey] = `${factorKey} * ${counter}`; 1698 | } 1699 | } 1700 | counter++; 1701 | } 1702 | return resultOBJ; 1703 | } 1704 | 1705 | // console.log(factorsOf(6)); //{ '1': '1 * 6', '2': '2 * 3', '3': '3 * 2', '6': '6 * 1' } 1706 | // console.log(factorsOf(4)); //{ '1': '1 * 4', '2': '2 * 2', '4': '4 * 1' } 1707 | // console.log(factorsOf(7)); //{ '1': '1 * 7', '7': '7 * 1' } 1708 | // console.log(factorsOf(100)); //{'1': '1 * 100','2': '2 * 50','4': '4 * 25','5': '5 * 20','10': '10 * 10','20': '20 * 5'25': '25 * 4','50': '50 * 2','100': '100 * 1'} 1709 | // console.log(factorsOf("50")); //Throws and Error 1710 | 1711 | //A function that takes an infinite number of arguments of with type number or an array of numbers and returns the LCM (lowerst common mutiple) of those numbers. 1712 | function LCM(...arr) { 1713 | if (!typeof arr[0] === "number" && !Array.isArray(arr[0])) 1714 | throw new Error(`Expected numbers or an array 1715 | received: 1716 | ${typeof arr[0]} : ${arr[0]}`); 1717 | 1718 | let arrClone = null; 1719 | 1720 | if (Array.isArray(arr[0])) { 1721 | arrClone = [...arr[0]]; 1722 | } else { 1723 | arrClone = [...arr]; 1724 | } 1725 | 1726 | let accumulator = 1; 1727 | let highestNumber = Math.max(...arrClone); 1728 | let counter = 2; 1729 | while (counter <= highestNumber) { 1730 | let currentDivisor = null; 1731 | //Loop through number in array. 1732 | for (let i = 0; i < arrClone.length; i++) { 1733 | //type check 1734 | if (typeof arrClone[i] !== "number") 1735 | throw new Error(`Expected a number 1736 | received: 1737 | ${typeof arrClone[i]} : ${arrClone[i]}`); 1738 | arrClone[i] = Math.floor(arrClone[i]); 1739 | 1740 | if ( 1741 | counter <= arrClone[i] && 1742 | arrClone[i] % counter === 0 && 1743 | arrClone[i] !== 0 1744 | ) { 1745 | let divident = arrClone[i] / counter; 1746 | arrClone[i] = divident; 1747 | if (!currentDivisor) { 1748 | currentDivisor = counter; 1749 | accumulator *= currentDivisor; 1750 | } 1751 | } 1752 | } 1753 | counter++; 1754 | const highestNumberPlus = highestNumber + 1; 1755 | if ( 1756 | counter === highestNumberPlus && 1757 | !arrClone.every((elem) => elem === 1) 1758 | ) { 1759 | counter = 2; 1760 | highestNumber = Math.max(...arrClone); 1761 | } 1762 | } 1763 | return accumulator === 1 ? NaN : accumulator; 1764 | } 1765 | 1766 | // console.log(LCM([1, 2, 5])); //10 1767 | // console.log(LCM(1, 2, 5)); //10 1768 | // console.log(LCM([1, 2, 5, 6, 7])); //210 1769 | // console.log(LCM(1, 2, 5, 6, 7)); //210 1770 | // console.log(LCM(1, 2, 5, 6, 7, [44, 6])); //NaN 1771 | // console.log(LCM(1, 2, 5, 6, 7, "6")); //Throws an Error 1772 | 1773 | //A function that takes an infinite number of arguments of with type number or an array of numbers and returns the HCF(highest common factor) of those numbers. 1774 | function HCF(...arr) { 1775 | if (!typeof arr[0] === "number" && !Array.isArray(arr[0])) 1776 | throw new Error(`Expected numbers or an array 1777 | received: 1778 | ${typeof arr[0]} : ${arr[0]}`); 1779 | 1780 | let arrClone = null; 1781 | let finalCheckArr = []; 1782 | 1783 | if (Array.isArray(arr[0])) { 1784 | arrClone = [...arr[0]]; 1785 | } else { 1786 | arrClone = [...arr]; 1787 | } 1788 | 1789 | const hcfArrClone = [...arrClone]; 1790 | let accumulator = 1; 1791 | let highestNumber = Math.max(...arrClone); 1792 | let counter = 2; 1793 | while (counter <= highestNumber) { 1794 | // let currentDivisor = null; 1795 | let hcfCheck = true; 1796 | //Loop through number in array. 1797 | for (let i = 0; i < arrClone.length; i++) { 1798 | //type check 1799 | if (typeof arrClone[i] !== "number") 1800 | throw new Error(`Expected a number 1801 | received: 1802 | ${typeof arrClone[i]} : ${arrClone[i]}`); 1803 | 1804 | arrClone[i] = Math.floor(arrClone[i]); 1805 | if (arrClone[i] % counter !== 0) { 1806 | hcfCheck = false; 1807 | } 1808 | 1809 | if (counter <= arrClone[i] && arrClone[i] !== 0 && hcfCheck) { 1810 | let divident = arrClone[i] / counter; 1811 | hcfArrClone[i] = divident; 1812 | if (i === arrClone.length - 1) { 1813 | arrClone = [...hcfArrClone]; 1814 | accumulator *= counter; 1815 | } 1816 | } else { 1817 | break; 1818 | } 1819 | } 1820 | counter++; 1821 | const highestNumberPlus = highestNumber + 1; 1822 | 1823 | if (counter === highestNumberPlus) { 1824 | highestNumber = Math.max(...arrClone); 1825 | if (JSON.stringify(arrClone) !== JSON.stringify(finalCheckArr)) { 1826 | counter = 2; 1827 | finalCheckArr = [...arrClone]; 1828 | } 1829 | } 1830 | } 1831 | return accumulator === 1 ? 0 : accumulator; 1832 | } 1833 | 1834 | // console.log(HCF([12, 16])); //4 1835 | // console.log(HCF(12, 16)); //4 1836 | // console.log(HCF([12, 18])); //6 1837 | // console.log(HCF(12, 18)); //6 1838 | // console.log(HCF([1, 2])); //0 1839 | // console.log(HCF([2, 4])); //2 1840 | // console.log(HCF([1, 2])); //0 1841 | // console.log(HCF([2, 4, 8, 16, 10])); //2 1842 | 1843 | //algorithm to javascript some arr method, 1844 | /* 1845 | Takes two arguments, 1846 | Argument 1 --- Array 1847 | Argument 2 --- item to search for 1848 | ------- 1849 | Return a boolean either true of false, return true if arr contains item and false it it dosent 1850 | */ 1851 | 1852 | function someJS(arr, item) { 1853 | let answer = false; 1854 | for (let i = 0; i < arr.length; i++) { 1855 | if (arr[i] === item) { 1856 | answer = true; 1857 | break; 1858 | } 1859 | } 1860 | return item; 1861 | } 1862 | 1863 | console.log(someJS([1, 2, 3, 4, 6], 3)); //true 1864 | 1865 | //algorithm to javascript every arr method, 1866 | /* 1867 | Takes two arguments, 1868 | Argument 1 --- Array 1869 | Argument 2 --- item to search for 1870 | ------- 1871 | Return a boolean either true of false, return true if all elemens in the arr are the same as the item and false if not. 1872 | */ 1873 | 1874 | function everyJS(arr, item) { 1875 | let answer = true; 1876 | for (let i = 0; i < arr.length; i++) { 1877 | if (arr[i] !== item) { 1878 | answer = false; 1879 | break; 1880 | } 1881 | } 1882 | return item; 1883 | } 1884 | 1885 | console.log(everyJS([1, 2, 3, 4, 6], 3)); //false 1886 | 1887 | /*Takes two argument 1888 | Argument 1 -- The array to push into 1889 | Argument 2 -- The value to push into the array 1890 | Returns the mutated version of the array containining with the second argument pushed into the last entery of the array. 1891 | */ 1892 | function pushJS(arr, item) { 1893 | arr[arr.length] = item; 1894 | return arr; 1895 | } 1896 | 1897 | // console.log(pushJS([1, 2, 3], 4)); //[1, 2, 3, 4] 1898 | 1899 | /*Takes two argument 1900 | Argument 1 -- The array to push into 1901 | Argument 2 -- The value to fill the array with 1902 | Returns the mutated version of the array with all enteries filled with the second argument 1903 | */ 1904 | function fillJS(arr, item) { 1905 | for (let i = 0; i < arr.length; i++) { 1906 | arr[i] = item; 1907 | } 1908 | return arr; 1909 | } 1910 | 1911 | console.log(fillJS([1, 2, 3, 4], 3)); //[3, 3, 3, 3] 1912 | 1913 | /* 1914 | A funciton that takes two argument n and r computating maths combination calculation 1915 | */ 1916 | 1917 | function combination(n, r) { 1918 | if (typeof n !== "number" || typeof r !== "number") 1919 | throw new Error(`Expect type of ${n} and ${r} as number 1920 | Received 1921 | n as ${typeof n} 1922 | r as ${typeof r} 1923 | `); 1924 | if (n < r) 1925 | throw new Error(` 1926 | Expect ${n} to be greater than ${r}`); 1927 | const nFactorial = factorial2(n); 1928 | const nMinusRFactorial = factorial2(n - r); 1929 | const rFactorial = factorial2(r); 1930 | 1931 | return nFactorial / (nMinusRFactorial * rFactorial); 1932 | } 1933 | 1934 | // console.log(combination(2, 2)); //1 1935 | // console.log(combination(5, 3)); //10 1936 | 1937 | /* 1938 | A funciton that takes two argument n and r computating maths permutation calculation 1939 | */ 1940 | function permutation(n, r) { 1941 | if (typeof n !== "number" || typeof r !== "number") 1942 | throw new Error(`Expect type of ${n} and ${r} as number 1943 | Received 1944 | n as ${typeof n} 1945 | r as ${typeof r} 1946 | `); 1947 | if (n < r) 1948 | throw new Error(` 1949 | Expect ${n} to be greater than ${r}`); 1950 | const nFactorial = factorial2(n); 1951 | const nMinusRFactorial = factorial2(n - r); 1952 | 1953 | return nFactorial / nMinusRFactorial; 1954 | } 1955 | 1956 | // console.log(permutation(2, 2)); //2 1957 | // console.log(permutation(5, 3)); //60 1958 | 1959 | function allLetters(string) { 1960 | if (typeof string !== "string") 1961 | throw new Error(`Expected value of input ${string} to be a string 1962 | Received 1963 | ${string} as a ${typeof string}`); 1964 | let result = true; 1965 | for (let i = 0; i < string.length; i++) { 1966 | const charCode = string.charCodeAt(i); 1967 | let upperCaseLetter = true; 1968 | let lowerCaseLetter = true; 1969 | 1970 | if (charCode < 65 || charCode > 90) { 1971 | upperCaseLetter = false; 1972 | } 1973 | if (charCode < 97 || charCode > 122) { 1974 | lowerCaseLetter = false; 1975 | } 1976 | 1977 | if (!upperCaseLetter && !lowerCaseLetter) { 1978 | result = false; 1979 | break; 1980 | } 1981 | } 1982 | return result; 1983 | } 1984 | 1985 | // console.log(allLetters("me")); //true 1986 | // console.log(allLetters("Me")); //true 1987 | // console.log(allLetters("MeTHIS")); //true 1988 | // console.log(allLetters("Me THIS")); //false 1989 | // console.log(allLetters("Me)")); //false 1990 | // console.log(allLetters("Me78")); //false 1991 | // console.log(allLetters("Me]")); //false 1992 | // console.log(allLetters("Me-")); //false 1993 | // console.log(allLetters(10)); //Throws error 1994 | 1995 | /* 1996 | A function that takes in a pretfix expression as string and calculate the infix value 1997 | 1998 | */ 1999 | 2000 | function calcHelper(first, symbol, second) { 2001 | //Postfix calc helper 2002 | if (symbol === "-") { 2003 | return first - second; 2004 | } 2005 | if (symbol === "+") { 2006 | return first + second; 2007 | } 2008 | if (symbol === "*") { 2009 | return first * second; 2010 | } 2011 | if (symbol === "/") { 2012 | return first / second; 2013 | } 2014 | if (symbol === "%") { 2015 | return first % second; 2016 | } 2017 | } 2018 | 2019 | export function prefixCalc(expression) { 2020 | const expressionAsArray = expression.split(" "); // array of data and symbols 2021 | const symbols = []; //intialize array of symbols 2022 | const store = []; 2023 | let accumulateCal = false; 2024 | for (let i = 0; i < expressionAsArray.length; i++) { 2025 | if (Number(expressionAsArray[i])) { 2026 | if (!accumulateCal) { 2027 | //do not assign if next element is a symbol 2028 | if (Number(expressionAsArray[i + 1])) { 2029 | accumulateCal = expressionAsArray[i]; 2030 | } else { 2031 | store.push(expressionAsArray[i]); 2032 | } 2033 | } else { 2034 | if (symbols.length > 0) { 2035 | accumulateCal = calcHelper( 2036 | Number(accumulateCal), 2037 | symbols.pop(), 2038 | Number(expressionAsArray[i]) 2039 | ); 2040 | } else { 2041 | accumulateCal = expressionAsArray[i]; 2042 | } 2043 | } 2044 | } else { 2045 | symbols.push(expressionAsArray[i]); 2046 | } 2047 | } 2048 | 2049 | //Check for remainder 2050 | for (let i = 0; i < store.length; i++) { 2051 | accumulateCal = calcHelper( 2052 | Number(store[i]), 2053 | symbols.pop(), 2054 | Number(accumulateCal) 2055 | ); 2056 | } 2057 | 2058 | return accumulateCal === false ? 0 : accumulateCal; 2059 | } 2060 | 2061 | console.log(prefixCalc("0")); //0 2062 | console.log(prefixCalc("+ 3 4")); //7 2063 | console.log(prefixCalc("- 3 * 4 5")); //-17 2064 | console.log(prefixCalc("* + 3 4 5")); //35 2065 | 2066 | /* 2067 | A function that takes in a postfix expression as string and calculate the infix value 2068 | 2069 | */ 2070 | 2071 | export function postfixCalc(expresssion) { 2072 | if (typeof expresssion !== "string") { 2073 | throw ` 2074 | Expected typeof expression to be string 2075 | Received: ${typeof expresssion} 2076 | `; 2077 | } 2078 | const expressionArr = expresssion.split(" "); 2079 | const numbers = []; 2080 | 2081 | for (let elem of expressionArr) { 2082 | const convertToNum = Number(elem); 2083 | if (!Number.isNaN(convertToNum)) { 2084 | numbers.push(convertToNum); 2085 | } else { 2086 | const removeLastNum = numbers.pop(); 2087 | const removeLastNum2 = numbers.pop(); 2088 | 2089 | const calculate = calcHelper(removeLastNum, elem, removeLastNum2); 2090 | numbers.push(calculate); 2091 | } 2092 | } 2093 | 2094 | return numbers[0]; 2095 | } 2096 | 2097 | console.log(postfixCalc("2 3 4 + * 5 6 7 8 + * + +")); //109 2098 | console.log(postfixCalc("2 3 4 * 6 / +")); //2.5 2099 | console.log(postfixCalc("5 7 + 1 *")); //12 2100 | 2101 | export function prefixCalc2(expression) { 2102 | let expressionRev = ""; 2103 | for (let i = expression.length - 1; i >= 0; i--) { 2104 | expressionRev += expression[i]; 2105 | } 2106 | 2107 | return postfixCalc(expressionRev); 2108 | } 2109 | 2110 | console.log(prefixCalc2("- 3 * 4 5")); //-17 2111 | console.log(prefixCalc2("* + 3 4 5")); //35 2112 | --------------------------------------------------------------------------------