├── .gitattributes ├── .gitignore ├── .prettierignore ├── .prettierrc ├── README.md ├── guess-the-output ├── adding-empty-and-non-empty-array.md ├── adding-two-array.md ├── array-length-after-deleting-element.md ├── array-reduce-right.md ├── bool-compare.md ├── bool-plus-number.md ├── bool-plus-string.md ├── calling-function-before-defining.md ├── delete-array-element.md ├── destructuring-and-string-joining.md ├── guess-return-type.md ├── hundred-by-zero.md ├── instanceof-number.md ├── is-deleted-array-element-undefined.md ├── is-nan-finite.md ├── is-this-not-a-number.md ├── new-array-to-string.md ├── set-array-element-by-index.md ├── string-charCodeAt.md ├── string-iterator.md ├── string-repeat.md ├── string-search-regex.md ├── substr-and-slice.md ├── the-number-constructor.md ├── tricky-array-init.md ├── typeof-array.md └── typeof-nan.md ├── package.json ├── programs ├── anagram.md ├── armstrong-number.md ├── array-inversion-count.md ├── binary-search-tree-breadth-first-search.md ├── binary-search-tree-implementation.md ├── binary-search-tree-inorder-traversal.md ├── binary-search-tree-postorder-traversal.md ├── binary-search-tree-preorder-traversal.md ├── binary-search.md ├── bubble-sort-recursive.md ├── bubble-sort.md ├── capitalize-first-letter-of-each-word.md ├── check-if-a-binary-tree-is-binary-search-tree-or-not.md ├── construct-binary-tree-from-inorder-and-postorder-traversal.md ├── construct-binary-tree-from-inorder-and-preorder-traversal.md ├── count-vowel.md ├── doubly-linked-list-get-element-by-index.md ├── doubly-linked-list-implementation.md ├── doubly-linked-list-insert-node-at-beginning.md ├── doubly-linked-list-insert-node-at-given-index.md ├── doubly-linked-list-remove-head-node.md ├── doubly-linked-list-remove-node-at-given-index.md ├── doubly-linked-list-replace-element-on-index.md ├── equilibrium-point-in-array.md ├── factorial-iterative.md ├── factorial-recursive.md ├── fibonacci-series-upto-n.md ├── find-least-occurred-element-in-an-array.md ├── graph-implementation.md ├── graph-traversal-breadth-first-search.md ├── graph-traversal-depth-first-search.md ├── greatest-common-divisor.md ├── insertion-sort.md ├── knapsack-problem-dynamic-programming.md ├── knapsack-problem-using-recursion-and-memoization.md ├── linear-search.md ├── linked-list-implementation.md ├── longest-common-subsequence.md ├── max-binary-heap.md ├── maximum-occuring-character.md ├── maximum-subarray-sum.md ├── merge-sort.md ├── merging-two-or-more-linked-lists-in-sorted-order.md ├── middle-element-in-linked-list.md ├── minimum-difference-between-two-elements-in-an-array.md ├── no-of-ones-in-binary-representation-of-a-number.md ├── nth-fibonacci-number.md ├── palindrome-check.md ├── perfect-number.md ├── priority-queue.md ├── pythagorean-triplet-in-an-array.md ├── queue-implementation.md ├── reverse-integer.md ├── reversing-the-content-of-array.md ├── segregate-even-odd-numbers-array.md ├── selection-sort.md ├── singly-linked-list-check-loop.md ├── singly-linked-list-check-palindrome.md ├── singly-linked-list-print-nth-node-from-end.md ├── singly-linked-list-print-nth-node.md ├── singly-linked-list-reverse-iterative.md └── stack-implementation.md ├── public ├── css │ └── main.css └── logo.png ├── questions ├── accidental-global-variable.md ├── how-does-the-bind-method-work.md ├── how-does-the-filter-method-work.md ├── how-does-the-map-method-work.md ├── how-to-encode-string-in-javascript.md ├── octal-literals-in-javascript.md ├── what-are-closures.md ├── what-are-new-features-in-es2020.md ├── what-is-IIFE.md ├── what-is-currying.md ├── what-is-the-difference-between-indexof-and-findindex.md ├── what-is-the-difference-between-map-and-foreach.md ├── what-is-use-strict-in-javascript.md ├── what-is-work-of-delete-keyword-in-javascript.md └── why-array-equals-not-array.md ├── routes ├── api.js ├── index.js ├── programs.js ├── questions.js ├── search.js └── topics.js ├── server.js ├── utils ├── gto.js ├── gto.test.js └── topics.js └── views ├── footer.ejs ├── gto.ejs ├── header.ejs ├── index.ejs ├── nav.ejs ├── program.ejs ├── programs.ejs ├── question.ejs ├── questions.ejs ├── search.ejs ├── searchresults.ejs ├── topic.ejs └── topics.ejs /.gitattributes: -------------------------------------------------------------------------------- 1 | *.md linguist-vendored 2 | *.ejs linguist-vendored -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *.md -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false, 4 | "semi": true, 5 | "singleQuote": true 6 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LearnJS 2 | 3 | This website has a collection of Javascript programs and questions. 4 | 5 | Live Preview: http://learnjs.tech/ 6 | 7 | ### Running it locally 8 | 9 | 1. Clone the repository 10 | ```bash 11 | $ git clone https://github.com/akulsr0/learn-js 12 | ``` 13 | 14 | 2. Install dependencies 15 | ```bash 16 | $ cd learn-js 17 | $ npm install 18 | ``` 19 | 20 | 3. Running server 21 | ```bash 22 | $ node server.js 23 | ``` 24 | 25 | Open http://localhost:3001 in browser to checkout it locally. 26 | 27 | ### Contributing 28 | 29 | #### Ways to contribute 30 | 31 | - Reporting a bug or issue 32 | - Adding a program 33 | - Adding a question 34 | 35 | #### STEPS: 36 | 37 | 1. Fork the repo, clone forked repo on your machine. 38 | 2. If you want to add a program goto programs folder, or else if you want to add some question goto questions folder. 39 | 3. Add a markdown file there, (NOTE: it's name must be in kebab-case i.e. "this-is-my-file.md") 40 | 4. Check other md files in same directory for reference how you need to add the content. 41 | 5. Commit and push to forked repo. 42 | 6. Send PR! 43 | 44 | ### About 45 | 46 | This project is built by [Akul Srivastava](https://akulsrivastava.com/). Here are my social profiles: 47 | 48 | - [Github](https://github.com/akulsr0) 49 | - [LinkedIn](https://www.linkedin.com/in/akulsr0/) 50 | - [Twitter](https://twitter.com/akulsr0) 51 | - [Instagram](https://www.instagram.com/akulsr0/) 52 | -------------------------------------------------------------------------------- /guess-the-output/adding-empty-and-non-empty-array.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | console.log([] + [] + 'foo'.split('')); 3 | ``` 4 | -------------------------------------------------------------------------------- /guess-the-output/adding-two-array.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let arr1 = [1,2,3]; 3 | let arr2 = [3,4,5]; 4 | 5 | console.log(arr1 + arr2) 6 | ``` 7 | -------------------------------------------------------------------------------- /guess-the-output/array-length-after-deleting-element.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let a = [1, 2, 3, 4, 5]; 3 | delete a[3]; 4 | 5 | console.log(a.length); 6 | ``` 7 | -------------------------------------------------------------------------------- /guess-the-output/array-reduce-right.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let arr = [1,2,'LOL',5]; 3 | 4 | arr.reduceRight((acc, val) => acc+val); 5 | ``` 6 | -------------------------------------------------------------------------------- /guess-the-output/bool-compare.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | console.log((true + false) > 2 + true); 3 | ``` 4 | -------------------------------------------------------------------------------- /guess-the-output/bool-plus-number.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let bool = true; 3 | let num = 1 4 | 5 | console.log(bool+num); 6 | ``` 7 | -------------------------------------------------------------------------------- /guess-the-output/bool-plus-string.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let bool = true; 3 | let str = '1' 4 | 5 | console.log(bool+str) 6 | ``` 7 | -------------------------------------------------------------------------------- /guess-the-output/calling-function-before-defining.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let name = 'John'; 3 | 4 | func(); 5 | 6 | function func() { 7 | console.log(name) 8 | } 9 | 10 | name = 'Jane'; 11 | ``` 12 | -------------------------------------------------------------------------------- /guess-the-output/delete-array-element.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let a = [1, 2, 3, 4, 5]; 3 | delete a[3]; 4 | 5 | console.log(a); 6 | ``` 7 | -------------------------------------------------------------------------------- /guess-the-output/destructuring-and-string-joining.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let vowels = ['a', 'e', 'i', 'o', 'u']; 3 | let [x, y, ...z] = vowels; 4 | 5 | console.log(z.join()); 6 | ``` 7 | -------------------------------------------------------------------------------- /guess-the-output/guess-return-type.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function bar() { 3 | return foo; 4 | foo = 10; 5 | function foo() {} 6 | var foo = '11'; 7 | } 8 | 9 | console.log(typeof bar()); 10 | ``` 11 | -------------------------------------------------------------------------------- /guess-the-output/hundred-by-zero.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | console.log(100/0); 3 | ``` 4 | -------------------------------------------------------------------------------- /guess-the-output/instanceof-number.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let x = 1; 3 | let y = new Number(1); 4 | 5 | let b1 = x instanceof Number; 6 | let b2 = y instanceof Number; 7 | 8 | console.log(b1===b2); 9 | ``` 10 | -------------------------------------------------------------------------------- /guess-the-output/is-deleted-array-element-undefined.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let a = [1, 2, 3, 4, 5]; 3 | delete a[3]; 4 | 5 | if(a[3]===undefined) { 6 | console.log(a.indexOf(undefined)); 7 | } else { 8 | console.log(a[3]); 9 | } 10 | ``` 11 | -------------------------------------------------------------------------------- /guess-the-output/is-nan-finite.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let ans = isFinite(NaN); 3 | 4 | console.log(ans); 5 | ``` 6 | -------------------------------------------------------------------------------- /guess-the-output/is-this-not-a-number.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let x = 23; 3 | let y = new Number(23); 4 | 5 | console.log(isNaN(y) === isNaN(x)); 6 | ``` 7 | -------------------------------------------------------------------------------- /guess-the-output/new-array-to-string.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | console.log(new Array(3).toString()); 3 | ``` 4 | -------------------------------------------------------------------------------- /guess-the-output/set-array-element-by-index.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let arr = [,,3]; 3 | arr[1] = 2; 4 | 5 | console.log(arr); 6 | ``` 7 | -------------------------------------------------------------------------------- /guess-the-output/string-charCodeAt.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let str = 'A and B'; 3 | 4 | let x = str.charCodeAt(0); 5 | let y = str.charCodeAt(2); 6 | let z = str.charCodeAt(1); 7 | 8 | console.log(z === y-x); 9 | ``` 10 | -------------------------------------------------------------------------------- /guess-the-output/string-iterator.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let digits = '12345'; 3 | 4 | let iter = digits[Symbol.iterator](); 5 | let char = iter.next(); 6 | 7 | console.log(typeof char.value); 8 | ``` 9 | -------------------------------------------------------------------------------- /guess-the-output/string-repeat.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let str = 'ha'; 3 | let laugh = str.repeat(3); 4 | 5 | console.log(str.repeat(3)); 6 | ``` 7 | -------------------------------------------------------------------------------- /guess-the-output/string-search-regex.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let sentence = "hey there, Hello WORLD!" 3 | 4 | let regex = /[A-Z]/g; 5 | 6 | let i = sentence.search(regex); 7 | console.log(sentence[i]); 8 | ``` 9 | -------------------------------------------------------------------------------- /guess-the-output/substr-and-slice.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let s = "LearnJS"; 3 | 4 | let sub1 = s.substr(1,4); 5 | let sub2 = s.slice(1,4); 6 | 7 | console.log(sub1 === sub2); 8 | ``` 9 | -------------------------------------------------------------------------------- /guess-the-output/the-number-constructor.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let a = 10; 3 | let b = new Number(10); 4 | 5 | console.log(a===b); 6 | ``` 7 | -------------------------------------------------------------------------------- /guess-the-output/tricky-array-init.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let x = Array(3); 3 | console.log(x); 4 | ``` 5 | -------------------------------------------------------------------------------- /guess-the-output/typeof-array.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let t = typeof []; 3 | 4 | console.log(t); 5 | ``` 6 | -------------------------------------------------------------------------------- /guess-the-output/typeof-nan.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let t = typeof NaN; 3 | 4 | console.log(t); 5 | ``` 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "learnjs-tech", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "server.js", 6 | "scripts": { 7 | "start": "node .", 8 | "test": "jest" 9 | }, 10 | "author": "Akul Srivastava", 11 | "license": "MIT", 12 | "dependencies": { 13 | "bluebird": "^3.7.2", 14 | "cors": "^2.8.5", 15 | "ejs": "^3.1.2", 16 | "express": "^4.17.1", 17 | "highlight.js": "^10.0.3", 18 | "marked": "^1.0.0", 19 | "underscore": "^1.10.2" 20 | }, 21 | "devDependencies": { 22 | "jest": "^26.0.1" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /programs/anagram.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function checkAnagram(str1, str2) { 3 | let sortedLowerStr1 = str1.toLowerCase().split('').sort().join(''); 4 | let sortedLowerStr2 = str2.toLowerCase().split('').sort().join(''); 5 | if (sortedLowerStr1 === sortedLowerStr2) { 6 | return true; 7 | } else { 8 | return false; 9 | } 10 | } 11 | 12 | console.log(checkAnagram('listen', 'silent')); // true 13 | console.log(checkAnagram('hey', 'heyy')); // false 14 | console.log(checkAnagram('the eyes', 'they see')); // true 15 | ``` 16 | -------------------------------------------------------------------------------- /programs/armstrong-number.md: -------------------------------------------------------------------------------- 1 | **Note:** Armstrong Numbers are those numbers whose sum of the cube of its digits equals the number itself. 2 | 3 | ```javascript 4 | function checkArmstrong(num){ 5 | let s = 0, n=num, d=0; 6 | while(n){ 7 | d = n%10; 8 | s += (d*d*d); 9 | n = Math.floor(n/10); 10 | } 11 | if(s == num) return true 12 | return false 13 | } 14 | 15 | let num = 153; 16 | checkArmstrong(num); // true 17 | ``` 18 | -------------------------------------------------------------------------------- /programs/array-inversion-count.md: -------------------------------------------------------------------------------- 1 | In an array, two elements at index i and j forms an inversion if a[i]>a[j] and iarr[j]) { 9 | count += 1; 10 | } 11 | } 12 | } 13 | return count; 14 | } 15 | 16 | let arr = [2,1,4,3,5] 17 | // Inversions: (2,1) and (4,3) 18 | 19 | console.log(countInversions(arr)) // 2 20 | ``` 21 | -------------------------------------------------------------------------------- /programs/binary-search-tree-breadth-first-search.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(val) { 6 | this.data = val; 7 | this.left = null; 8 | this.right = null; 9 | } 10 | } 11 | 12 | // BST Class 13 | class BinarySearchTree { 14 | // Constructor for BST 15 | constructor() { 16 | this.root = null; 17 | } 18 | // Inserting Elements in BST 19 | insert(val) { 20 | // Creating the new Node 21 | let newNode = new Node(val) 22 | // If tree is empty i.e. root node is null 23 | if(this.root === null) { 24 | // Insert new Node as Root Node 25 | this.root = newNode; 26 | return this; 27 | } else { 28 | // Initialize current as root node 29 | let current = this.root; 30 | while(true) { 31 | if(val < current.data) { 32 | // Checking if new node value is less 33 | // than current node's value 34 | if(current.left === null) { 35 | // If there is no left subtree, 36 | // Insert node as left child and return BST 37 | current.left = newNode; 38 | return this; 39 | } else { 40 | // If there is left subtree, change 41 | // current to current.left 42 | current = current.left; 43 | } 44 | } else { 45 | // If new node value is greater than 46 | // current node's value 47 | if(current.right === null) { 48 | // If there is no right subtree, 49 | // Insert node as right child and return BST 50 | current.right = newNode; 51 | return this; 52 | } else { 53 | // If there is right subtree, change 54 | // current to current.right 55 | current = current.right; 56 | } 57 | } 58 | } 59 | } 60 | } 61 | // Breadth First Search of BST 62 | bfs() { 63 | let node = this.root; 64 | let queue = []; 65 | let output = []; 66 | queue.push(node); 67 | while(queue.length!==0) { 68 | node = queue.shift(); 69 | output.push(node.data); 70 | if(node.left) { 71 | queue.push(node.left); 72 | } 73 | if(node.right) { 74 | queue.push(node.right); 75 | } 76 | } 77 | return output; 78 | } 79 | } 80 | 81 | // Creating a Binary Search Tree 82 | let bst = new BinarySearchTree(); 83 | 84 | // First node will be inserted 85 | // as root node 86 | bst.insert(100); 87 | 88 | // Inserting more nodes... 89 | bst.insert(50); 90 | bst.insert(150); 91 | bst.insert(175); 92 | bst.insert(130); 93 | bst.insert(60); 94 | bst.insert(20); 95 | 96 | // Getting BFS of tree 97 | bst.bfs(); 98 | // [100,50,150,20,60,130,175] 99 | ``` 100 | 101 | Following tree is demonstrated in the code above. 102 | 103 | ![](https://user-images.githubusercontent.com/43666833/82456922-73830f00-9ad2-11ea-8462-6735e2ec415a.png) 104 | -------------------------------------------------------------------------------- /programs/binary-search-tree-implementation.md: -------------------------------------------------------------------------------- 1 | ### BST Properties: 2 | - A node can have atmost two children. 3 | - Every node to left of parent is always less than the parent. 4 | - Every node to right of parent is always greater than the parent. 5 | 6 | ```javascript 7 | // Node Class 8 | class Node { 9 | // Constructor for Node 10 | constructor(val) { 11 | this.data = val; 12 | this.left = null; 13 | this.right = null; 14 | } 15 | } 16 | 17 | // BST Class 18 | class BinarySearchTree { 19 | // Constructor for BST 20 | constructor() { 21 | this.root = null; 22 | } 23 | // Inserting Elements in BST 24 | insert(val) { 25 | // Creating the new Node 26 | let newNode = new Node(val) 27 | // If tree is empty i.e. root node is null 28 | if(this.root === null) { 29 | // Insert new Node as Root Node 30 | this.root = newNode; 31 | return this; 32 | } else { 33 | // Initialize current as root node 34 | let current = this.root; 35 | while(true) { 36 | if(val < current.data) { 37 | // Checking if new node value is less 38 | // than current node's value 39 | if(current.left === null) { 40 | // If there is no left subtree, 41 | // Insert node as left child and return BST 42 | current.left = newNode; 43 | return this; 44 | } else { 45 | // If there is left subtree, change 46 | // current to current.left 47 | current = current.left; 48 | } 49 | } else { 50 | // If new node value is greater than 51 | // current node's value 52 | if(current.right === null) { 53 | // If there is no right subtree, 54 | // Insert node as right child and return BST 55 | current.right = newNode; 56 | return this; 57 | } else { 58 | // If there is right subtree, change 59 | // current to current.right 60 | current = current.right; 61 | } 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | // Creating a Binary Search Tree 69 | let bst = new BinarySearchTree(); 70 | 71 | // First node will be inserted 72 | // as root node 73 | bst.insert(100); 74 | 75 | // Inserting more nodes... 76 | bst.insert(50); 77 | bst.insert(150); 78 | bst.insert(175); 79 | bst.insert(130); 80 | bst.insert(60); 81 | bst.insert(20); 82 | ``` 83 | 84 | Following tree is demonstrated in the code above. 85 | 86 | ![](https://user-images.githubusercontent.com/43666833/82456922-73830f00-9ad2-11ea-8462-6735e2ec415a.png) 87 | -------------------------------------------------------------------------------- /programs/binary-search-tree-inorder-traversal.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(val) { 6 | this.data = val; 7 | this.left = null; 8 | this.right = null; 9 | } 10 | } 11 | 12 | // BST Class 13 | class BinarySearchTree { 14 | // Constructor for BST 15 | constructor() { 16 | this.root = null; 17 | } 18 | // Inserting Elements in BST 19 | insert(val) { 20 | // Creating the new Node 21 | let newNode = new Node(val) 22 | // If tree is empty i.e. root node is null 23 | if(this.root === null) { 24 | // Insert new Node as Root Node 25 | this.root = newNode; 26 | return this; 27 | } else { 28 | // Initialize current as root node 29 | let current = this.root; 30 | while(true) { 31 | if(val < current.data) { 32 | // Checking if new node value is less 33 | // than current node's value 34 | if(current.left === null) { 35 | // If there is no left subtree, 36 | // Insert node as left child and return BST 37 | current.left = newNode; 38 | return this; 39 | } else { 40 | // If there is left subtree, change 41 | // current to current.left 42 | current = current.left; 43 | } 44 | } else { 45 | // If new node value is greater than 46 | // current node's value 47 | if(current.right === null) { 48 | // If there is no right subtree, 49 | // Insert node as right child and return BST 50 | current.right = newNode; 51 | return this; 52 | } else { 53 | // If there is right subtree, change 54 | // current to current.right 55 | current = current.right; 56 | } 57 | } 58 | } 59 | } 60 | } 61 | // Inorder Traversal 62 | inorder() { 63 | // Declaring an empty list for output 64 | let output = []; 65 | // Inorder Traversal: 66 | // Left, Root, Right 67 | function traverse(node) { 68 | if(node.left) { 69 | traverse(node.left); 70 | } 71 | output.push(node.data); 72 | if(node.right) { 73 | traverse(node.right); 74 | } 75 | } 76 | traverse(this.root); 77 | return output; 78 | } 79 | } 80 | 81 | // Creating a Binary Search Tree 82 | let bst = new BinarySearchTree(); 83 | 84 | // First node will be inserted 85 | // as root node 86 | bst.insert(100); 87 | 88 | // Inserting more nodes... 89 | bst.insert(50); 90 | bst.insert(150); 91 | bst.insert(175); 92 | bst.insert(130); 93 | bst.insert(60); 94 | bst.insert(20); 95 | 96 | // Getting Inorder Traversal 97 | bst.inorder(); 98 | // [20,50,60,100,130,150,175] 99 | ``` 100 | 101 | Following tree is demonstrated in the code above. 102 | 103 | ![](https://user-images.githubusercontent.com/43666833/82456922-73830f00-9ad2-11ea-8462-6735e2ec415a.png) 104 | -------------------------------------------------------------------------------- /programs/binary-search-tree-postorder-traversal.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(val) { 6 | this.data = val; 7 | this.left = null; 8 | this.right = null; 9 | } 10 | } 11 | 12 | // BST Class 13 | class BinarySearchTree { 14 | // Constructor for BST 15 | constructor() { 16 | this.root = null; 17 | } 18 | // Inserting Elements in BST 19 | insert(val) { 20 | // Creating the new Node 21 | let newNode = new Node(val) 22 | // If tree is empty i.e. root node is null 23 | if(this.root === null) { 24 | // Insert new Node as Root Node 25 | this.root = newNode; 26 | return this; 27 | } else { 28 | // Initialize current as root node 29 | let current = this.root; 30 | while(true) { 31 | if(val < current.data) { 32 | // Checking if new node value is less 33 | // than current node's value 34 | if(current.left === null) { 35 | // If there is no left subtree, 36 | // Insert node as left child and return BST 37 | current.left = newNode; 38 | return this; 39 | } else { 40 | // If there is left subtree, change 41 | // current to current.left 42 | current = current.left; 43 | } 44 | } else { 45 | // If new node value is greater than 46 | // current node's value 47 | if(current.right === null) { 48 | // If there is no right subtree, 49 | // Insert node as right child and return BST 50 | current.right = newNode; 51 | return this; 52 | } else { 53 | // If there is right subtree, change 54 | // current to current.right 55 | current = current.right; 56 | } 57 | } 58 | } 59 | } 60 | } 61 | // Postorder Traversal 62 | postorder() { 63 | // Declaring an empty list for output 64 | let output = []; 65 | // Postorder Traversal: 66 | // Left, Right, Root 67 | function traverse(node) { 68 | if(node.left) { 69 | traverse(node.left); 70 | } 71 | if(node.right) { 72 | traverse(node.right); 73 | } 74 | output.push(node.data); 75 | } 76 | traverse(this.root); 77 | return output; 78 | } 79 | } 80 | 81 | // Creating a Binary Search Tree 82 | let bst = new BinarySearchTree(); 83 | 84 | // First node will be inserted 85 | // as root node 86 | bst.insert(100); 87 | 88 | // Inserting more nodes... 89 | bst.insert(50); 90 | bst.insert(150); 91 | bst.insert(175); 92 | bst.insert(130); 93 | bst.insert(60); 94 | bst.insert(20); 95 | 96 | // Getting Postorder Traversal 97 | bst.postorder(); 98 | // [20,60,50,130,175,150,100] 99 | ``` 100 | 101 | Following tree is demonstrated in the code above. 102 | 103 | ![](https://user-images.githubusercontent.com/43666833/82456922-73830f00-9ad2-11ea-8462-6735e2ec415a.png) 104 | -------------------------------------------------------------------------------- /programs/binary-search-tree-preorder-traversal.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(val) { 6 | this.data = val; 7 | this.left = null; 8 | this.right = null; 9 | } 10 | } 11 | 12 | // BST Class 13 | class BinarySearchTree { 14 | // Constructor for BST 15 | constructor() { 16 | this.root = null; 17 | } 18 | // Inserting Elements in BST 19 | insert(val) { 20 | // Creating the new Node 21 | let newNode = new Node(val) 22 | // If tree is empty i.e. root node is null 23 | if(this.root === null) { 24 | // Insert new Node as Root Node 25 | this.root = newNode; 26 | return this; 27 | } else { 28 | // Initialize current as root node 29 | let current = this.root; 30 | while(true) { 31 | if(val < current.data) { 32 | // Checking if new node value is less 33 | // than current node's value 34 | if(current.left === null) { 35 | // If there is no left subtree, 36 | // Insert node as left child and return BST 37 | current.left = newNode; 38 | return this; 39 | } else { 40 | // If there is left subtree, change 41 | // current to current.left 42 | current = current.left; 43 | } 44 | } else { 45 | // If new node value is greater than 46 | // current node's value 47 | if(current.right === null) { 48 | // If there is no right subtree, 49 | // Insert node as right child and return BST 50 | current.right = newNode; 51 | return this; 52 | } else { 53 | // If there is right subtree, change 54 | // current to current.right 55 | current = current.right; 56 | } 57 | } 58 | } 59 | } 60 | } 61 | // Preorder Traversal 62 | preorder() { 63 | // Declaring an empty list for output 64 | let output = []; 65 | // Preorder Traversal: 66 | // Root, Left, Right 67 | function traverse(node) { 68 | output.push(node.data); 69 | if(node.left) { 70 | traverse(node.left); 71 | } 72 | if(node.right) { 73 | traverse(node.right); 74 | } 75 | } 76 | traverse(this.root); 77 | return output; 78 | } 79 | } 80 | 81 | // Creating a Binary Search Tree 82 | let bst = new BinarySearchTree(); 83 | 84 | // First node will be inserted 85 | // as root node 86 | bst.insert(100); 87 | 88 | // Inserting more nodes... 89 | bst.insert(50); 90 | bst.insert(150); 91 | bst.insert(175); 92 | bst.insert(130); 93 | bst.insert(60); 94 | bst.insert(20); 95 | 96 | // Getting Preorder Traversal 97 | bst.preorder(); 98 | // [100,50,20,60,150,130,175] 99 | ``` 100 | 101 | Following tree is demonstrated in the code above. 102 | 103 | ![](https://user-images.githubusercontent.com/43666833/82456922-73830f00-9ad2-11ea-8462-6735e2ec415a.png) 104 | -------------------------------------------------------------------------------- /programs/binary-search.md: -------------------------------------------------------------------------------- 1 | **Note:** Binary Search can only be done on a sorted array. 2 | 3 | ```javascript 4 | function binarySearch(arr, element) { 5 | let left = 0 6 | let right = arr.length 7 | while (leftelement) { 10 | right = mid; 11 | } else if(arr[mid] arr[i + 1]) { 8 | let temp = arr[i]; 9 | arr[i] = arr[i + 1]; 10 | arr[i + 1] = temp; 11 | } 12 | } 13 | return bubbleSortRecursive(arr, n - 1); 14 | } 15 | 16 | let a = [2, 4, 1, 3, 5]; 17 | console.log(bubbleSortRecursive(a, a.length - 1)); // [1,2,3,4,5] 18 | ``` 19 | -------------------------------------------------------------------------------- /programs/bubble-sort.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function bubbleSort(arr) { 3 | for (let i = 0; i < arr.length; i++) { 4 | for (let j = 0; j < arr.length; j++) { 5 | if (arr[j] > arr[j + 1]) { 6 | let tmp = arr[j]; 7 | arr[j] = arr[j + 1]; 8 | arr[j + 1] = tmp; 9 | } 10 | } 11 | } 12 | return arr; 13 | } 14 | 15 | console.log(bubbleSort([2, 4, 1, 3, 5])); // [1,2,3,4,5] 16 | ``` 17 | -------------------------------------------------------------------------------- /programs/capitalize-first-letter-of-each-word.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function capitalize(str) { 3 | let wordsArr = []; 4 | for(let word of str.split(' ')) { 5 | let newWord = word[0].toUpperCase() + word.slice(1); 6 | wordsArr.push(newWord); 7 | } 8 | return wordsArr.join(' ') 9 | } 10 | 11 | let s = "deno and node are anagram" 12 | let capitalSentence = capitalize(s) 13 | 14 | console.log(capitalSentence) 15 | // 'Deno And Node Are Anagram' 16 | 17 | ``` -------------------------------------------------------------------------------- /programs/check-if-a-binary-tree-is-binary-search-tree-or-not.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.data = data; 7 | this.left = null; 8 | this.right = null; 9 | } 10 | } 11 | 12 | // BinaryTree Class 13 | class BinaryTree { 14 | // Constructor for Node 15 | constructor() { 16 | this.root = null; 17 | } 18 | // Inorder Traversal 19 | inorder() { 20 | // Declaring an empty list for output 21 | let output = []; 22 | // Inorder Traversal: 23 | // Left, Root, Right 24 | function traverse(node) { 25 | if(node.left) { 26 | traverse(node.left); 27 | } 28 | output.push(node.data); 29 | if(node.right) { 30 | traverse(node.right); 31 | } 32 | } 33 | traverse(this.root); 34 | return output; 35 | } 36 | // If Inorder traversal of binary tree is 37 | // sorted, then its a BST. 38 | checkBST() { 39 | let inorder = this.inorder(); 40 | let sortedInorder = this.inorder().sort((x,y)=>x-y); 41 | return inorder.join()===sortedInorder.join(); 42 | } 43 | } 44 | 45 | // Creating a new Binary Tree 46 | let bt = new BinaryTree(); 47 | 48 | // Adding some nodes 49 | bt.root = new Node(10); 50 | bt.root.left = new Node(5); 51 | bt.root.right = new Node(15); 52 | 53 | // Checking for BST (fig. a) 54 | console.log(bt.checkBST()); 55 | // true 56 | 57 | // Now its no more BST (fig. b) 58 | bt.root.left.left = new Node(11); 59 | 60 | // Checking for BST (fig. b) 61 | console.log(bt.checkBST()); 62 | // false 63 | ``` 64 | 65 | Following trees are mentioned in above code. 66 | 67 | ![](https://user-images.githubusercontent.com/43666833/83417634-00698900-a440-11ea-98a5-2245e33c8a9b.png) -------------------------------------------------------------------------------- /programs/construct-binary-tree-from-inorder-and-postorder-traversal.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.data = data; 7 | this.left = null; 8 | this.right = null; 9 | } 10 | } 11 | 12 | function buildTree(In, Post, n) { 13 | // Last element of postorder is root node 14 | // Hence creating new Node(root) 15 | let newNode = new Node(Post[n-1]); 16 | 17 | // Getting index of root node in 18 | // inorder traversal 19 | let iIndex = In.indexOf(Post[n-1]); 20 | 21 | // Left subarray to iIndex is left subtree 22 | // Getting inorder and postorder of left subtree 23 | let leftSubIn = In.slice(0, iIndex); 24 | let leftSubPost = Post.slice(0, leftSubIn.length); 25 | 26 | // Right subarray to iIndex is right subtree 27 | // Getting inorder and postorder of right subtree 28 | let rightSubIn = In.slice(iIndex+1, n); 29 | let rightSubPost = Post.slice(leftSubIn.length, n-1) 30 | 31 | // Recursively creating left subtree 32 | if(leftSubIn.length>0 && leftSubPost.length>0) { 33 | newNode.left = buildTree(leftSubIn, leftSubPost, leftSubIn.length); 34 | } 35 | // Recursively creating right subtree 36 | if(rightSubIn.length>0 && rightSubPost.length>0) { 37 | newNode.right = buildTree(rightSubIn, rightSubPost, rightSubIn.length); 38 | } 39 | 40 | // returning the root node 41 | return newNode; 42 | } 43 | 44 | // Preorder Traversal 45 | function preorder(root) { 46 | // Declaring an empty list for output 47 | let output = []; 48 | // Preorder Traversal: 49 | // Root, Left, Right 50 | function traverse(node) { 51 | output.push(node.data); 52 | if(node.left) { 53 | traverse(node.left); 54 | } 55 | if(node.right) { 56 | traverse(node.right); 57 | } 58 | } 59 | traverse(root); 60 | return output; 61 | } 62 | 63 | // Sample Inorder and Postorder 64 | let inorder = [3,5,6,8,11] ; 65 | let postorder = [5,3,8,11,6]; 66 | 67 | // Building tree 68 | let root = buildTree(inorder, postorder, inorder.length); 69 | 70 | console.log(preorder(root)); 71 | // [6, 3, 5, 11, 8] 72 | ``` 73 | 74 | Following tree is mentioned in the program above. 75 | 76 | ![](https://user-images.githubusercontent.com/43666833/83410860-c8a91400-a434-11ea-9d0c-e09e3694b017.png) -------------------------------------------------------------------------------- /programs/construct-binary-tree-from-inorder-and-preorder-traversal.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.data = data; 7 | this.left = null; 8 | this.right = null; 9 | } 10 | } 11 | 12 | function buildTree(In, Pre, n) { 13 | // First element of preorder is root node 14 | // Hence creating new Node(root) 15 | let newNode = new Node(Pre[0]); 16 | 17 | // Getting index of root node in 18 | // inorder traversal 19 | let iIndex = In.indexOf(Pre[0]); 20 | 21 | // Left subarray to iIndex is left subtree 22 | // Getting inorder and preorder of left subtree 23 | let leftSubIn = In.slice(0, iIndex); 24 | let leftSubPre = Pre.slice(1, leftSubIn.length+1); 25 | 26 | // Right subarray to iIndex is right subtree 27 | // Getting inorder and preorder of right subtree 28 | let rightSubIn = In.slice(iIndex+1, n); 29 | let rightSubPre = Pre.slice(leftSubIn.length+1, n); 30 | 31 | // Recursively creating left subtree 32 | if(leftSubIn.length>0 && leftSubPre.length>0) { 33 | newNode.left = buildTree(leftSubIn, leftSubPre, leftSubIn.length); 34 | } 35 | // Recursively creating right subtree 36 | if(rightSubIn.length>0 && rightSubPre.length>0) { 37 | newNode.right = buildTree(rightSubIn, rightSubPre, rightSubIn.length); 38 | } 39 | // returning the root node 40 | return newNode; 41 | } 42 | 43 | // Postorder Traversal 44 | function postorder(root) { 45 | // Declaring an empty list for output 46 | let output = []; 47 | // Postorder Traversal: 48 | // Left, Right, Root 49 | function traverse(node) { 50 | if(node.left) { 51 | traverse(node.left); 52 | } 53 | if(node.right) { 54 | traverse(node.right); 55 | } 56 | output.push(node.data); 57 | } 58 | traverse(root); 59 | return output; 60 | } 61 | 62 | // Sample Inorder and Preorder 63 | let inorder = [3,5,6,8,11]; 64 | let preorder = [6,3,5,11,8]; 65 | 66 | // Building tree 67 | let root = buildTree(inorder, preorder, inorder.length); 68 | 69 | console.log(postorder(root)); 70 | // [5, 3, 8, 11, 6] 71 | ``` 72 | 73 | Following tree is mentioned in the program above. 74 | 75 | ![](https://user-images.githubusercontent.com/43666833/83410860-c8a91400-a434-11ea-9d0c-e09e3694b017.png) -------------------------------------------------------------------------------- /programs/count-vowel.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function countVowel(str) { 3 | const matches = str.match(/[aeiou]/gi); 4 | return matches ? matches.length : 0; 5 | } 6 | 7 | console.log(countVowel("Learn js")); // 2 8 | console.log(countVowel("javascript")); // 3 9 | console.log(countVowel("why?")); // 0 10 | ``` -------------------------------------------------------------------------------- /programs/doubly-linked-list-get-element-by-index.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.prev = null; 7 | this.data = data; 8 | this.next = null; 9 | } 10 | } 11 | 12 | // DoublyLinkedList Class 13 | class DoublyLinkedList { 14 | // Constructor for DLL 15 | constructor() { 16 | this.head = null; 17 | this.tail = null; 18 | this.length = 0; 19 | } 20 | // Insert Node at end of DLL 21 | insert(data) { 22 | let newNode = new Node(data); 23 | if(this.head === null) { 24 | this.head = newNode; 25 | this.tail = newNode; 26 | } else { 27 | this.tail.next = newNode; 28 | newNode.prev = this.tail; 29 | this.tail = newNode; 30 | } 31 | this.length++; 32 | } 33 | // Get element by index 34 | get(i) { 35 | if(i<0 || i>=this.length) return null 36 | if(i <= this.length/2) { 37 | let count = 0; 38 | let tempHead = this.head; 39 | while(count != i) { 40 | tempHead = tempHead.next; 41 | count++; 42 | } 43 | return tempHead; 44 | } else { 45 | let count = this.length-1; 46 | let tempHead = this.tail; 47 | while(count != i) { 48 | tempHead = tempHead.prev; 49 | count--; 50 | } 51 | return tempHead; 52 | } 53 | } 54 | // Print the DLL 55 | print() { 56 | let head = this.head; 57 | let dllOutput = []; 58 | while(head!==null) { 59 | dllOutput.push(head.data) 60 | head = head.next 61 | } 62 | console.log(dllOutput.join(' <-> ')) 63 | } 64 | } 65 | 66 | // Creating a new DoublyLinkedList 67 | let dll = new DoublyLinkedList() 68 | 69 | // Inserting Some Nodes 70 | dll.insert(10); // 10 71 | dll.insert(15); // 10 <-> 15 72 | dll.insert(20); // 10 <-> 15 <-> 20 73 | dll.insert(25); // 10 <-> 15 <-> 20 <-> 25 74 | 75 | // Printing DLL after inserting Nodes 76 | dll.print(); 77 | // 10 <-> 15 <-> 20 <-> 25 78 | 79 | // Getting element by index 80 | console.log(dll.get(2).data); // 20 81 | ``` 82 | -------------------------------------------------------------------------------- /programs/doubly-linked-list-implementation.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.prev = null; 7 | this.data = data; 8 | this.next = null; 9 | } 10 | } 11 | 12 | // DoublyLinkedList Class 13 | class DoublyLinkedList { 14 | // Constructor for DLL 15 | constructor() { 16 | this.head = null; 17 | this.tail = null; 18 | this.length = 0; 19 | } 20 | // Insert Node at end of DLL 21 | insert(data) { 22 | let newNode = new Node(data); 23 | if(this.head === null) { 24 | this.head = newNode; 25 | this.tail = newNode; 26 | } else { 27 | this.tail.next = newNode; 28 | newNode.prev = this.tail; 29 | this.tail = newNode; 30 | } 31 | this.length++; 32 | } 33 | // Delete Tail Node from DLL 34 | delete() { 35 | if(!this.head) return undefined; 36 | let delNode = this.tail; 37 | if(this.length===1) { 38 | this.head = null; 39 | this.tail = null; 40 | } else { 41 | this.tail = delNode.prev; 42 | this.tail.next = null; 43 | delNode.prev = null; 44 | } 45 | this.length--; 46 | } 47 | // Print the DLL 48 | print() { 49 | let head = this.head; 50 | let dllOutput = []; 51 | while(head!==null) { 52 | dllOutput.push(head.data) 53 | head = head.next 54 | } 55 | console.log(dllOutput.join(' <-> ')) 56 | } 57 | } 58 | 59 | // Creating a new DoublyLinkedList 60 | let dll = new DoublyLinkedList() 61 | 62 | dll.insert(10); // 10 63 | dll.insert(15); // 10 <-> 15 64 | dll.insert(20); // 10 <-> 15 <-> 20 65 | dll.insert(25); // 10 <-> 15 <-> 20 <-> 25 66 | 67 | dll.delete(); // 10 <-> 15 <-> 20 68 | 69 | dll.print() 70 | // '10 <-> 15 <-> 20' 71 | ``` 72 | -------------------------------------------------------------------------------- /programs/doubly-linked-list-insert-node-at-beginning.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.prev = null; 7 | this.data = data; 8 | this.next = null; 9 | } 10 | } 11 | 12 | // DoublyLinkedList Class 13 | class DoublyLinkedList { 14 | // Constructor for DLL 15 | constructor() { 16 | this.head = null; 17 | this.tail = null; 18 | this.length = 0; 19 | } 20 | // Insert Node at end of DLL 21 | insert(data) { 22 | let newNode = new Node(data); 23 | if(this.head === null) { 24 | this.head = newNode; 25 | this.tail = newNode; 26 | } else { 27 | this.tail.next = newNode; 28 | newNode.prev = this.tail; 29 | this.tail = newNode; 30 | } 31 | this.length++; 32 | } 33 | // Insert a new node at beginning of DLL 34 | insertHead(data) { 35 | let newNode = new Node(data); 36 | if(this.head === 0) { 37 | this.head = newNode; 38 | this.tail = newNode; 39 | } else { 40 | this.head.prev = newNode; 41 | newNode.next = this.head; 42 | this.head = newNode; 43 | } 44 | this.length++; 45 | } 46 | // Print the DLL 47 | print() { 48 | let head = this.head; 49 | let dllOutput = []; 50 | while(head!==null) { 51 | dllOutput.push(head.data) 52 | head = head.next 53 | } 54 | console.log(dllOutput.join(' <-> ')) 55 | } 56 | } 57 | 58 | // Creating a new DoublyLinkedList 59 | let dll = new DoublyLinkedList() 60 | 61 | // Inserting Some Nodes 62 | dll.insert(10); // 10 63 | dll.insert(15); // 10 <-> 15 64 | dll.insert(20); // 10 <-> 15 <-> 20 65 | dll.insert(25); // 10 <-> 15 <-> 20 <-> 25 66 | 67 | // Printing DLL after inserting Nodes 68 | dll.print(); 69 | // '10 <-> 15 <-> 20 <-> 25' 70 | 71 | // Inserting a new node at beginning of DLL 72 | dll.insertHead(5); // 5 <-> 10 <-> 15 <-> 20 <-> 25 73 | 74 | // Printing DLL after removing head node 75 | dll.print() 76 | // '5 <-> 10 <-> 15 <-> 20 <-> 25' 77 | ``` 78 | -------------------------------------------------------------------------------- /programs/doubly-linked-list-insert-node-at-given-index.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.prev = null; 7 | this.data = data; 8 | this.next = null; 9 | } 10 | } 11 | 12 | // DoublyLinkedList Class 13 | class DoublyLinkedList { 14 | // Constructor for DLL 15 | constructor() { 16 | this.head = null; 17 | this.tail = null; 18 | this.length = 0; 19 | } 20 | // Insert Node at end of DLL 21 | insert(data) { 22 | let newNode = new Node(data); 23 | if(this.head === null) { 24 | this.head = newNode; 25 | this.tail = newNode; 26 | } else { 27 | this.tail.next = newNode; 28 | newNode.prev = this.tail; 29 | this.tail = newNode; 30 | } 31 | this.length++; 32 | } 33 | // Insert a new node at beginning of DLL 34 | insertHead(data) { 35 | let newNode = new Node(data); 36 | if(this.head === 0) { 37 | this.head = newNode; 38 | this.tail = newNode; 39 | } else { 40 | this.head.prev = newNode; 41 | newNode.next = this.head; 42 | this.head = newNode; 43 | } 44 | this.length++; 45 | } 46 | // Get element by index 47 | get(i) { 48 | if(i<0 || i>this.length) return null 49 | if(i <= this.length/2) { 50 | let count = 0; 51 | let tempHead = this.head; 52 | while(count != i) { 53 | tempHead = tempHead.next; 54 | count++; 55 | } 56 | return tempHead; 57 | } else { 58 | let count = this.length-1; 59 | let tempHead = this.tail; 60 | while(count != i) { 61 | tempHead = tempHead.prev; 62 | count--; 63 | } 64 | return tempHead; 65 | } 66 | } 67 | // Insert Node at given index 68 | insertAt(i, val) { 69 | if(i<0 || i>this.length) { 70 | return null; 71 | } else if(i===0) { 72 | this.insertHead(val); 73 | } else if(i===this.length) { 74 | this.insert(val) 75 | } else { 76 | // We have to insert between before and after 77 | // i.e. before <-> newNode <-> after 78 | let newNode = new Node(val); 79 | let before = this.get(i-1); 80 | let after = before.next; 81 | before.next = newNode; 82 | newNode.prev = before; 83 | newNode.next = after; 84 | after.prev = newNode; 85 | this.length++; 86 | return newNode; 87 | } 88 | } 89 | // Print the DLL 90 | print() { 91 | let head = this.head; 92 | let dllOutput = []; 93 | while(head!==null) { 94 | dllOutput.push(head.data) 95 | head = head.next 96 | } 97 | console.log(dllOutput.join(' <-> ')) 98 | } 99 | } 100 | 101 | 102 | // Creating a new DoublyLinkedList 103 | let dll = new DoublyLinkedList() 104 | 105 | // Inserting Some Nodes 106 | dll.insert(10); // 10 107 | dll.insert(15); // 10 <-> 15 108 | dll.insert(20); // 10 <-> 15 <-> 20 109 | dll.insert(25); // 10 <-> 15 <-> 20 <-> 25 110 | 111 | // Printing DLL after inserting Nodes 112 | dll.print(); 113 | // '10 <-> 15 <-> 20 <-> 25' 114 | 115 | // Suppose we have to add a node between 15 and 20 116 | // i.e. at index 2 117 | dll.insertAt(2, 50); 118 | 119 | // Printing DLL after inserting node at index 2 120 | dll.print(); 121 | // 10 <-> 15 <-> 50 <-> 20 <-> 25 122 | ``` 123 | -------------------------------------------------------------------------------- /programs/doubly-linked-list-remove-head-node.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.prev = null; 7 | this.data = data; 8 | this.next = null; 9 | } 10 | } 11 | 12 | // DoublyLinkedList Class 13 | class DoublyLinkedList { 14 | // Constructor for DLL 15 | constructor() { 16 | this.head = null; 17 | this.tail = null; 18 | this.length = 0; 19 | } 20 | // Insert Node at end of DLL 21 | insert(data) { 22 | let newNode = new Node(data); 23 | if(this.head === null) { 24 | this.head = newNode; 25 | this.tail = newNode; 26 | } else { 27 | this.tail.next = newNode; 28 | newNode.prev = this.tail; 29 | this.tail = newNode; 30 | } 31 | this.length++; 32 | } 33 | // Remove Node from beginning of DLL 34 | removeHead() { 35 | if(!this.head) return undefined; 36 | let tempHead = this.head; 37 | if(this.length === 1) { 38 | this.head = null; 39 | this.tail = null; 40 | } else { 41 | this.head = tempHead.next; 42 | this.head.prev = null; 43 | tempHead.next = null; 44 | } 45 | this.length--; 46 | } 47 | // Print the DLL 48 | print() { 49 | let head = this.head; 50 | let dllOutput = []; 51 | while(head!==null) { 52 | dllOutput.push(head.data) 53 | head = head.next 54 | } 55 | console.log(dllOutput.join(' <-> ')) 56 | } 57 | } 58 | 59 | // Creating a new DoublyLinkedList 60 | let dll = new DoublyLinkedList() 61 | 62 | // Inserting Some Nodes 63 | dll.insert(10); // 10 64 | dll.insert(15); // 10 <-> 15 65 | dll.insert(20); // 10 <-> 15 <-> 20 66 | dll.insert(25); // 10 <-> 15 <-> 20 <-> 25 67 | 68 | // Printing DLL after inserting Nodes 69 | dll.print(); 70 | // '10 <-> 15 <-> 20 <-> 25' 71 | 72 | // Removing head of DLL 73 | dll.removeHead(); // 15 <-> 20 <-> 25 74 | 75 | // Printing DLL after removing head node 76 | dll.print() 77 | // '15 <-> 20 <-> 25' 78 | ``` 79 | -------------------------------------------------------------------------------- /programs/doubly-linked-list-remove-node-at-given-index.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.prev = null; 7 | this.data = data; 8 | this.next = null; 9 | } 10 | } 11 | 12 | // DoublyLinkedList Class 13 | class DoublyLinkedList { 14 | // Constructor for DLL 15 | constructor() { 16 | this.head = null; 17 | this.tail = null; 18 | this.length = 0; 19 | } 20 | // Insert Node at end of DLL 21 | insert(data) { 22 | let newNode = new Node(data); 23 | if(this.head === null) { 24 | this.head = newNode; 25 | this.tail = newNode; 26 | } else { 27 | this.tail.next = newNode; 28 | newNode.prev = this.tail; 29 | this.tail = newNode; 30 | } 31 | this.length++; 32 | } 33 | // Remove Node from beginning of DLL 34 | removeHead() { 35 | if(!this.head) return undefined; 36 | let tempHead = this.head; 37 | if(this.length === 1) { 38 | this.head = null; 39 | this.tail = null; 40 | } else { 41 | this.head = tempHead.next; 42 | this.head.prev = null; 43 | tempHead.next = null; 44 | } 45 | this.length--; 46 | } 47 | // Remove Tail Node from DLL 48 | removeTail() { 49 | if(!this.head) return undefined; 50 | let delNode = this.tail; 51 | if(this.length===1) { 52 | this.head = null; 53 | this.tail = null; 54 | } else { 55 | this.tail = delNode.prev; 56 | this.tail.next = null; 57 | delNode.prev = null; 58 | } 59 | this.length--; 60 | } 61 | // Get element by index 62 | get(i) { 63 | if(i<0 || i>this.length) return null 64 | if(i <= this.length/2) { 65 | let count = 0; 66 | let tempHead = this.head; 67 | while(count != i) { 68 | tempHead = tempHead.next; 69 | count++; 70 | } 71 | return tempHead; 72 | } else { 73 | let count = this.length-1; 74 | let tempHead = this.tail; 75 | while(count != i) { 76 | tempHead = tempHead.prev; 77 | count--; 78 | } 79 | return tempHead; 80 | } 81 | } 82 | // Remove element at given index 83 | removeAt(i) { 84 | if(i<0 || i>=this.length) { 85 | return null 86 | } else if(i === 0) { 87 | this.removeHead() 88 | } else if(i === this.length - 1) { 89 | this.removeTail() 90 | } else { 91 | let removedNode = this.get(i); 92 | removedNode.prev.next = removedNode.next; 93 | removedNode.next.prev = removedNode.prev; 94 | removedNode.prev = null; 95 | removedNode.next = null; 96 | this.length--; 97 | return removedNode; 98 | } 99 | } 100 | // Print the DLL 101 | print() { 102 | let head = this.head; 103 | let dllOutput = []; 104 | while(head!==null) { 105 | dllOutput.push(head.data) 106 | head = head.next 107 | } 108 | console.log(dllOutput.join(' <-> ')) 109 | } 110 | } 111 | 112 | 113 | // Creating a new DoublyLinkedList 114 | let dll = new DoublyLinkedList() 115 | 116 | // Inserting Some Nodes 117 | dll.insert(10); // 10 118 | dll.insert(15); // 10 <-> 15 119 | dll.insert(20); // 10 <-> 15 <-> 20 120 | dll.insert(25); // 10 <-> 15 <-> 20 <-> 25 121 | 122 | // Printing DLL after inserting Nodes 123 | dll.print(); 124 | // '10 <-> 15 <-> 20 <-> 25' 125 | 126 | // Suppose we have to remove node at index 2 127 | dll.removeAt(2); 128 | 129 | // Printing DLL after removing node at index 2 130 | dll.print(); 131 | // 10 <-> 15 <-> 25 132 | ``` 133 | -------------------------------------------------------------------------------- /programs/doubly-linked-list-replace-element-on-index.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.prev = null; 7 | this.data = data; 8 | this.next = null; 9 | } 10 | } 11 | 12 | // DoublyLinkedList Class 13 | class DoublyLinkedList { 14 | // Constructor for DLL 15 | constructor() { 16 | this.head = null; 17 | this.tail = null; 18 | this.length = 0; 19 | } 20 | // Insert Node at end of DLL 21 | insert(data) { 22 | let newNode = new Node(data); 23 | if(this.head === null) { 24 | this.head = newNode; 25 | this.tail = newNode; 26 | } else { 27 | this.tail.next = newNode; 28 | newNode.prev = this.tail; 29 | this.tail = newNode; 30 | } 31 | this.length++; 32 | } 33 | // Get element by index 34 | get(i) { 35 | if(i<0 || i>this.length) return null 36 | if(i <= this.length/2) { 37 | let count = 0; 38 | let tempHead = this.head; 39 | while(count != i) { 40 | tempHead = tempHead.next; 41 | count++; 42 | } 43 | return tempHead; 44 | } else { 45 | let count = this.length-1; 46 | let tempHead = this.tail; 47 | while(count != i) { 48 | tempHead = tempHead.prev; 49 | count--; 50 | } 51 | return tempHead; 52 | } 53 | } 54 | // Set element on index 55 | // (Replacing value of a node) 56 | set(i, val) { 57 | let node = this.get(i); 58 | if(node !== null) { 59 | node.data = val; 60 | return node; 61 | } 62 | return null; 63 | } 64 | // Print the DLL 65 | print() { 66 | let head = this.head; 67 | let dllOutput = []; 68 | while(head!==null) { 69 | dllOutput.push(head.data) 70 | head = head.next 71 | } 72 | console.log(dllOutput.join(' <-> ')) 73 | } 74 | } 75 | 76 | // Creating a new DoublyLinkedList 77 | let dll = new DoublyLinkedList() 78 | 79 | // Inserting Some Nodes 80 | dll.insert(10); // 10 81 | dll.insert(15); // 10 <-> 15 82 | dll.insert(20); // 10 <-> 15 <-> 20 83 | dll.insert(25); // 10 <-> 15 <-> 20 <-> 25 84 | 85 | // Printing DLL after inserting Nodes 86 | dll.print(); // 10 <-> 15 <-> 20 <-> 25 87 | 88 | // Replacing the value on index 2 to 12 89 | dll.set(2, 12) 90 | 91 | // Printing DLL after replacing value on index 2 92 | dll.print(); // 10 <-> 15 <-> 12 <-> 25 93 | ``` 94 | -------------------------------------------------------------------------------- /programs/equilibrium-point-in-array.md: -------------------------------------------------------------------------------- 1 | Given an unsorted array, write a function to find the equilibrium point. 2 | Equilibrium point is the index of array where sum of elements before it is equal to the sum of elements after it. 3 | 4 | ```javascript 5 | function equilibriumPoint(arr) { 6 | for(let i=1; ia+b); 8 | let rightsum = arr.slice(i+1,arr.length).reduce((a,b)=>a+b); 9 | if(leftsum === rightsum) { 10 | return i; 11 | } 12 | } 13 | return -1; 14 | } 15 | 16 | let arr = [5,5,3,4,6]; 17 | console.log(equilibriumPoint(arr)); 18 | // 2 19 | ``` 20 | -------------------------------------------------------------------------------- /programs/factorial-iterative.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function factorial(n) { 3 | let ans = 1; 4 | for(let i=2; i<=n; i++) { 5 | ans *= i; 6 | } 7 | return ans; 8 | } 9 | 10 | console.log(factorial(5)) // 120 11 | ``` -------------------------------------------------------------------------------- /programs/factorial-recursive.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function factorial(n) { 3 | if(n<0) return null 4 | if(n===0) return 1 5 | return n * factorial(n-1) 6 | } 7 | 8 | console.log(factorial(5)) // 120 9 | ``` -------------------------------------------------------------------------------- /programs/fibonacci-series-upto-n.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function fibSeries(n) { 3 | let result = [0, 1]; 4 | for(let i = 2; i < n; i++) { 5 | result.push(result[i-2] + result[i-1]); 6 | } 7 | return result; 8 | 9 | } 10 | 11 | console.log(fibSeries(1)); 12 | // [0, 1] 13 | 14 | console.log(fibSeries(8)); 15 | // [0, 1, 1, 2, 3, 5, 8, 13] 16 | ``` -------------------------------------------------------------------------------- /programs/find-least-occurred-element-in-an-array.md: -------------------------------------------------------------------------------- 1 | Given an unsorted array, write a function to find the least occurring element in that array. 2 | 3 | ```javascript 4 | function getLeastOccurred(arr) { 5 | let map = new Map(); 6 | arr.forEach(e => { 7 | map.set(e, map.get(e)+1||1); 8 | }) 9 | let countArr = [...map] 10 | let leastOccurredElement = countArr.reduce((acc, val) => { 11 | if(val[1] < acc[1]) { 12 | return val; 13 | } else { 14 | return acc; 15 | } 16 | }) 17 | return leastOccurredElement[0]; 18 | } 19 | 20 | let arr = [1,1,2,2,0,0,5,1,2,1,2,2]; 21 | let n = getLeastOccurred(arr); 22 | console.log(n); 23 | ``` 24 | -------------------------------------------------------------------------------- /programs/graph-implementation.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Graph Class 3 | class Graph { 4 | // Constructor for Graph 5 | constructor() { 6 | this.AdjList = new Map(); 7 | } 8 | // Adding a new Vertex(v) 9 | addVertex(v) { 10 | this.AdjList.set(v, []); 11 | } 12 | // Adding an edge from source(src) 13 | // to destination(dest) 14 | addEdge(src, dest) { 15 | this.AdjList.get(src).push(dest); 16 | this.AdjList.get(dest).push(src); 17 | } 18 | // Print the Graph 19 | printGraph() { 20 | let keys = this.AdjList.keys(); 21 | for (let key of keys) { 22 | let values = this.AdjList.get(key); 23 | console.log(`${key} -> ${values.join(' ')}`); 24 | } 25 | } 26 | } 27 | 28 | // Creating a new Graph 29 | let g = new Graph(); 30 | 31 | // Adding vertices to graph 32 | g.addVertex('A'); 33 | g.addVertex('B'); 34 | g.addVertex('C'); 35 | g.addVertex('D'); 36 | 37 | // Adding edges to graph 38 | g.addEdge('A', 'C'); 39 | g.addEdge('C', 'D'); 40 | g.addEdge('C', 'B'); 41 | 42 | // Print the graph 43 | g.printGraph(); 44 | // A -> C 45 | // B -> C 46 | // C -> A D B 47 | // D -> C 48 | ``` 49 | 50 | Following graph is demonstrated in the code above. 51 | Note: This is an undirected Graph. 52 | 53 | ![](https://user-images.githubusercontent.com/43666833/82234116-94225c00-994e-11ea-8d95-b489ee2c5d40.png) 54 | -------------------------------------------------------------------------------- /programs/graph-traversal-breadth-first-search.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Graph Class 3 | class Graph { 4 | // Constructor for Graph 5 | constructor() { 6 | this.AdjList = new Map(); 7 | } 8 | // Adding a new Vertex(v) 9 | addVertex(v) { 10 | this.AdjList.set(v, []); 11 | } 12 | // Adding an edge from source(src) 13 | // to destination(dest) 14 | addEdge(src, dest) { 15 | this.AdjList.get(src).push(dest); 16 | this.AdjList.get(dest).push(src); 17 | } 18 | // Print the Graph 19 | printGraph() { 20 | let keys = this.AdjList.keys(); 21 | for (let key of keys) { 22 | let values = this.AdjList.get(key); 23 | console.log(`${key} -> ${values.join(' ')}`); 24 | } 25 | } 26 | // Breadth First Search 27 | bfs(startNode) { 28 | let q = []; 29 | let visited = new Set(); 30 | q.push(startNode); 31 | visited.add(startNode); 32 | let bfsOutput = []; 33 | while (q.length !== 0) { 34 | let ele = q.shift(); 35 | bfsOutput.push(ele); 36 | this.AdjList.get(ele) 37 | .filter((n) => !visited.has(n)) 38 | .forEach((n) => { 39 | visited.add(n); 40 | q.push(n); 41 | }); 42 | } 43 | console.log('BFS:', bfsOutput.join(' ')); 44 | } 45 | // Get no. of vertices in Graph 46 | getSize() { 47 | return this.AdjList.size; 48 | } 49 | } 50 | 51 | // Creating a new Graph 52 | let g = new Graph(); 53 | 54 | // Adding vertices to graph 55 | g.addVertex('A'); 56 | g.addVertex('B'); 57 | g.addVertex('C'); 58 | g.addVertex('D'); 59 | 60 | // Adding edges to graph 61 | g.addEdge('A', 'C'); 62 | g.addEdge('C', 'D'); 63 | g.addEdge('C', 'B'); 64 | 65 | g.bfs('A'); 66 | // BFS: A C D B 67 | ``` 68 | 69 | Following graph is demonstrated in the code above. 70 | Note: This is an undirected Graph. 71 | 72 | ![](https://user-images.githubusercontent.com/43666833/82234116-94225c00-994e-11ea-8d95-b489ee2c5d40.png) 73 | -------------------------------------------------------------------------------- /programs/graph-traversal-depth-first-search.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Graph Class 3 | class Graph { 4 | // Constructor for Graph 5 | constructor() { 6 | this.AdjList = new Map(); 7 | } 8 | // Adding a new Vertex(v) 9 | addVertex(v) { 10 | this.AdjList.set(v, []); 11 | } 12 | // Adding an edge from source(src) 13 | // to destination(dest) 14 | addEdge(src, dest) { 15 | this.AdjList.get(src).push(dest); 16 | this.AdjList.get(dest).push(src); 17 | } 18 | // Print the Graph 19 | printGraph() { 20 | let keys = this.AdjList.keys(); 21 | for (let key of keys) { 22 | let values = this.AdjList.get(key); 23 | console.log(`${key} -> ${values.join(' ')}`); 24 | } 25 | } 26 | // Depth First Search 27 | dfs(startNode) { 28 | let stack = []; 29 | let visited = new Set(); 30 | stack.push(startNode); 31 | visited.add(startNode); 32 | let dfsOutput = []; 33 | while (stack.length !== 0) { 34 | let ele = stack.pop(); 35 | dfsOutput.push(ele); 36 | this.AdjList.get(ele) 37 | .filter((n) => !visited.has(n)) 38 | .forEach((n) => { 39 | stack.push(n); 40 | visited.add(n); 41 | }); 42 | } 43 | console.log('DFS:', dfsOutput.join(' ')); 44 | } 45 | // Get no. of vertices in Graph 46 | getSize() { 47 | return this.AdjList.size; 48 | } 49 | } 50 | 51 | // Creating a new Graph 52 | let g = new Graph(); 53 | 54 | // Adding vertices to graph 55 | g.addVertex('A'); 56 | g.addVertex('B'); 57 | g.addVertex('C'); 58 | g.addVertex('D'); 59 | 60 | // Adding edges to graph 61 | g.addEdge('A', 'C'); 62 | g.addEdge('C', 'D'); 63 | g.addEdge('C', 'B'); 64 | 65 | g.dfs('A'); 66 | // DFS: A C B D 67 | ``` 68 | 69 | Following graph is demonstrated in the code above. 70 | Note: This is an undirected Graph. 71 | 72 | ![](https://user-images.githubusercontent.com/43666833/82234116-94225c00-994e-11ea-8d95-b489ee2c5d40.png) 73 | -------------------------------------------------------------------------------- /programs/greatest-common-divisor.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function getGCD(a, b) { 3 | if(!b) { 4 | return a; 5 | } 6 | return getGCD(b, a%b); 7 | } 8 | 9 | console.log(getGCD(12,16)) // 4 10 | console.log(getGCD(21, 35)) // 7 11 | ``` -------------------------------------------------------------------------------- /programs/insertion-sort.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function insertionSort(arr) { 3 | for (let i = 1; i < arr.length; i++) { 4 | let key = arr[i]; 5 | let j = i - 1; 6 | while (j >= 0 && arr[j] > key) { 7 | arr[j + 1] = arr[j]; 8 | j = j - 1; 9 | } 10 | arr[j + 1] = key; 11 | } 12 | return arr; 13 | } 14 | 15 | console.log(insertionSort([2, 4, 1, 3, 5])); // [1,2,3,4,5] 16 | ``` 17 | -------------------------------------------------------------------------------- /programs/knapsack-problem-dynamic-programming.md: -------------------------------------------------------------------------------- 1 | ### Given a set of items, each with a weight and a value, determine the number of each item to include in a collection so that the total weight is less than or equal to a given limit(w) and the total value is as large as possible. 2 | 3 | ```javascript 4 | function knapsack(val, weight, n, w) { 5 | var mem = []; 6 | // Creating a matrix of size (n+1) X (w+1) 7 | // and initializing each element with 0 initially. 8 | for (let i = 0; i < n + 1; i++) { 9 | let intermediate_array = new Array(w+1).fill(0); 10 | mem.push(intermediate_array); 11 | } 12 | // Storing maximum value for ith item 13 | // that has j weight in mem[i][j]. 14 | for (let i = 1; i < n + 1; i++) { 15 | for (let j = 1; j < w + 1; j++) { 16 | // Making a choice on whether or not to include an item in the knapsack. 17 | // When we decide to choose the item, the capacity of the knapsack decreases. 18 | // On the contrary, if we do not choose it, the capacity remains the same. Selection is done to maximise profit. 19 | if (weight[i - 1] <= j) { 20 | mem[i][j] = Math.max( 21 | val[i - 1] + mem[i - 1][j - weight[i - 1]], 22 | mem[i - 1][j] 23 | ); 24 | } else { 25 | mem[i][j] = mem[i - 1][j]; 26 | } 27 | } 28 | } 29 | // As a result mem[n][w] stores the maximum profit. 30 | return mem[n][w]; 31 | } 32 | 33 | let val = [4, 6, 3, 9, 2]; 34 | let weight = [2, 12, 10, 5, 6]; 35 | let n = val.length; 36 | let w = 15; 37 | 38 | console.log(knapsack(val, weight, n, w)); 39 | // 15 40 | ``` 41 | -------------------------------------------------------------------------------- /programs/knapsack-problem-using-recursion-and-memoization.md: -------------------------------------------------------------------------------- 1 | ### Given a set of items, each with a weight and a value, determine the number of each item to include in a collection so that the total weight is less than or equal to a given limit(w) and the total value is as large as possible. 2 | 3 | ```javascript 4 | function knapsack(val, weight, n, w, mem) { 5 | let result; 6 | // base condition : 7 | if (n == 0 || w == 0) { 8 | return 0; 9 | } 10 | if (mem[n][w] != -1) { 11 | // return value if already stored 12 | // in the look-up table 13 | return mem[n][w]; 14 | } else if (weight[n - 1] <= w) { 15 | // store the maximum between the two results, 16 | // when the item is included in the knapsack 17 | // and when it is excluded, in the result variable. 18 | result = Math.max( 19 | val[n - 1] + knapsack(val, weight, n - 1, w - weight[n - 1], mem), 20 | knapsack(val, weight, n - 1, w, mem) 21 | ); 22 | } // if the weight of item in the weight array > capacity of knapsack, it cannot be included. 23 | else { 24 | result = knapsack(val, weight, n - 1, w, mem); 25 | } 26 | // store the result in the look-table, mem, before returning result. 27 | mem[n][w] = result; 28 | return result; 29 | } 30 | 31 | let val = [4, 6, 3, 9, 2]; 32 | let weight = [2, 12, 10, 5, 6]; 33 | let n = val.length; 34 | let w = 15; 35 | let mem = []; 36 | 37 | for (let i = 0; i < n + 1; i++) { 38 | let intermediate_array = new Array(w+1).fill(-1); 39 | mem.push(intermediate_array); 40 | } 41 | 42 | console.log(knapsack(val, weight, n, w, mem)); 43 | // Output: 44 | // 15 45 | ``` 46 | -------------------------------------------------------------------------------- /programs/linear-search.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function linearSearch(arr, element) { 3 | for(let i=0; i4 58 | ll.addNode(6); // ll: 2->4->6 59 | ll.addNode(8); // ll: 2->4->6->8 60 | 61 | // Printing Linked List 62 | ll.printLinkedList(); // 2 4 6 8 63 | 64 | ll.deleteNode(6); // ll: 2->4->8 65 | 66 | // Printing Linked List Again 67 | ll.printLinkedList(); // 2 4 8 68 | ``` 69 | -------------------------------------------------------------------------------- /programs/longest-common-subsequence.md: -------------------------------------------------------------------------------- 1 | **Problem** 2 | Given two sequences, find the length of longest subsequence present in both of them. 3 | 4 | ```javascript 5 | function lcs(s1, s2, x, y) { 6 | if(x==0 || y==0) { 7 | return 0; 8 | } else if(s1.charAt(x-1) == s2.charAt(y-1)) { 9 | return 1 + lcs(s1, s2, x-1, y-1) 10 | } else { 11 | return Math.max(lcs(s1,s2,x-1,y), lcs(s1,s2,x,y-1)) 12 | } 13 | } 14 | 15 | let s1 = 'axcdz' 16 | let s2 = 'ajcd' 17 | let x = s1.length 18 | let y = s2.length 19 | 20 | console.log(lcs(s1, s2, x, y)) 21 | // 3 22 | ``` 23 | -------------------------------------------------------------------------------- /programs/max-binary-heap.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Max Binary Heap Class 3 | class MaxBinaryHeap { 4 | // Constructor for MaxBinaryHeap 5 | constructor() { 6 | this.values = []; 7 | } 8 | // Inserting data in heap 9 | insert(data) { 10 | this.values.push(data); 11 | // Building Max Heap 12 | this.buildMaxHeap(); 13 | } 14 | // Function to build MaxBinaryHeap 15 | buildMaxHeap() { 16 | // Initialising i and e as inserted element's 17 | // index and value respectively. 18 | let i = this.values.length -1; 19 | let e = this.values[i]; 20 | while(i>0) { 21 | // Getting parent index and value of 22 | // element at index i 23 | let parentIndex = Math.floor((i-1)/2); 24 | let parent = this.values[parentIndex]; 25 | // If element e is less than or equal 26 | // to parent, break out of loop. 27 | if(e <= parent) { 28 | break; 29 | } 30 | // If element e is greater than 31 | // parent, swap them. 32 | this.values[i] = parent; 33 | this.values[parentIndex] = e; 34 | // Change index i to parent's index 35 | i = parentIndex 36 | } 37 | } 38 | } 39 | 40 | // Create a new Binary Heap 41 | let heap = new MaxBinaryHeap(); 42 | 43 | heap.insert(12) 44 | heap.insert(10) 45 | heap.insert(15) 46 | heap.insert(11) 47 | heap.insert(20) 48 | 49 | console.log(heap.values) 50 | // [ 20, 15, 12, 10, 11 ] 51 | ``` 52 | -------------------------------------------------------------------------------- /programs/maximum-occuring-character.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function maxChar(str) { 3 | let chars = {}; 4 | for(let char of str) { 5 | chars[char] = chars[char]+1 || 1; 6 | } 7 | let max=0, maxChars=''; 8 | for(let char in chars) { 9 | if(chars[char]>max) { 10 | max = chars[char]; 11 | maxChars = char 12 | } 13 | } 14 | return maxChars; 15 | } 16 | 17 | console.log(maxChar('Hello')) // 'l' 18 | console.log(maxChar('abbccd')) // 'b' 19 | ``` -------------------------------------------------------------------------------- /programs/maximum-subarray-sum.md: -------------------------------------------------------------------------------- 1 | This function calculates maximum sum of n consecutive elements in an array. 2 | 3 | ```javascript 4 | function maxSubarray(arr, n) { 5 | let tempsum = 0; 6 | let maxsum = 0; 7 | for(let i=0; i a-b); 42 | // Changing each node's data 43 | // as per the sorted array 44 | current = this.head; 45 | let c = 0; 46 | while(current !== null) { 47 | current.data = arr[c]; 48 | c++; 49 | current = current.next; 50 | } 51 | // Returning the linked list 52 | return this; 53 | } 54 | // Print a LinkedList 55 | print() { 56 | let head = this.head; 57 | let output = []; 58 | while (head !== null) { 59 | output.push(head.data); 60 | head = head.next; 61 | } 62 | console.log(output.join('->')); 63 | } 64 | } 65 | 66 | // Merge two or more LinkedLists 67 | // in sorted order 68 | function sortedMerge(...args) { 69 | // Creating an empty array 70 | let tempArr = [] 71 | // Pushing data of each node of 72 | // each linked list to tempArr 73 | for(let arg of args) { 74 | let current = arg.head; 75 | while(current !== null) { 76 | tempArr.push(current.data) 77 | current = current.next; 78 | } 79 | } 80 | // Sorting tempArr 81 | tempArr.sort((a,b) => a-b) 82 | // Creating a new LinkedList 83 | let newL = new LinkedList(); 84 | // For each element in tempArr 85 | // Inserting into LinkedList (newL) 86 | for(let e of tempArr) { 87 | newL.insert(e); 88 | } 89 | // Returning New LinkedList (newL) 90 | return newL; 91 | } 92 | 93 | // Creating LinkedList 1 (l1) 94 | let l1 = new LinkedList(); 95 | l1.insert(10); 96 | l1.insert(30); 97 | l1.insert(8); 98 | 99 | // Printing LinkedList 1 (l1) 100 | l1.print() 101 | // '10->30->8' 102 | 103 | // Creating LinkedList 2 (l2) 104 | let l2 = new LinkedList(); 105 | l2.insert(13); 106 | l2.insert(5); 107 | l2.insert(24); 108 | 109 | // Printing LinkedList 2 (l2) 110 | l2.print() 111 | // '13->5->24' 112 | 113 | // Merging both linkedlists in 114 | // sorted order 115 | let sl = sortedMerge(l1,l2) 116 | 117 | // Printing merged linkedlist 118 | sl.print() 119 | // '5->8->10->13->24->30' 120 | ``` 121 | -------------------------------------------------------------------------------- /programs/middle-element-in-linked-list.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for new Node 5 | constructor(data) { 6 | this.next = null; 7 | this.data = data; 8 | } 9 | } 10 | 11 | // Linked List Class 12 | class LinkedList { 13 | // Constructor for Linked List 14 | constructor() { 15 | this.headNode = null; 16 | this.lastNode = null; 17 | } 18 | // Adding New Node to Linked List 19 | addNode(data) { 20 | if (this.lastNode === null) { 21 | this.headNode = new Node(data); 22 | this.lastNode = this.headNode; 23 | } else { 24 | this.lastNode.next = new Node(data); 25 | this.lastNode = this.lastNode.next; 26 | } 27 | } 28 | // Get Middle Element 29 | getMiddleElement() { 30 | let size = this.getSize(); 31 | let mid = Math.floor(size/2) 32 | let head = this.headNode; 33 | for(let i=0; i4 69 | ll.addNode(6); // ll: 2->4->6 70 | ll.addNode(8); // ll: 2->4->6->8 71 | ll.addNode(10) // ll: 2->4->6->8->10 72 | 73 | // Printing Linked List 74 | ll.printLinkedList(); // 2 4 6 8 10 75 | 76 | // Get Middle Element of Linked List 77 | ll.getMiddleElement(); // 6 78 | ``` -------------------------------------------------------------------------------- /programs/minimum-difference-between-two-elements-in-an-array.md: -------------------------------------------------------------------------------- 1 | Find the minimum difference between any pair in a given unsorted array. 2 | 3 | ```javascript 4 | function getMinDifference(arr) { 5 | arr = arr.sort((a,b) => a-b); 6 | let diff = Infinity; 7 | for(let i=0; i { 5 | let count = 0; 6 | while (num) { 7 | if (num & 1) { 8 | count += 1; 9 | } 10 | num = num >> 1; 11 | } 12 | return count; 13 | }; 14 | console.log(noOfOnes(2)); // 1 15 | console.log(noOfOnes(3)); // 2 16 | console.log(noOfOnes(7)); // 3 17 | console.log(noOfOnes(8)); // 1 18 | 19 | // Since: 20 | // 2 -> 10 21 | // 3 -> 11 22 | // 7 -> 111 23 | // 8 -> 1000 24 | ``` 25 | -------------------------------------------------------------------------------- /programs/nth-fibonacci-number.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function nthFib(n) { 3 | if(n < 2) { 4 | return n 5 | } 6 | return nthFib(n-1) + nthFib(n-2) 7 | } 8 | 9 | let sixthFibonacci = nthFib(6) 10 | let tenthFibonacci = nthFib(10) 11 | 12 | console.log(sixthFibonacci) // 8 13 | console.log(tenthFibonacci) // 55 14 | ``` -------------------------------------------------------------------------------- /programs/palindrome-check.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | function isPalindrome(str) { 3 | let revstr = str.split('').reverse().join(''); 4 | let result = (str===revstr) ? true : false; 5 | return result 6 | } 7 | 8 | console.log(isPalindrome('mom')) // true 9 | console.log(isPalindrome('bro')) // false 10 | ``` -------------------------------------------------------------------------------- /programs/perfect-number.md: -------------------------------------------------------------------------------- 1 | **Note:** Perfect Numbers are those numbers whose sum of its factors(excluding the number itself) is equal to the number. Eg: 6(1+2+3=6) is a perfect Number. 2 | 3 | 4 | ```javascript 5 | function checkPerfect(n){ 6 | let s=0; 7 | for(let i=1; i e*e); 6 | arr.sort((a,b) => a-b); 7 | for(let i=arr.length-1; i>1; i--) { 8 | let j = 0; 9 | let k = i-1; 10 | while(j arr[j]) { 7 | min = j; 8 | } 9 | } 10 | if (min !== i) { 11 | let tmp = arr[i]; 12 | arr[i] = arr[min]; 13 | arr[min] = tmp; 14 | } 15 | } 16 | return arr; 17 | } 18 | 19 | console.log(selectionSort([2, 4, 1, 3, 5])); // [1,2,3,4,5] 20 | ``` 21 | -------------------------------------------------------------------------------- /programs/singly-linked-list-check-loop.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.data = data; 7 | this.next = null; 8 | } 9 | } 10 | 11 | // Linked List Class 12 | class LinkedList { 13 | // Constructor for Linked List 14 | constructor() { 15 | this.head = null; 16 | this.tail = null; 17 | } 18 | // Insert node into Linked List 19 | insert(data) { 20 | if(this.tail === null) { 21 | this.head = new Node(data); 22 | this.tail = this.head; 23 | } else { 24 | this.tail.next = new Node(data); 25 | this.tail = this.tail.next; 26 | } 27 | } 28 | // Checking if linked list 29 | // has a loop 30 | checkLoop() { 31 | let s = new Set(); 32 | let current = this.head; 33 | while(current !== null) { 34 | if(s.has(current)) { 35 | return true; 36 | } 37 | s.add(current); 38 | current = current.next; 39 | } 40 | return false; 41 | } 42 | } 43 | 44 | // Creating a new Linked List 45 | let ll = new LinkedList(); 46 | 47 | // Inserting Nodes 48 | ll.insert(1); 49 | ll.insert(2); 50 | ll.insert(3); 51 | ll.insert(4); 52 | 53 | // Check Loop before 54 | // creating a loop 55 | ll.checkLoop(); 56 | // false 57 | 58 | // Creating a loop 59 | ll.head.next.next.next.next = ll.head.next 60 | 61 | // Check Loop after 62 | // creating a loop 63 | ll.checkLoop(); 64 | // true 65 | ``` 66 | 67 | Following loop is created in the above code. 68 | 69 | ![](https://user-images.githubusercontent.com/43666833/82942161-2a8cf800-9fb5-11ea-99b4-7650ba660b2a.png) -------------------------------------------------------------------------------- /programs/singly-linked-list-check-palindrome.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.data = data; 7 | this.next = null; 8 | } 9 | } 10 | 11 | // LinkedList Class 12 | class LinkedList { 13 | // Constructor for LinkedList 14 | constructor() { 15 | this.head = null; 16 | this.tail = null; 17 | this.length = 0; 18 | } 19 | // Inserting data in LinkedList 20 | insert(data) { 21 | if(this.tail===null) { 22 | this.head = new Node(data); 23 | this.tail = this.head; 24 | this.length++; 25 | } else { 26 | this.tail.next = new Node(data); 27 | this.tail = this.tail.next; 28 | this.length++; 29 | } 30 | } 31 | // Print whole LinkedList 32 | print() { 33 | let current = this.head; 34 | let output = []; 35 | while(current !== null) { 36 | output.push(current.data); 37 | current = current.next; 38 | } 39 | return output.join('->'); 40 | } 41 | // Check if LinkedList is palindrome 42 | isPalindrome() { 43 | let currentLL = this.print(); 44 | let revCurrentLL = currentLL 45 | .split('->') 46 | .reverse() 47 | .join('->'); 48 | if(currentLL === revCurrentLL) { 49 | return true; 50 | } 51 | return false; 52 | } 53 | } 54 | 55 | // Creating a new LinkedList 56 | let ll = new LinkedList(); 57 | 58 | // Inserting elements 59 | ll.insert(1); 60 | ll.insert(2); 61 | ll.insert(2); 62 | ll.insert(1); 63 | 64 | // Printing LinkedList 65 | console.log(ll.print()) 66 | // '1->2->2->1' 67 | 68 | console.log(ll.isPalindrome()); 69 | // true 70 | 71 | // Now testing for non- 72 | // palindromic LinkedList 73 | ll.insert(5); 74 | console.log(ll.print()); 75 | // '1->2->2->1->5' 76 | 77 | console.log(ll.isPalindrome()) 78 | // false 79 | ``` 80 | -------------------------------------------------------------------------------- /programs/singly-linked-list-print-nth-node-from-end.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.data = data; 7 | this.next = null; 8 | } 9 | } 10 | 11 | // LinkedList Class 12 | class LinkedList { 13 | // Constructor for LinkedList 14 | constructor() { 15 | this.head = null; 16 | this.tail = null; 17 | this.length = 0; 18 | } 19 | // Inserting data in LinkedList 20 | insert(data) { 21 | if(this.tail===null) { 22 | this.head = new Node(data); 23 | this.tail = this.head; 24 | this.length++; 25 | } else { 26 | this.tail.next = new Node(data); 27 | this.tail = this.tail.next; 28 | this.length++; 29 | } 30 | } 31 | // Print whole LinkedList 32 | print() { 33 | let current = this.head; 34 | let output = []; 35 | while(current !== null) { 36 | output.push(current.data); 37 | current = current.next; 38 | } 39 | console.log(output.join('->')) 40 | } 41 | // Print nth node from end of 42 | // Linked List 43 | printNthNodeFromLast(n) { 44 | if(n>this.length || n<0) { 45 | return null; 46 | } 47 | let current = this.head; 48 | let count = this.length; 49 | while(count!==n) { 50 | count--; 51 | current = current.next; 52 | } 53 | console.log(current.data); 54 | } 55 | } 56 | 57 | // Creating a new LinkedList 58 | let ll = new LinkedList(); 59 | 60 | // Inserting elements 61 | ll.insert(10); 62 | ll.insert(20); 63 | ll.insert(8); 64 | ll.insert(13); 65 | 66 | // Printing LinkedList 67 | ll.print(); 68 | // '10->20->8->13' 69 | 70 | // Printing nth node from end 71 | // of LinkedList 72 | ll.printNthNodeFromLast(3) 73 | // 20 74 | ``` 75 | -------------------------------------------------------------------------------- /programs/singly-linked-list-print-nth-node.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.data = data; 7 | this.next = null; 8 | } 9 | } 10 | 11 | // LinkedList Class 12 | class LinkedList { 13 | // Constructor for LinkedList 14 | constructor() { 15 | this.head = null; 16 | this.tail = null; 17 | this.length = 0; 18 | } 19 | // Inserting data in LinkedList 20 | insert(data) { 21 | if(this.tail===null) { 22 | this.head = new Node(data); 23 | this.tail = this.head; 24 | this.length++; 25 | } else { 26 | this.tail.next = new Node(data); 27 | this.tail = this.tail.next; 28 | this.length++; 29 | } 30 | } 31 | // Print whole LinkedList 32 | print() { 33 | let current = this.head; 34 | let output = []; 35 | while(current !== null) { 36 | output.push(current.data); 37 | current = current.next; 38 | } 39 | console.log(output.join('->')) 40 | } 41 | // Print nth node of LinkedList 42 | printNthNode(n) { 43 | if(n>this.length || n<0) { 44 | return null; 45 | } 46 | let current = this.head; 47 | let count = 1; 48 | while(count!==n) { 49 | count++; 50 | current = current.next; 51 | } 52 | console.log(current.data); 53 | } 54 | } 55 | 56 | // Creating a new LinkedList 57 | let ll = new LinkedList(); 58 | 59 | // Inserting elements 60 | ll.insert(10); 61 | ll.insert(20); 62 | ll.insert(8); 63 | ll.insert(13); 64 | 65 | // Printing LinkedList 66 | ll.print(); 67 | // '10->20->8->13' 68 | 69 | // Printing nth node 70 | // of LinkedList 71 | ll.printNthNode(3) 72 | // 8 73 | ``` 74 | -------------------------------------------------------------------------------- /programs/singly-linked-list-reverse-iterative.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | // Node Class 3 | class Node { 4 | // Constructor for Node 5 | constructor(data) { 6 | this.data = data; 7 | this.next = null; 8 | } 9 | } 10 | 11 | // Linked List Class 12 | class LinkedList { 13 | // Constructor for Linked List 14 | constructor() { 15 | this.head = null; 16 | this.tail = null; 17 | } 18 | // Insert node into Linked List 19 | insert(data) { 20 | if(this.tail === null) { 21 | this.head = new Node(data); 22 | this.tail = this.head; 23 | } else { 24 | this.tail.next = new Node(data); 25 | this.tail = this.tail.next; 26 | } 27 | } 28 | // Reverse Linked List 29 | reverse() { 30 | this.tail = this.head; 31 | let prev = null; 32 | let current = this.head; 33 | let next; 34 | while(current !== null) { 35 | next = current.next; 36 | current.next = prev; 37 | prev = current; 38 | current = next; 39 | } 40 | this.head = prev; 41 | } 42 | // Print Linked List 43 | print() { 44 | let current = this.head; 45 | let output = []; 46 | while(current !== null) { 47 | output.push(current.data); 48 | current = current.next; 49 | } 50 | console.log(output.join('->')); 51 | } 52 | } 53 | 54 | // Creating a new Linked List 55 | let ll = new LinkedList(); 56 | 57 | // Inserting Nodes 58 | ll.insert(1); 59 | ll.insert(2); 60 | ll.insert(3); 61 | ll.insert(4); 62 | 63 | // Print linked list 64 | ll.print(); 65 | // 1->2->3->4 66 | 67 | // Reverse the linked list 68 | ll.reverse(); 69 | 70 | // Print linked list 71 | // after reversing 72 | ll.print(); 73 | // 4->3->2->1 74 | ``` 75 | -------------------------------------------------------------------------------- /programs/stack-implementation.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | let stack = [] 3 | 4 | console.log("Initially Stack: ", stack) 5 | // 'Initially Stack: ' [] 6 | 7 | // Push 8 | stack.push(1) 9 | stack.push(2) 10 | stack.push(3) 11 | 12 | // After Push 13 | console.log("After Push: ", stack) 14 | // 'After Push: ' [ 1, 2, 3 ] 15 | 16 | // Pop 17 | let poppedValue = stack.pop() 18 | console.log("Popped Value: ", poppedValue) 19 | // 'Popped Value: ' 3 20 | 21 | // After Pop 22 | console.log("After Pop: ", stack) 23 | // 'After Pop: ' [ 1, 2 ] 24 | 25 | // Peek 26 | Array.prototype.peek = function() { 27 | return this[this.length-1] 28 | } 29 | console.log("Peek: ", stack.peek()) 30 | // 'Peek: ' 2 31 | 32 | // After Peek 33 | console.log("After Peek: ", stack) 34 | // 'After Peek: ' [ 1, 2 ] 35 | 36 | ``` -------------------------------------------------------------------------------- /public/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | h1, 8 | h2, 9 | h3, 10 | h4, 11 | h5, 12 | h6 { 13 | margin: 0; 14 | padding: 0; 15 | } 16 | 17 | .content-area { 18 | margin-top: 20px; 19 | } 20 | 21 | .programs-div h3, 22 | .questions-div h3 { 23 | margin-left: 10px; 24 | } -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akulsr0/learn-js/HEAD/public/logo.png -------------------------------------------------------------------------------- /questions/accidental-global-variable.md: -------------------------------------------------------------------------------- 1 | Why in the following code example a is not defined but b is 2 | 3 | ```javascript 4 | function fun() { 5 | let a=b=10; 6 | } 7 | 8 | fun() 9 | 10 | console.log("a: ", a) 11 | // ReferenceError: a is not defined 12 | 13 | console.log("b: ", b) 14 | // b: 10 15 | 16 | ``` 17 | 18 | **Answer** 19 | 20 | This statement inside function fun() 21 | 22 | ```javascript 23 | let a=b=10; 24 | ``` 25 | 26 | can be break down into two statements, i.e. 27 | 28 | ```javascript 29 | let b = 10 // global scope 30 | let a = b // fun() scope 31 | ``` 32 | 33 | Hence, a is not available in global scope while b is available. 34 | 35 | That's why on printing a and b in global scope b is printed but a says that it is not defined. 36 | 37 | **Solution** 38 | 39 | To prevent your code from creating global variables accidentally, you can use strict mode. 40 | 41 | Add following line at top of your code - 42 | 43 | ```javascript 44 | 'use strict' 45 | ``` -------------------------------------------------------------------------------- /questions/how-does-the-bind-method-work.md: -------------------------------------------------------------------------------- 1 | ### Polyfill for Function.prototype.bind() method 2 | 3 | .bind() method binds the this keyword of a function with an object(passed as the first argument) and returns it. This function can be invoked later. Rest of the arguments can be passed separated by a comma. 4 | 5 | ```javascript 6 | const person = { 7 | firstname: 'John', 8 | lastname: 'Doe' 9 | }; 10 | 11 | function printInfo(age, country) { 12 | console.log( 13 | `Hi, my name is ${this.firstname} ${this.lastname} and I am ${age} years old. I live in ${country}` 14 | ); 15 | } 16 | 17 | var print = printInfo.bind(person, 100); // Original bind method 18 | print('xyz'); 19 | // Hi, my name is John Doe and I am 100 years old. I live in xyz 20 | 21 | // Our implementation of bind method : 22 | Function.prototype.myBind = function(...args) { 23 | let that = this; 24 | let val = args.slice(1); 25 | return function(...args2) { 26 | that.apply(args[0], [...val, ...args2]); 27 | }; 28 | }; 29 | 30 | var myPrint = printInfo.myBind(person, 100); 31 | myPrint('xyz'); 32 | // Hi, my name is John Doe and I am 100 years old. I live in xyz 33 | ``` 34 | -------------------------------------------------------------------------------- /questions/how-does-the-filter-method-work.md: -------------------------------------------------------------------------------- 1 | ## Polyfill for Array.prototype.filter() 2 | 3 | The filter method returns a new array which consists of the elements that satisfy the condition thrown by the callback function over each element the given array. 4 | 5 | This method does not mutate the original array. 6 | 7 | ```javascript 8 | let arr = [1, 4, 5, 9, 3, 6, 8, 10]; 9 | 10 | // The function below returns a filtered array of only the even numbers. 11 | Array.prototype.myFilter = function(callback) { 12 | let newArray = []; 13 | let passedArray = this; 14 | passedArray.forEach(element => { 15 | if (callback(element)) { 16 | newArray.push(element); 17 | } 18 | }); 19 | return newArray; 20 | }; 21 | 22 | console.log(arr.myFilter(x => x % 2 == 0)); 23 | 24 | // Output 25 | // [4, 6, 8, 10] 26 | ``` 27 | -------------------------------------------------------------------------------- /questions/how-does-the-map-method-work.md: -------------------------------------------------------------------------------- 1 | ## Polyfill for Array.prototype.map() function 2 | 3 | .map() method performs a function(callback) over all the elements of the array and returns a new array ie. it does not mutate the original array. 4 | 5 | ```javascript 6 | let arr = [6, 9, 3, 7, 12]; 7 | 8 | Array.prototype.myMap = function(callback) { 9 | let newArray = []; 10 | let arr = this; 11 | for (let i = 0; i < arr.length; i++) { 12 | newArray.push(callback(arr[i])); 13 | } 14 | return newArray; 15 | }; 16 | 17 | console.log(arr.myMap(x => 2 * x)); 18 | 19 | // Output: 20 | // [12, 18, 6, 14, 24] 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /questions/how-to-encode-string-in-javascript.md: -------------------------------------------------------------------------------- 1 | We can use built-in **encodeURI()** function to encode a string. 2 | 3 | Here's how: 4 | 5 | ```javascript 6 | let someString = `find value of √4`; 7 | 8 | console.log("Encoded Multiline String: ", encodeURI(someString)) 9 | // 'Encoded Multiline String: ' 'find%20value%20of%20%E2%88%9A4' 10 | 11 | console.log("Encoded Emoji: ", encodeURI("🙂")) 12 | // 'Encoded Emoji: ' '%F0%9F%99%82' 13 | ``` -------------------------------------------------------------------------------- /questions/octal-literals-in-javascript.md: -------------------------------------------------------------------------------- 1 | ### Octal Literals 2 | 3 | Octal literals are a way to write octal numbers in javascript. 4 | 5 | ```javascript 6 | // Parsed as Decimal number 7 | console.log(08) // 8 8 | console.log(09) // 9 9 | 10 | // Parsed as Octal Numbers (in non-strict mode) 11 | console.log(010) // 8 12 | console.log(011) // 9 13 | 14 | // Parsed as Octal Numbers (in strict mode) 15 | 16 | console.log(0o10); // 8 17 | console.log(0o11); // 9 18 | ``` 19 | 20 | Similarly there are binary and hexadecimal literals 21 | 22 | ```javascript 23 | // Parsed as Binary Number 24 | console.log(0b101); // 5 25 | 26 | // Parsed as Hexadecimal Number 27 | console.log(0x1a); // 26 28 | ``` 29 | -------------------------------------------------------------------------------- /questions/what-are-closures.md: -------------------------------------------------------------------------------- 1 | When a function remembers it's lexical scope even when it is executed out of its lexical scope, closure persists. 2 | 3 | ```javascript 4 | const outerFunction = (...args) => { 5 | let counter = 0; 6 | return () => { 7 | console.log(args[0]); 8 | console.log(counter++); 9 | }; 10 | }; 11 | 12 | const innerFunction = outerFunction('Incrementing counter'); 13 | innerFunction(); 14 | innerFunction(); 15 | innerFunction(); 16 | innerFunction(); 17 | 18 | // Output: 19 | // Incrementing counter 20 | // 0 21 | // Incrementing counter 22 | // 1 23 | // Incrementing counter 24 | // 2 25 | // Incrementing counter 26 | // 3 27 | 28 | ``` 29 | -------------------------------------------------------------------------------- /questions/what-are-new-features-in-es2020.md: -------------------------------------------------------------------------------- 1 | ### 1. Optional chaining => symbol => **?.** 2 | 3 | This is use to access long chain properties and methods of an object. 4 | 5 | For example: 6 | 7 | ```javascript 8 | const Obj = { 9 | db: { 10 | user: { 11 | name: undefined, 12 | sayHii(name){ 13 | console.log(`Hii ${name}`); 14 | } 15 | }, 16 | }, 17 | }; 18 | 19 | console.log(Obj?.db?.user?.name || "username not found"); 20 | // username not found 21 | // Because in above obj name is undefined 22 | 23 | // We can also call methods of the object by ?.() 24 | console.log(Obj?.db?.user?.sayHii?.("learn js")); 25 | // Hii learn js 26 | 27 | // we can also do dynamic properties access by ?.[] 28 | const hiiFunc = "sayHii"; 29 | console.log(Obj?.db?.user?.[hiiFunc]?.("learn js")); 30 | // Hii learn js 31 | ``` 32 | 33 | ### 2. Nullish coalescing => symbol => ?? 34 | 35 | New short-circuiting operator to handle only nullish values (undefined or null) 36 | 37 | For Example: 38 | 39 | ```javascript 40 | console.log(null ?? []); 41 | // [] 42 | console.log(undefined ?? []); 43 | // [] 44 | console.log(false ?? "learn js"); 45 | // false 46 | // This is strictly equal to the (null or undefined only) not falsy value 47 | console.log(0 ?? 1); 48 | // 0 49 | console.log('' ?? "learn js"); 50 | // '' 51 | ``` 52 | 53 | ### 3. Object.fromEntries() 54 | 55 | This will convert [['x',2], ['y',4]] into { x: 2, y: 4 } 56 | 57 | For Example: 58 | 59 | ```javascript 60 | // First we need to understand Object.entries() 61 | const obj = {x:2,u:4}; 62 | const entries = Object.entries(obj); 63 | console.log(entries); 64 | //[['x',2],['u',4]] 65 | 66 | //Now if want again that object we can do 67 | console.log(Object.fromEntries(entries)); 68 | //{x:2,u:4} 69 | ``` 70 | 71 | ### 4. Array.prototype.flat() 72 | 73 | Flat returns a flattened version of an given array 74 | Like [1,2,[3]] into [1,2,3] 75 | 76 | For Example: 77 | 78 | ```javascript 79 | 80 | const nestedArray = [1,[2, [3]]]; 81 | console.log(nestedArray.flat()); 82 | // [1,2,[3]] 83 | 84 | // Here flat flatten the above array into one level deep 85 | // We can also pass any number like 1,2,3 to recursively flatten up to that depth 86 | // Or If you wanna to flatten all nested array then pass (Infinity) 87 | 88 | console.log(nestedArray.flat(1)); 89 | // [1,2,[3]] // 1 is default depth 90 | console.log(nestedArray.flat(Infinity)); 91 | // [1,2,3] will flatten all nested array 92 | ``` 93 | 94 | ### 5. Array.prototype.flatMap() 95 | 96 | This is use to create duplicate elements of an array 97 | 98 | For Example: 99 | 100 | ```javascript 101 | console.log([2,3,4].map((x)=>[x,x]).flat()); 102 | //[2,2,3,3,4,4] 103 | 104 | //Now we can achieve this simply by flatMap() 105 | console.log([1,2,3].flatMap((x)=>[x,x])); 106 | //[1,1,2,2,3,3] 107 | ``` 108 | 109 | ### 6. Dynamic import() 110 | 111 | Now by using Dynamic import() we can import module on-demand (or conditionally). 112 | Dynamic import introduces a new function-like form of import. 113 | Now no need to import module at top of the file. 114 | 115 | For Example: 116 | ```javascript 117 | // Suppose ./main.js file have two function exported 118 | // main.js 119 | export default ()=>{ 120 | console.log("This is default function"); 121 | }; 122 | 123 | export const learnJs = ()=>{ 124 | console.log("Learn Js"); 125 | } 126 | 127 | // app.js 128 | // Now we can import it anywhere in the file by using function Dynamic import 129 | (async()=>{ 130 | const module = await import('./main.js'); 131 | module.default(); 132 | // logs => This is default function 133 | module.learnJs(); 134 | // logs => Learn Js 135 | })(); 136 | ``` 137 | 138 | ### 7. globalThis 139 | 140 | Now we can access the global **this** in any javascript environment 141 | (like browser,Node.js or something else) 142 | 143 | For Example: 144 | 145 | ```javascript 146 | //In browser 147 | console.log(globalThis); 148 | //window 149 | //In node js 150 | console.log(globalThis); 151 | //global 152 | ``` 153 | 154 | ### 8. String.prototype.replaceAll() 155 | 156 | This is use to replace all instances of a given substring. 157 | 158 | For Example: 159 | ```javascript 160 | console.log('abba'.replace('b','_')) 161 | //a_ba 162 | // This only replace the first occurence of the substring. 163 | 164 | //Now we can use replaceAll() to remove all the occrurence 165 | console.log('abba'.replaceAll('b','_')); 166 | //a__a 167 | ``` 168 | -------------------------------------------------------------------------------- /questions/what-is-IIFE.md: -------------------------------------------------------------------------------- 1 | An IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined. 2 | 3 | ```javascript 4 | (function () { 5 | statements; 6 | })(); 7 | ``` 8 | -------------------------------------------------------------------------------- /questions/what-is-currying.md: -------------------------------------------------------------------------------- 1 | Currying is a way of constructing functions that allows partial application of a function’s arguments. 2 | 3 | What this means is that you can pass all of the arguments a function is expecting and get the result, or pass a subset of those arguments and get a function back that’s waiting for the rest of the arguments. It really is that simple. 4 | 5 | This function requires both the name and the greeting to be passed as arguments in order to work properly 6 | 7 | ```js 8 | var greet = function (greeting, name) { 9 | console.log(greeting + ' ' + name); // Output: Hello Tom 10 | }; 11 | 12 | greet('Hello', 'Tom'); 13 | ``` 14 | 15 | But we could rewrite this function using simple nested currying, so that the basic function only requires a greeting, and it returns another function that takes the name of the person we want to greet. 16 | 17 | ```js 18 | var greet = function (greeting) { 19 | return function (name) { 20 | console.log(greeting + ' ' + name); // Output: Hello Tom 21 | }; 22 | }; 23 | 24 | var greetHello = greet('Hello'); 25 | greetHello('Tom'); 26 | ``` 27 | 28 | Let’s takes another example of currying. 29 | 30 | In this example, the sum function only requires a first value, and it returns another function that takes the second value and returns the sum 31 | 32 | ```js 33 | function sum(a) { 34 | return function (b) { 35 | return a + b; 36 | }; 37 | } 38 | 39 | var sumWithTwo = sum(2); 40 | console.log(sumWithTwo(3)); // Output: 5 41 | ``` 42 | 43 | Another way of calling sum function without assigning in a variable. 44 | 45 | ```js 46 | function sum(a) { 47 | return function (b) { 48 | return a + b; 49 | }; 50 | } 51 | 52 | console.log(sum(2)(3)); // Output: 5 53 | ``` -------------------------------------------------------------------------------- /questions/what-is-the-difference-between-indexof-and-findindex.md: -------------------------------------------------------------------------------- 1 | ### indexOf() - 2 | 3 | - The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present. 4 | 5 | - It takes element to locate in array as parameter. 6 | 7 | ### findIndex()- 8 | 9 | - The findIndex() method returns the index of the first element in the array that satisfies the provided testing function. Otherwise, it returns -1. 10 | 11 | - It takes a callback function as a parameter 12 | 13 | ```javascript 14 | let arr = [-3, 4, -2, 6, 7, -1] 15 | 16 | console.log(arr.indexOf(4)) 17 | // 1 18 | 19 | console.log(arr.findIndex(4)) 20 | // TypeError: 4 is not a function 21 | 22 | let isPositive = e => e>0 23 | console.log(arr.findIndex(isPositive)) 24 | // 1 25 | ``` 26 | -------------------------------------------------------------------------------- /questions/what-is-the-difference-between-map-and-foreach.md: -------------------------------------------------------------------------------- 1 | ### map(): 2 | - map() calls the provided function for each array element and returns a new array of results. 3 | - It returns a new array. 4 | - It can be chained with other methods. 5 | 6 | ### forEach(): 7 | - forEach() calls the provided for each array element but does not returns a new array. 8 | - It returns undefined. 9 | - It cannot be chained further. 10 | 11 | ```javascript 12 | let nums = [1,2,3,4,5] 13 | 14 | let twoTimesNums = nums.map(n => n*2) 15 | console.log(twoTimesNums) // [2,4,6,8,10] 16 | 17 | // Similar thing using forEach 18 | let twoTimesNumsFE = [] 19 | nums.forEach(n => { 20 | twoTimesNumsFE.push(n*2) 21 | }) 22 | console.log(twoTimesNumsFE) // [2,4,6,8,10] 23 | 24 | // Chaining 25 | let sum = nums.map(n => n*2).reduce((sum, acc) => sum+acc) 26 | console.log(sum) // 30 27 | 28 | // Chaining not applicable in forEach as it returns undefined. 29 | ``` -------------------------------------------------------------------------------- /questions/what-is-use-strict-in-javascript.md: -------------------------------------------------------------------------------- 1 | ### What is the significance, and what are the benefits, of including ```use strict``` at the beginning of a JavaScript source file? 2 | 3 | The short and most important answer here is that ```use strict``` is a way to voluntarily enforce stricter parsing and error handling on your JavaScript code at runtime. Code errors that would otherwise have been ignored or would have failed silently will now generate errors or throw exceptions. In general, it is a good practice. 4 | 5 | - Makes debugging easier. Code errors that would otherwise have been ignored or would have failed silently will now generate errors or throw exceptions, alerting you sooner to problems in your code and directing you more quickly to their source. 6 | 7 | - Prevents accidental globals. Without strict mode, assigning a value to an undeclared variable automatically creates a global variable with that name. This is one of the most common errors in JavaScript. In strict mode, attempting to do so throws an error. 8 | 9 | - Eliminates `this` coercion. Without strict mode, a reference to a `this` value of null or undefined is automatically coerced to the global. This can cause many headfakes and pull-out-your-hair kind of bugs. In strict mode, referencing a `this` value of null or undefined throws an error. 10 | 11 | -------------------------------------------------------------------------------- /questions/what-is-work-of-delete-keyword-in-javascript.md: -------------------------------------------------------------------------------- 1 | The JavaScript delete operator removes a property from an object. 2 | 3 | For example: 4 | 5 | ```javascript 6 | // Creating a demo object 7 | let user = { 8 | name: "Akul Srivastava", 9 | username: "akulsr0", 10 | isAuthenticated: true, 11 | }; 12 | 13 | console.log(user.isAuthenticated); 14 | // true 15 | 16 | delete user.isAuthenticated; 17 | 18 | console.log(user.isAuthenticated); 19 | //undefined 20 | 21 | console.log(user); 22 | // { name: 'Akul Srivastava', username: 'akulsr0' } 23 | ``` 24 | -------------------------------------------------------------------------------- /questions/why-array-equals-not-array.md: -------------------------------------------------------------------------------- 1 | ```javascript 2 | [] == ![]; // true 3 | ``` 4 | 5 | It happens because the empty array on the right side is coerced to number first. An empty array when coerced to number gives 0 despite being truthy. 6 | 7 | Let's examine on both sides, 8 | 9 | L.H.S. => 10 | 11 | ```javascript 12 | Boolean([]); // true 13 | ``` 14 | 15 | R.H.S. => 16 | 17 | ```javascript 18 | Number([]); // 0 19 | !Number([]); // 1 20 | Boolean(!Number([])); // true 21 | ``` 22 | -------------------------------------------------------------------------------- /routes/api.js: -------------------------------------------------------------------------------- 1 | const { Router } = require('express'); 2 | const router = Router(); 3 | const marked = require('marked'); 4 | var Promise = require('bluebird'); 5 | var fs = Promise.promisifyAll(require('fs')); 6 | const path = require('path'); 7 | const hljs = require('highlight.js'); 8 | const { questions } = require('../utils/gto'); 9 | const topics = require('../utils/topics'); 10 | 11 | router.get('/gto/all', (req, res) => { 12 | res.json(questions); 13 | }); 14 | 15 | router.get('/gto/:title', (req, res) => { 16 | const title = req.params.title; 17 | const gtoDir = path.join(__dirname, '../guess-the-output/'); 18 | if (!fs.existsSync(gtoDir + title + '.md')) { 19 | return res.json({ error: 'File not found' }); 20 | } 21 | const mdContent = fs.readFileSync(`${gtoDir}/${title}.md`, 'utf8'); 22 | const titleUppercase = title 23 | .split('-') 24 | .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) 25 | .join(' '); 26 | res.json({ slug: title, title: titleUppercase, mdContent }); 27 | }); 28 | 29 | router.get('/questions/all', async (req, res) => { 30 | try { 31 | const directoryPath = path.join(__dirname, '../questions'); 32 | const filesArr = await fs.readdirAsync(directoryPath); 33 | const questions = []; 34 | filesArr.forEach((file) => { 35 | const slug = file.split('.')[0]; 36 | const titleFirstWord = slug.split('-')[0]; 37 | const title = 38 | titleFirstWord.charAt(0).toUpperCase() + 39 | titleFirstWord.slice(1) + 40 | ' ' + 41 | slug.split('-').slice(1).join(' '); 42 | const mdContent = fs.readFileSync(directoryPath + '/' + file, 'utf8'); 43 | const question = { slug, title, mdContent }; 44 | questions.push(question); 45 | }); 46 | res.json(questions); 47 | } catch (error) { 48 | console.log(error); 49 | } 50 | }); 51 | 52 | router.get('/programs/all', async (req, res) => { 53 | try { 54 | const directoryPath = path.join(__dirname, '../programs'); 55 | const filesArr = await fs.readdirAsync(directoryPath); 56 | const programs = []; 57 | filesArr.forEach((file) => { 58 | const slug = file.split('.')[0]; 59 | const titleFirstWord = slug.split('-')[0]; 60 | const title = 61 | titleFirstWord.charAt(0).toUpperCase() + 62 | titleFirstWord.slice(1) + 63 | ' ' + 64 | slug.split('-').slice(1).join(' '); 65 | const mdContent = fs.readFileSync(directoryPath + '/' + file, 'utf8'); 66 | const program = { slug, title, mdContent }; 67 | programs.push(program); 68 | }); 69 | res.json(programs); 70 | } catch (error) { 71 | console.log(error); 72 | } 73 | }); 74 | 75 | router.get('/topics', async (req, res) => { 76 | try { 77 | const programsDir = path.join(__dirname, '../programs'); 78 | const programsFiles = await fs.readdirAsync(programsDir); 79 | const programs = []; 80 | programsFiles.forEach((file) => { 81 | const slug = file.split('.')[0]; 82 | const title = slug 83 | .split('-') 84 | .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) 85 | .join(' '); 86 | const searchKey = slug.replace(/-/g, ''); 87 | const mdContent = fs.readFileSync(programsDir + '/' + file, 'utf8'); 88 | const program = { slug, title, searchKey, mdContent }; 89 | programs.push(program); 90 | }); 91 | 92 | const questionsDir = path.join(__dirname, '../questions'); 93 | const quesFiles = await fs.readdirAsync(questionsDir); 94 | const questions = []; 95 | quesFiles.forEach((file) => { 96 | const slug = file.split('.')[0]; 97 | const titleFirstWord = slug.split('-')[0]; 98 | const title = 99 | titleFirstWord.charAt(0).toUpperCase() + 100 | titleFirstWord.slice(1) + 101 | ' ' + 102 | slug.split('-').slice(1).join(' '); 103 | const searchKey = slug.replace(/-/g, ''); 104 | const mdContent = fs.readFileSync(questionsDir + '/' + file, 'utf8'); 105 | const question = { slug, title, searchKey, mdContent }; 106 | questions.push(question); 107 | }); 108 | 109 | const topicObj = {}; 110 | topics.sort(); 111 | for (let topic of topics) { 112 | topicObj[topic] = []; 113 | } 114 | let contentArr = [...programs, ...questions]; 115 | let topicKeys = Object.keys(topicObj); 116 | for (let key of topicKeys) { 117 | for (let c of contentArr) { 118 | if (c.searchKey.includes(key)) { 119 | topicObj[key].push(c); 120 | } 121 | } 122 | } 123 | res.json({ topics: topicObj }); 124 | } catch (error) { 125 | console.log(error); 126 | } 127 | }); 128 | 129 | module.exports = router; 130 | -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | const { Router } = require('express'); 2 | const router = Router(); 3 | const marked = require('marked'); 4 | var Promise = require('bluebird'); 5 | var fs = Promise.promisifyAll(require('fs')); 6 | const path = require('path'); 7 | const { questions } = require('../utils/gto'); 8 | const hljs = require('highlight.js'); 9 | const _ = require('underscore'); 10 | 11 | router.get('/', async (req, res) => { 12 | // Getting Programs 13 | const programsDir = path.join(__dirname, '../programs'); 14 | const programsFiles = await fs.readdirAsync(programsDir); 15 | const programs = []; 16 | programsFiles.forEach((file) => { 17 | const slug = file.split('.')[0]; 18 | const title = slug 19 | .split('-') 20 | .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) 21 | .join(' '); 22 | const mdContent = fs.readFileSync(programsDir + '/' + file, 'utf8'); 23 | const mdHtml = marked(mdContent); 24 | const program = { slug, title, html: mdHtml }; 25 | programs.push(program); 26 | }); 27 | 28 | // Getting Questions 29 | const questionsDir = path.join(__dirname, '../questions'); 30 | const quesFiles = await fs.readdirAsync(questionsDir); 31 | const questions = []; 32 | quesFiles.forEach((file) => { 33 | const slug = file.split('.')[0]; 34 | const titleFirstWord = slug.split('-')[0]; 35 | const title = 36 | titleFirstWord.charAt(0).toUpperCase() + 37 | titleFirstWord.slice(1) + 38 | ' ' + 39 | slug.split('-').slice(1).join(' '); 40 | const mdContent = fs.readFileSync(questionsDir + '/' + file, 'utf8'); 41 | const mdHtml = marked(mdContent); 42 | const question = { slug, title, html: mdHtml }; 43 | questions.push(question); 44 | }); 45 | 46 | res.render('index', { programs, questions }); 47 | }); 48 | 49 | router.get('/guess-the-output', (req, res) => { 50 | const gtoDir = path.join(__dirname, '../guess-the-output'); 51 | let randomQues = questions[Math.floor(Math.random() * questions.length)]; 52 | randomQues.options = _.shuffle(randomQues.options); 53 | let title = randomQues.title 54 | .split('-') 55 | .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) 56 | .join(' '); 57 | const mdContent = fs.readFileSync(`${gtoDir}/${randomQues.title}.md`, 'utf8'); 58 | marked.setOptions({ 59 | highlight: function (code, language) { 60 | const hljs = require('highlight.js'); 61 | const validLanguage = hljs.getLanguage(language) ? language : 'plaintext'; 62 | return hljs.highlight(validLanguage, code).value; 63 | }, 64 | }); 65 | const mdHtml = marked(mdContent); 66 | res.render('gto', { randomQues, mdHtml, title }); 67 | }); 68 | 69 | module.exports = router; 70 | -------------------------------------------------------------------------------- /routes/programs.js: -------------------------------------------------------------------------------- 1 | const { Router } = require('express'); 2 | const router = Router(); 3 | const marked = require('marked'); 4 | var Promise = require('bluebird'); 5 | var fs = Promise.promisifyAll(require('fs')); 6 | const path = require('path'); 7 | const hljs = require('highlight.js'); 8 | 9 | router.get('/', (req, res) => { 10 | const directoryPath = path.join(__dirname, '../programs'); 11 | fs.readdirAsync(directoryPath) 12 | .then((filesArr) => { 13 | const programs = []; 14 | filesArr.forEach((file) => { 15 | const slug = file.split('.')[0]; 16 | const title = slug 17 | .split('-') 18 | .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) 19 | .join(' '); 20 | const mdContent = fs.readFileSync(directoryPath + '/' + file, 'utf8'); 21 | marked.setOptions({ 22 | highlight: function (code, language) { 23 | const hljs = require('highlight.js'); 24 | const validLanguage = hljs.getLanguage(language) 25 | ? language 26 | : 'plaintext'; 27 | return hljs.highlight(validLanguage, code).value; 28 | }, 29 | }); 30 | const mdHtml = marked(mdContent); 31 | const program = { slug, title, html: mdHtml }; 32 | programs.push(program); 33 | }); 34 | res.render('programs', { programs }); 35 | }) 36 | .catch((err) => { 37 | console.log(err); 38 | }); 39 | }); 40 | 41 | router.get('/:slug', (req, res) => { 42 | const directoryPath = path.join(__dirname, '../programs'); 43 | const slug = req.params.slug; 44 | const title = slug 45 | .split('-') 46 | .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) 47 | .join(' '); 48 | const mdContent = fs.readFileSync(directoryPath + '/' + slug + '.md', 'utf8'); 49 | marked.setOptions({ 50 | highlight: function (code, language) { 51 | const hljs = require('highlight.js'); 52 | const validLanguage = hljs.getLanguage(language) ? language : 'plaintext'; 53 | return hljs.highlight(validLanguage, code).value; 54 | }, 55 | }); 56 | const mdHtml = marked(mdContent); 57 | const program = { slug, title, html: mdHtml }; 58 | res.render('program', { program }); 59 | }); 60 | 61 | module.exports = router; 62 | -------------------------------------------------------------------------------- /routes/questions.js: -------------------------------------------------------------------------------- 1 | const { Router } = require('express'); 2 | const router = Router(); 3 | const marked = require('marked'); 4 | var Promise = require('bluebird'); 5 | var fs = Promise.promisifyAll(require('fs')); 6 | const path = require('path'); 7 | const hljs = require('highlight.js'); 8 | 9 | router.get('/', async (req, res) => { 10 | const directoryPath = path.join(__dirname, '../questions'); 11 | const filesArr = await fs.readdirAsync(directoryPath); 12 | const questions = []; 13 | filesArr.forEach((file) => { 14 | const slug = file.split('.')[0]; 15 | const titleFirstWord = slug.split('-')[0]; 16 | const title = 17 | titleFirstWord.charAt(0).toUpperCase() + 18 | titleFirstWord.slice(1) + 19 | ' ' + 20 | slug.split('-').slice(1).join(' '); 21 | const mdContent = fs.readFileSync(directoryPath + '/' + file, 'utf8'); 22 | marked.setOptions({ 23 | highlight: function (code, language) { 24 | const hljs = require('highlight.js'); 25 | const validLanguage = hljs.getLanguage(language) 26 | ? language 27 | : 'plaintext'; 28 | return hljs.highlight(validLanguage, code).value; 29 | }, 30 | }); 31 | const mdHtml = marked(mdContent); 32 | const question = { slug, title, html: mdHtml }; 33 | questions.push(question); 34 | }); 35 | res.render('questions', { questions }); 36 | }); 37 | 38 | router.get('/:slug', (req, res) => { 39 | const directoryPath = path.join(__dirname, '../questions'); 40 | const slug = req.params.slug; 41 | const titleFirstWord = slug.split('-')[0]; 42 | const title = 43 | titleFirstWord.charAt(0).toUpperCase() + 44 | titleFirstWord.slice(1) + 45 | ' ' + 46 | slug.split('-').slice(1).join(' '); 47 | const mdContent = fs.readFileSync(directoryPath + '/' + slug + '.md', 'utf8'); 48 | marked.setOptions({ 49 | highlight: function (code, language) { 50 | const hljs = require('highlight.js'); 51 | const validLanguage = hljs.getLanguage(language) ? language : 'plaintext'; 52 | return hljs.highlight(validLanguage, code).value; 53 | }, 54 | }); 55 | const mdHtml = marked(mdContent); 56 | const question = { slug, title, html: mdHtml }; 57 | res.render('question', { question }); 58 | }); 59 | 60 | module.exports = router; 61 | -------------------------------------------------------------------------------- /routes/search.js: -------------------------------------------------------------------------------- 1 | const { Router } = require('express'); 2 | const router = Router(); 3 | const marked = require('marked'); 4 | var Promise = require('bluebird'); 5 | var fs = Promise.promisifyAll(require('fs')); 6 | const path = require('path'); 7 | const hljs = require('highlight.js'); 8 | 9 | router.get('/', async (req, res) => { 10 | try { 11 | const sQuery = req.query.q.toLowerCase(); 12 | 13 | // Getting Programs 14 | const programsDir = path.join(__dirname, '../programs'); 15 | const programsFiles = await fs.readdirAsync(programsDir); 16 | const programs = []; 17 | programsFiles.forEach((file) => { 18 | const slug = file.split('.')[0]; 19 | const title = slug 20 | .split('-') 21 | .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) 22 | .join(' '); 23 | const program = { slug, title }; 24 | programs.push(program); 25 | }); 26 | 27 | // Getting Questions 28 | const questionsDir = path.join(__dirname, '../questions'); 29 | const quesFiles = await fs.readdirAsync(questionsDir); 30 | const questions = []; 31 | quesFiles.forEach((file) => { 32 | const slug = file.split('.')[0]; 33 | const titleFirstWord = slug.split('-')[0]; 34 | const title = 35 | titleFirstWord.charAt(0).toUpperCase() + 36 | titleFirstWord.slice(1) + 37 | ' ' + 38 | slug.split('-').slice(1).join(' '); 39 | const question = { slug, title }; 40 | questions.push(question); 41 | }); 42 | 43 | let qPrograms = programs.filter((p) => 44 | p.title.toLowerCase().includes(sQuery) 45 | ); 46 | let qQuestions = questions.filter((q) => 47 | q.title.toLowerCase().includes(sQuery) 48 | ); 49 | 50 | res.render('searchresults', { 51 | sQuery, 52 | programs: qPrograms, 53 | questions: qQuestions, 54 | }); 55 | } catch (error) { 56 | console.log(error); 57 | } 58 | }); 59 | 60 | module.exports = router; 61 | -------------------------------------------------------------------------------- /routes/topics.js: -------------------------------------------------------------------------------- 1 | const { Router } = require('express'); 2 | const router = Router(); 3 | var Promise = require('bluebird'); 4 | var fs = Promise.promisifyAll(require('fs')); 5 | const path = require('path'); 6 | const topics = require('../utils/topics'); 7 | 8 | router.get('/', async (req, res) => { 9 | try { 10 | const programsDir = path.join(__dirname, '../programs'); 11 | const programsFiles = await fs.readdirAsync(programsDir); 12 | const programs = []; 13 | programsFiles.forEach((file) => { 14 | const slug = file.split('.')[0]; 15 | const title = slug 16 | .split('-') 17 | .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) 18 | .join(' '); 19 | const searchKey = slug.replace(/-/g, ''); 20 | const program = { slug, title, searchKey }; 21 | programs.push(program); 22 | }); 23 | 24 | const questionsDir = path.join(__dirname, '../questions'); 25 | const quesFiles = await fs.readdirAsync(questionsDir); 26 | const questions = []; 27 | quesFiles.forEach((file) => { 28 | const slug = file.split('.')[0]; 29 | const titleFirstWord = slug.split('-')[0]; 30 | const title = 31 | titleFirstWord.charAt(0).toUpperCase() + 32 | titleFirstWord.slice(1) + 33 | ' ' + 34 | slug.split('-').slice(1).join(' '); 35 | const searchKey = slug.replace(/-/g, ''); 36 | const question = { slug, title, searchKey }; 37 | questions.push(question); 38 | }); 39 | 40 | const topicObj = {}; 41 | topics.sort(); 42 | for (let topic of topics) { 43 | topicObj[topic] = []; 44 | } 45 | let contentArr = [...programs, ...questions]; 46 | let topicKeys = Object.keys(topicObj); 47 | for (let key of topicKeys) { 48 | for (let c of contentArr) { 49 | if (c.searchKey.includes(key)) { 50 | topicObj[key].push(c); 51 | } 52 | } 53 | } 54 | res.render('topics', { topics: topicObj }); 55 | } catch (error) { 56 | console.log(error); 57 | } 58 | }); 59 | 60 | router.get('/:topic', async (req, res) => { 61 | try { 62 | const topic = req.params.topic; 63 | 64 | const programsDir = path.join(__dirname, '../programs'); 65 | const programsFiles = await fs.readdirAsync(programsDir); 66 | const programs = []; 67 | programsFiles.forEach((file) => { 68 | const slug = file.split('.')[0]; 69 | const title = slug 70 | .split('-') 71 | .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) 72 | .join(' '); 73 | const program = { slug, title }; 74 | programs.push(program); 75 | }); 76 | 77 | // Getting Questions 78 | const questionsDir = path.join(__dirname, '../questions'); 79 | const quesFiles = await fs.readdirAsync(questionsDir); 80 | const questions = []; 81 | quesFiles.forEach((file) => { 82 | const slug = file.split('.')[0]; 83 | const titleFirstWord = slug.split('-')[0]; 84 | const title = 85 | titleFirstWord.charAt(0).toUpperCase() + 86 | titleFirstWord.slice(1) + 87 | ' ' + 88 | slug.split('-').slice(1).join(' '); 89 | const question = { slug, title }; 90 | questions.push(question); 91 | }); 92 | 93 | let tPrograms = programs.filter((p) => 94 | p.slug.replace(/-/g, '').toLowerCase().includes(topic) 95 | ); 96 | let tQuestions = questions.filter((q) => 97 | q.slug.replace(/-/g, '').toLowerCase().includes(topic) 98 | ); 99 | let capTopic = topic.charAt(0).toUpperCase() + topic.slice(1); 100 | 101 | res.render('topic', { 102 | topic: capTopic, 103 | programs: tPrograms, 104 | questions: tQuestions, 105 | }); 106 | } catch (error) { 107 | console.log(error); 108 | } 109 | }); 110 | 111 | module.exports = router; 112 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const ejs = require('ejs'); 3 | const cors = require('cors'); 4 | 5 | const app = express(); 6 | 7 | app.use(cors()); 8 | app.set('view engine', 'ejs'); 9 | app.use(express.static(__dirname + '/public')); 10 | const PORT = process.env.PORT || 3001; 11 | 12 | app.use('/', require('./routes/index')); 13 | app.use('/api', require('./routes/api')); 14 | app.use('/programs', require('./routes/programs')); 15 | app.use('/questions', require('./routes/questions')); 16 | app.use('/topics', require('./routes/topics')); 17 | app.use('/search', require('./routes/search')); 18 | 19 | app.listen(PORT, () => { 20 | console.log(`Server is running at port ${PORT}`); 21 | }); 22 | -------------------------------------------------------------------------------- /utils/gto.js: -------------------------------------------------------------------------------- 1 | let questions = [ 2 | { 3 | title: 'bool-plus-number', 4 | options: ['12', 'false', 'true', '2'], 5 | answer: '2', 6 | }, 7 | { 8 | title: 'bool-plus-string', 9 | options: ['true1', 'truetrue', 'true', 'undefined'], 10 | answer: 'true1', 11 | }, 12 | { 13 | title: 'tricky-array-init', 14 | options: ['[3, 3, 3]', '[]', '[ <3 empty items> ]', '[null, null, null]'], 15 | answer: '[ <3 empty items> ]', 16 | }, 17 | { 18 | title: 'adding-two-array', 19 | options: [ 20 | '[1, 2, 3, 4, 5]', 21 | '[1, 2, 3, 3, 4, 5]', 22 | '1,2,33,4,5', 23 | '1,2,3,3,4,5', 24 | ], 25 | answer: '1,2,33,4,5', 26 | }, 27 | { 28 | title: 'destructuring-and-string-joining', 29 | options: ['i,o,u', 'iou', 'u', 'undefined'], 30 | answer: 'i,o,u', 31 | }, 32 | { 33 | title: 'the-number-constructor', 34 | options: ['true', 'false'], 35 | answer: 'false', 36 | }, 37 | { 38 | title: 'typeof-array', 39 | options: ['array', 'object', 'null', 'undefined'], 40 | answer: 'object', 41 | }, 42 | { 43 | title: 'typeof-nan', 44 | options: ['number', 'object', 'null', 'undefined'], 45 | answer: 'number', 46 | }, 47 | { 48 | title: 'delete-array-element', 49 | options: [ 50 | '[ 1, 2, 3, <1 empty item>, 5 ]', 51 | '[ 1, 2, 3, null, 5 ]', 52 | '[ 1, 2, 3, 4, 5 ]', 53 | '[ 1, 2, 3, undefined, 5 ]', 54 | ], 55 | answer: '[ 1, 2, 3, <1 empty item>, 5 ]', 56 | }, 57 | { 58 | title: 'array-length-after-deleting-element', 59 | options: ['5', '4', '0', 'Reference Error'], 60 | answer: '5', 61 | }, 62 | { 63 | title: 'calling-function-before-defining', 64 | options: ['John', 'Jane', 'undefined', 'Reference Error'], 65 | answer: 'John', 66 | }, 67 | { 68 | title: 'instanceof-number', 69 | options: ['true', 'false'], 70 | answer: 'false', 71 | }, 72 | { 73 | title: 'is-deleted-array-element-undefined', 74 | options: ['-1', '4', 'null', 'empty'], 75 | answer: '-1', 76 | }, 77 | { 78 | title: 'is-this-not-a-number', 79 | options: ['true', 'false'], 80 | answer: 'true', 81 | }, 82 | { 83 | title: 'hundred-by-zero', 84 | options: ['0', 'Infinity', 'NaN', '1'], 85 | answer: 'Infinity', 86 | }, 87 | { 88 | title: 'string-search-regex', 89 | options: ['undefined', 'D', 'H', 'h'], 90 | answer: 'H', 91 | }, 92 | { 93 | title: 'array-reduce-right', 94 | options: ['3LOL5', '5LOL21', '5LOL3', '239'], 95 | answer: '5LOL21', 96 | }, 97 | { 98 | title: 'substr-and-slice', 99 | options: ['true', 'false'], 100 | answer: 'false', 101 | }, 102 | { 103 | title: 'string-iterator', 104 | options: ['string', 'number', 'undefined', 'symbol'], 105 | answer: 'string', 106 | }, 107 | { 108 | title: 'string-repeat', 109 | options: ['hahaha', 'hahahaha'], 110 | answer: 'hahaha', 111 | }, 112 | { 113 | title: 'string-charCodeAt', 114 | options: ['true', 'false'], 115 | answer: 'true', 116 | }, 117 | { 118 | title: 'is-nan-finite', 119 | options: ['undefined', 'true', 'false', 'Reference Error'], 120 | answer: 'false', 121 | }, 122 | { 123 | title: 'bool-compare', 124 | options: ['true', 'false', 'NaN', 'undefined'], 125 | answer: 'false', 126 | }, 127 | { 128 | title: 'guess-return-type', 129 | options: ['number', 'function', 'string', 'Syntax Error'], 130 | answer: 'function', 131 | }, 132 | { 133 | title: 'adding-empty-and-non-empty-array', 134 | options: ['f,o,o', 'Type Error', '[][][f,o,o]', '[f,o,o]'], 135 | answer: 'f,o,o', 136 | }, 137 | { 138 | title: 'new-array-to-string', 139 | options: ["''", ',,,', ',,', '[]'], 140 | answer: ',,', 141 | }, 142 | { 143 | title: 'set-array-element-by-index', 144 | options: [ 145 | '[ <1 empty item>, 2, 3 ]', 146 | '[undefined, 2, 3]', 147 | '[null, 2, 3]', 148 | 'Type Error', 149 | ], 150 | answer: '[ <1 empty item>, 2, 3 ]', 151 | }, 152 | ]; 153 | 154 | module.exports = { questions }; 155 | -------------------------------------------------------------------------------- /utils/gto.test.js: -------------------------------------------------------------------------------- 1 | const { questions } = require('./gto'); 2 | const path = require('path'); 3 | var Promise = require('bluebird'); 4 | var fs = Promise.promisifyAll(require('fs')); 5 | 6 | function ifGTOExists(filename) { 7 | filename = filename + '.md'; 8 | let dir = path.join(__dirname, '../guess-the-output/'); 9 | if (fs.existsSync(dir + filename)) { 10 | return true; 11 | } else { 12 | return false; 13 | } 14 | } 15 | 16 | for (let question of questions) { 17 | test('Check if corresponding markdown exists', () => { 18 | expect(ifGTOExists(question.title)).toBe(true); 19 | }); 20 | } 21 | 22 | for (let question of questions) { 23 | test('Check if there is a valid answer in options and only once', () => { 24 | expect(question.options.includes(question.answer)).toBe(true); 25 | expect( 26 | question.options.filter((opt) => opt === question.answer).length 27 | ).toBe(1); 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /utils/topics.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | 'array', 3 | 'linkedlist', 4 | 'graph', 5 | 'tree', 6 | 'heap', 7 | 'search', 8 | 'sort', 9 | ]; 10 | -------------------------------------------------------------------------------- /views/footer.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 23 | 24 | 25 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /views/gto.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 14 | 15 | 16 | 17 | 22 | 26 | 33 | LearnJS 34 | 35 | 36 | <%- include('./header.ejs') %> <%- include('./nav.ejs') %> 37 |
38 |

Question: <%=title%>

39 |
40 | <%- mdHtml %> 41 |
42 |

Answer:

43 |
44 |
45 | <% for(let option of randomQues.options) { %> 46 | -> 47 |
48 | <% } %> 49 |
50 |
51 | 56 | 63 |
64 |
65 | 66 | 67 |
68 |
69 |
70 | <%- include('./footer.ejs') %> 71 | 72 | 97 | 98 | -------------------------------------------------------------------------------- /views/header.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 30 | 31 | 32 |
33 |

LearnJS

34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 15 | 16 | 17 | 18 | 23 | 24 | 25 | 26 | LearnJS 27 | 28 | 29 | <%- include('./header.ejs') %> <%- include('./nav.ejs') %> 30 |
31 |
32 |

Programs

33 | 40 |
41 |
42 |

Questions

43 | 50 |
51 | <%- include('./footer.ejs') %> 52 |
53 | 54 | 55 | -------------------------------------------------------------------------------- /views/nav.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 22 | <%- include('./search.ejs') %> 23 | 24 | 25 | -------------------------------------------------------------------------------- /views/program.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 14 | 15 | 16 | 17 | 22 | <%=program.title%> | LearnJS 23 | 27 | 34 | 35 | 36 | <%- include('./header.ejs') %> <%- include('./nav.ejs') %> 37 |
38 |

<%=program.title%>

39 |
40 | <%- program.html %> 41 |
42 |
43 | <%- include('./footer.ejs') %> 44 | 45 | 46 | -------------------------------------------------------------------------------- /views/programs.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 14 | 15 | 16 | 17 | 22 | 23 | Programs: LearnJS 24 | 25 | 26 | <%- include('./header.ejs') %> <%- include('./nav.ejs') %> 27 |
28 |
29 |

Programs (<%=programs.length%>)

30 | 37 |
38 | <%- include('./footer.ejs') %> 39 |
40 | 41 | 42 | -------------------------------------------------------------------------------- /views/question.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 14 | 15 | 16 | 17 | 22 | <%=question.title%> | LearnJS 23 | 27 | 34 | 35 | 36 | <%- include('./header.ejs') %> <%- include('./nav.ejs') %> 37 |
38 |

<%=question.title%>

39 |
40 | <%- question.html %> 41 |
42 |
43 | <%- include('./footer.ejs') %> 44 | 45 | 46 | -------------------------------------------------------------------------------- /views/questions.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 14 | 15 | 16 | 17 | 22 | 23 | Questions: LearnJS 24 | 25 | 26 | <%- include('./header.ejs') %> <%- include('./nav.ejs') %> 27 |
28 |
29 |

Questions (<%=questions.length%>)

30 | 37 |
38 | <%- include('./footer.ejs') %> 39 |
40 | 41 | 42 | -------------------------------------------------------------------------------- /views/search.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |
6 |
7 | -------------------------------------------------------------------------------- /views/searchresults.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 14 | 15 | 16 | 17 | 22 | Search: <%=sQuery%> 23 | 24 | 25 | <%- include('./header.ejs') %> <%- include('./nav.ejs') %> 26 |
27 |

Search: <%=sQuery%>

28 |
29 |

Programs

30 | 37 |
38 |
39 |

Questions

40 | 47 |
48 | <%- include('./footer.ejs') %> 49 |
50 | 51 | 52 | -------------------------------------------------------------------------------- /views/topic.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 14 | 15 | 16 | 17 | 22 | <%=topic%>: LearnJS 23 | 24 | 25 | <%- include('./header.ejs') %> <%- include('./nav.ejs') %> 26 |
27 |

Topic: <%=topic%>

28 |
29 |

Programs

30 | 37 |
38 |
39 |

Questions

40 | 47 |
48 |
49 | <%-include('./footer.ejs') %> 50 | 51 | 52 | -------------------------------------------------------------------------------- /views/topics.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 14 | 15 | 16 | 17 | 22 | 23 | Topics: LearnJS 24 | 25 | 26 | <%- include('./header.ejs') %> <%- include('./nav.ejs') %> 27 |
28 |

Topics

29 | 38 |
39 | <%-include('./footer.ejs') %> 40 | 41 | 42 | --------------------------------------------------------------------------------