├── .gitignore ├── 01-basic-challenges-1 ├── 01-hello-world │ ├── hello-world-run.js │ ├── hello-world-solution.js │ ├── hello-world-test.js │ ├── hello-world.js │ └── readme.md ├── 02-get-sum │ ├── get-sum-run.js │ ├── get-sum-solution.js │ ├── get-sum-test.js │ ├── get-sum.js │ └── readme.md ├── 03-calculator │ ├── calculator-run.js │ ├── calculator-solution.js │ ├── calculator-test.js │ ├── calculator.js │ └── readme.md ├── 04-count-occurrences │ ├── count-occurences-run.js │ ├── count-occurences-solution.js │ ├── count-occurrences-test.js │ ├── count-occurrences.js │ └── readme.md ├── 05-find-max-number │ ├── find-max-number-run.js │ ├── find-max-number-solution.js │ ├── find-max-number-test.js │ ├── find-max-number.js │ └── readme.md ├── 06-title-case │ ├── readme.md │ ├── title-case-run.js │ ├── title-case-solution.js │ ├── title-case-test.js │ └── title-case.js ├── 07-reverse-string │ ├── readme.md │ ├── reverse-string-run.js │ ├── reverse-string-solution.js │ ├── reverse-string-test.js │ └── reverse-string.js ├── 08-palindrome │ ├── palindrome-run.js │ ├── palindrome-solution.js │ ├── palindrome-test.js │ ├── palindrome.js │ └── readme.md ├── 09-count-vowels │ ├── count-vowels-run.js │ ├── count-vowels-solution.js │ ├── count-vowels-test.js │ ├── count-vowels.js │ └── readme.md └── 10-remove-duplicates │ ├── readme.md │ ├── remove-duplicates-run.js │ ├── remove-duplicates-solution.js │ ├── remove-duplicates-test.js │ └── remove-duplicates.js ├── 02-basic-challenges-2 ├── 01-fizzbuzz-array │ ├── fizzbuzz-array-run.js │ ├── fizzbuzz-array-solution.js │ ├── fizzbuzz-array-test.js │ ├── fizzbuzz-array.js │ └── readme.md ├── 02-array-intersection │ ├── array-intersection-run.js │ ├── array-intersection-solution.js │ ├── array-intersection-test.js │ ├── array-intersection.js │ └── readme.md ├── 03-display-likes │ ├── display-likes-run.js │ ├── display-likes-solution.js │ ├── display-likes-test.js │ ├── display-likes.js │ └── readme.md ├── 04-find-missing-number │ ├── find-missing-number-run.js │ ├── find-missing-number-solution.js │ ├── find-missing-number-test.js │ ├── find-missing-number.js │ └── readme.md ├── 05-find-missing-letter │ ├── find-missing-letter-run.js │ ├── find-missing-letter-solution.js │ ├── find-missing-letter-test.js │ ├── find-missing-letter.js │ └── readme.md ├── 06-are-all-chars-unique │ ├── are-all-chars-unique-run.js │ ├── are-all-chars-unique-solution.js │ ├── are-all-chars-unique-test.js │ ├── are-all-chars-unique.js │ └── readme.md ├── 07-first-non-repeating │ ├── first-non-repeating-run.js │ ├── first-non-repeating-solution.js │ ├── first-non-repeating-test.js │ ├── first-non-repeating.js │ └── readme.md ├── 08-dice-game │ ├── dice-game-run.js │ ├── dice-game-solution.js │ ├── dice-game-test.js │ ├── dice-game.js │ └── readme.md ├── 09-format-phone-number │ ├── format-phone-number-run.js │ ├── format-phone-number-solution.js │ ├── format-phone-number-test.js │ ├── format-phone-number.js │ └── readme.md └── 10-validate-email │ ├── readme.md │ ├── validate-email-run.js │ ├── validate-email-solution.js │ ├── validate-email-test.js │ └── validate-email.js ├── 03-high-order-array-methods ├── 01-simple-examples │ ├── readme.md │ ├── simple-examples-done.js │ └── simple-examples.js ├── 02-sum-of-even-squares │ ├── readme.md │ ├── sum-of-even-squares-run.js │ ├── sum-of-even-squares-solution.js │ ├── sum-of-even-squares-test.js │ └── sum-of-even-squares.js ├── 03-calculate-total-sales │ ├── calculate-total-sales-run.js │ ├── calculate-total-sales-solution.js │ ├── calculate-total-sales-test.js │ ├── calculate-total-sales.js │ └── readme.md ├── 04-highest-scoring-word │ ├── highest-scoring-word-run.js │ ├── highest-scoring-word-solution.js │ ├── highest-scoring-word-test.js │ ├── highest-scoring-word.js │ └── readme.md ├── 05-valid-anagrams │ ├── readme.md │ ├── valid-anagrams-run.js │ ├── valid-anagrams-solution.js │ ├── valid-anagrams-test.js │ └── valid-anagrams.js ├── 06-hashtag-generator │ ├── hashtag-generator-run.js │ ├── hashtag-generator-solution.js │ ├── hashtag-generator-test.js │ ├── hashtag-generator.js │ └── readme.md ├── 07-valid-ipv4 │ ├── readme.md │ ├── valid-ipv4-run.js │ ├── valid-ipv4-solution.js │ ├── valid-ipv4-test.js │ └── valid-ipv4.js ├── 08-analyze-car-milage │ ├── analyze-car-milage-run.js │ ├── analyze-car-milage-solution.js │ ├── analyze-car-milage-test.js │ ├── analyze-car-milage.js │ └── readme.md ├── 09-password-validator │ ├── password-validator-run.js │ ├── password-validator-solution.js │ ├── password-validator-test.js │ ├── password-validator.js │ └── readme.md └── 10-find-missing-letter-refactor │ ├── find-missing-letter-refactor-run.js │ ├── find-missing-letter-refactor-solution.js │ ├── find-missing-letter-refactor-test.js │ ├── find-missing-letter-refactor.js │ └── readme.md ├── 04-recursion ├── 01-recursion-intro │ ├── count-down-run.js │ ├── count-down-solution.js │ ├── count-down-test.js │ ├── count-down.js │ └── readme.md ├── 02-unwinding │ ├── readme.md │ ├── sum-up-to-run.js │ ├── sum-up-to-solution.js │ ├── sum-up-to-test.js │ └── sum-up-to.js ├── 03-reverse-string-recursion │ ├── readme.md │ ├── reverse-string-recursion-run.js │ ├── reverse-string-recursion-solution.js │ ├── reverse-string-recursion-test.js │ └── reverse-string-recursion.js ├── 04-fibonacci-sequence │ ├── fibonacci-run.js │ ├── fibonacci-solution.js │ ├── fibonacci-test.js │ ├── fibonacci.js │ └── readme.md ├── 05-factorial │ ├── factorial-run.js │ ├── factorial-solution.js │ ├── factorial-test.js │ ├── factorial.js │ └── readme.md ├── 06-power │ ├── power-run.js │ ├── power-solution.js │ ├── power-test.js │ ├── power.js │ └── readme.md ├── 07-array-sum │ ├── array-sum-run.js │ ├── array-sum-solution.js │ ├── array-sum-test.js │ ├── array-sum.js │ └── readme.md ├── 08-number-range │ ├── number-range-run.js │ ├── number-range-solution.js │ ├── number-range-test.js │ ├── number-range.js │ └── readme.md ├── 09-flatten-array │ ├── flatten-array-run.js │ ├── flatten-array-solution.js │ ├── flatten-array-test.js │ ├── flatten-array.js │ └── readme.md └── 10-permutations │ ├── permutations-run.js │ ├── permutations-solution.js │ ├── permutations-test.js │ ├── permutations.js │ └── readme.md ├── 05-complexity ├── 01-what-is-time-complexity │ └── readme.md ├── 02-big-o-notation │ └── readme.md ├── 03-constant-time-complexity │ ├── constant-time-done.js │ ├── constant-time.js │ └── readme.md ├── 04-linear-time-complexity │ ├── linear-time-done.js │ ├── linear-time.js │ └── readme.md ├── 05-quadratic-time-complexity │ ├── quadradic-time-done.js │ ├── quadradic-time.js │ └── readme.md ├── 06-logarithmic-time-complexity │ ├── logarithmic-time-done.js │ ├── logarithmic-time.js │ └── readme.md ├── 07-space-complexity │ ├── readme.md │ └── space-complexity.js ├── 08-max-subarray-quadratic │ ├── max-subarray-quadratic-run.js │ ├── max-subarray-quadratic-solution.js │ ├── max-subarray-quadratic-test.js │ ├── max-subarray-quadratic.js │ └── readme.md ├── 09-sliding-window-technique │ └── readme.md └── 10-max-subarray-linear │ ├── max-subarray-linear-run.js │ ├── max-subarray-linear-solution.js │ ├── max-subarray-linear-test.js │ ├── max-subarray-linear.js │ └── readme.md ├── 06-hash-tables-maps-sets ├── 01-what-are-data-structures │ └── readme.md ├── 02-hash-table-intro │ └── readme.md ├── 03-maps │ ├── maps-done.js │ ├── maps.js │ └── readme.md ├── 04-word-frequency-counter │ ├── readme.md │ ├── word-frequency-counter-run.js │ ├── word-frequency-counter-solution.js │ ├── word-frequency-counter-test.js │ └── word-frequency-counter.js ├── 05-phone-number-directory │ ├── phone-number-directory-run.js │ ├── phone-number-directory-solution.js │ ├── phone-number-directory-test.js │ ├── phone-number-directory.js │ └── readme.md ├── 06-anagram-grouping │ ├── anagram-grouping-run.js │ ├── anagram-grouping-solution.js │ ├── anagram-grouping-test.js │ ├── anagram-grouping.js │ └── readme.md ├── 07-sets │ ├── readme.md │ ├── sets-done.js │ └── sets.js ├── 08-symmetric-difference │ ├── readme.md │ ├── symmetric-difference-solution.js │ ├── symmetric-difference-test.js │ ├── symmetric-difference.js │ └── symmetric-diiference-run.js ├── 09-two-sum │ ├── readme.md │ ├── two-sum-run.js │ ├── two-sum-solution.js │ ├── two-sum-test.js │ └── two-sum.js ├── 10-longest-consecutive │ ├── logest-consecutive-test.js │ ├── longest-consecutive-run.js │ ├── longest-consecutive-solution.js │ ├── longest-consecutive.js │ └── readme.md ├── 11-custom-hash-table │ ├── custom-hash-table-run.js │ ├── custom-hash-table-solution.js │ ├── custom-hash-table-test.js │ ├── custom-hash-table.js │ └── readme.md ├── 12-word-instance-counter │ ├── HashTable.js │ ├── readme.md │ ├── word-instance-counter-run.js │ ├── word-instance-counter-solution.js │ ├── word-instance-counter-test.js │ └── word-instance-counter.js ├── 13-add-get-values-method │ ├── HashTable.js │ ├── get-values-run.js │ ├── get-values-solution.js │ ├── get-values-test.js │ └── readme.md └── 14-custom-anagram-grouping │ ├── HashTable.js │ ├── custom-anagram-grouping-run.js │ ├── custom-anagram-grouping-solution.js │ ├── custom-anagram-grouping-test.js │ ├── custom-anagram-grouping.js │ └── readme.md ├── 07-stacks-queues-linked-lists ├── 01-what-is-a-stack │ └── readme.md ├── 02-stack-implementation │ ├── readme.md │ ├── stack-run.js │ ├── stack-solution.js │ ├── stack-test.js │ └── stack.js ├── 03-reverse-string-stack │ ├── readme.md │ ├── reverse-string-stack-run.js │ ├── reverse-string-stack-solution.js │ ├── reverse-string-stack-test.js │ ├── reverse-string-stack.js │ └── stack.js ├── 04-balanced-parenthesis │ ├── balanced-parenthesis-run.js │ ├── balanced-parenthesis-solution.js │ ├── balanced-parenthesis-test.js │ ├── balanced-parenthesis.js │ ├── readme.md │ └── stack.js ├── 05-what-is-a-queue │ └── readme.md ├── 06-queue-implementation │ ├── queue-run.js │ ├── queue-solution.js │ ├── queue-test.js │ ├── queue.js │ └── readme.md ├── 07-reverse-string-queue │ ├── queue.js │ ├── readme.md │ ├── reverse-string-queue-run.js │ ├── reverse-string-queue-solution.js │ ├── reverse-string-queue-test.js │ └── reverse-string-queue.js ├── 08-palindrome-queue-stack.js │ ├── palindrome-queue-stack-run.js │ ├── palindrome-queue-stack-solution.js │ ├── palindrome-queue-stack-test.js │ ├── palindrome-queue-stack.js │ ├── queue.js │ ├── readme.md │ └── stack.js ├── 09-what-is-a-linked-list │ └── readme.md ├── 10-linked-list-implementation │ ├── linked-list-run.js │ ├── linked-list-solution.js │ ├── linked-list-test.js │ ├── linked-list.js │ └── readme.md ├── 11-reverse-string-linked-list │ ├── linked-list.js │ ├── readme.md │ ├── reverse-string-linked-list-run.js │ ├── reverse-string-linked-list-solution.js │ ├── reverse-string-linked-list-test.js │ └── reverse-string-linked-list.js ├── 12-fast-and-slow-pointers │ └── readme.md ├── 13-find-middle │ ├── find-middle-run.js │ ├── find-middle-solution.js │ ├── find-middle-test.js │ ├── find-middle.js │ ├── linked-list.js │ └── readme.md ├── 14-what-is-a-doubly-linked-list │ └── readme.md ├── 15-doubly-linked-list-implementation │ ├── doubly-linked-list-run.js │ ├── doubly-linked-list-solution.js │ ├── doubly-linked-list-test.js │ ├── doubly-linked-list.js │ └── readme.md └── 16-find-pair-sum │ ├── DoublyLinkedList.js │ ├── find-pair-sum-run.js │ ├── find-pair-sum-solution.js │ ├── find-pair-sum-test.js │ ├── find-pair-sum.js │ └── readme.md ├── 08-binary-trees-graphs ├── 01-what-is-a-tree │ └── readme.md ├── 02-tree-node-class │ ├── readme.md │ ├── tree-node-class-run.js │ ├── tree-node-class-solution.js │ ├── tree-node-class-test.js │ └── tree-node-class.js ├── 03-depth-first-traversal │ ├── depth-first-traversal-run.js │ ├── depth-first-traversal-solution.js │ ├── depth-first-traversal-test.js │ ├── depth-first-traversal.js │ ├── readme.md │ └── stack.js ├── 04-depth-first-traversal-recursive │ ├── depth-first-traversal-recursive-run.js │ ├── depth-first-traversal-recursive-solution.js │ ├── depth-first-traversal-recursive-test.js │ ├── depth-first-traversal-recursive.js │ └── readme.md ├── 05-breadth-first-traversal │ ├── breadth-first-traversal-run.js │ ├── breadth-first-traversal-solution.js │ ├── breadth-first-traversal-test.js │ ├── breadth-first-traversal.js │ ├── queue.js │ └── readme.md ├── 06-maximum-depth │ ├── maximum-depth-run.js │ ├── maximum-depth-solution.js │ ├── maximum-depth-test.js │ ├── maximum-depth.js │ └── readme.md ├── 07-what-is-a-binary-search-tree │ └── readme.md ├── 08-binary-search-tree-implementation │ ├── binary-search-tree-run.js │ ├── binary-search-tree-solution.js │ ├── binary-search-tree-test.js │ ├── binary-search-tree.js │ └── readme.md ├── 09-validate-bst │ ├── readme.md │ ├── validate-bst-run.js │ ├── validate-bst-solution.js │ ├── validate-bst-test.js │ └── validate-bst.js ├── 10-what-is-a-graph │ └── readme.md ├── 11-adjacency-matrix-adjacency-list │ └── readme.md ├── 12-graph-implementation │ ├── graph-run.js │ ├── graph-solution.js │ ├── graph-test.js │ ├── graph.js │ └── readme.md ├── 13-graph-traversal │ └── readme.md ├── 14-graph-depth-first-traversal │ ├── graph-depth-first-run.js │ ├── graph-depth-first-solution.js │ ├── graph-depth-first-test.js │ ├── graph-depth-first.js │ ├── graph.js │ ├── readme.md │ └── stack.js └── 15-graph-breadth-first-traversal │ ├── graph-breadth-first-run.js │ ├── graph-breadth-first-solution.js │ ├── graph-breadth-first-test.js │ ├── graph-breadth-first.js │ ├── graph.js │ ├── queue.js │ └── readme.md ├── 09-sorting-algorithms ├── 01-what-are-sorting-algorithms │ └── readme.md ├── 02-bubble-sort-algorithm │ └── readme.md ├── 03-bubble-sort-implementation │ ├── bubble-sort-run.js │ ├── bubble-sort-solution.js │ ├── bubble-sort-test.js │ ├── bubble-sort.js │ └── readme.md ├── 04-insertion-sort-algorithm │ └── readme.md ├── 05-insertion-sort-implementation │ ├── insertion-sort-run.js │ ├── insertion-sort-solution.js │ ├── insertion-sort-test.js │ ├── insertion-sort.js │ └── readme.md ├── 06-selection-sort-algorithm │ └── readme.md ├── 07-selection-sort-implentation │ ├── readme.md │ ├── selection-sort-run.js │ ├── selection-sort-solution.js │ ├── selection-sort-test.js │ └── selection-sort.js ├── 08-merge-sort-algorithm │ └── readme.md ├── 09-merge-sort-implementation │ ├── merge-sort-run.js │ ├── merge-sort-solution.js │ ├── merge-sort-test.js │ ├── merge-sort.js │ └── readme.md ├── 10-quick-sort-algorithm │ └── readme.md └── 11-quick-sort-implementation │ ├── quick-sort-run.js │ ├── quick-sort-solution.js │ ├── quick-sort-test.js │ ├── quick-sort.js │ └── readme.md ├── assets └── images │ ├── adjacency-list.png │ ├── adjacency-matrix.png │ ├── binary-search-tree.png │ ├── binary-search-tree1.png │ ├── binarytree.png │ ├── breadth-first.png │ ├── bubble-sort-console.png │ ├── bubble-sort.png │ ├── depth-first.png │ ├── doubly-linked-list.png │ ├── event-loop.png │ ├── fastslow.png │ ├── firstnonrepeat.png │ ├── graph-breadth-first.png │ ├── graph-cycle.png │ ├── graph-depth-first.png │ ├── graph.png │ ├── graph1.png │ ├── hash-table.png │ ├── insertion-sort.png │ ├── linked-list1.png │ ├── merge-sort.png │ ├── notbinarytree.png │ ├── queue1.png │ ├── quicksort.png │ ├── recursion-stack-1.png │ ├── recursion-stack-2.png │ ├── selection-sort.png │ ├── sliding-window.png │ ├── stack1.png │ ├── time-complexity.webp │ ├── tree1.png │ ├── tree2.png │ ├── tree3.png │ ├── tree4.png │ ├── tree5.png │ └── treeheightdepth.png ├── package-lock.json ├── package.json └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store -------------------------------------------------------------------------------- /01-basic-challenges-1/01-hello-world/hello-world-run.js: -------------------------------------------------------------------------------- 1 | const helloWorld = require('./hello-world'); 2 | 3 | const result = helloWorld(); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /01-basic-challenges-1/01-hello-world/hello-world-solution.js: -------------------------------------------------------------------------------- 1 | function helloWorld() { 2 | // Return the string 'Hello World!' 3 | return 'Hello World!'; 4 | } 5 | 6 | module.exports = helloWorld; 7 | -------------------------------------------------------------------------------- /01-basic-challenges-1/01-hello-world/hello-world-test.js: -------------------------------------------------------------------------------- 1 | const helloWorld = require('./hello-world'); 2 | 3 | test("Returning 'Hello, World!' as a string", () => { 4 | const result = helloWorld(); 5 | expect(result).toBe('Hello World!'); 6 | }); 7 | -------------------------------------------------------------------------------- /01-basic-challenges-1/01-hello-world/hello-world.js: -------------------------------------------------------------------------------- 1 | function helloWorld() {} 2 | 3 | module.exports = helloWorld; 4 | -------------------------------------------------------------------------------- /01-basic-challenges-1/01-hello-world/readme.md: -------------------------------------------------------------------------------- 1 | # Challenge: Hello World Sample Challenge 2 | 3 | This is a practice challenge to show you how things are set up and how to test, etc. 4 | 5 | ## Instructions 6 | 7 | Write a function called `helloWorld` that returns a string of 'Hello World!'. 8 | 9 | ### Function Signature 10 | 11 | ```js 12 | /** 13 | * Returns a string containing 'Hello World!'. 14 | * @returns {string} - The string 'Hello World!'. 15 | */ 16 | function helloWorld(): string; 17 | ``` 18 | 19 | ### Examples 20 | 21 | ```JS 22 | helloWorld() // 'Hello World!' 23 | ``` 24 | 25 | ### Constraints 26 | 27 | I will put any constraints here. They will vary depending on the challenge. 28 | 29 | - The function must return a string 30 | 31 | ### Hints 32 | 33 | - I will put a couple hints here. You can choose to use them or not. 34 | 35 | ## Solutions 36 | 37 |
38 | Click For Solution 39 | 40 | ```JS 41 | function printHelloWorld() { 42 | return 'Hello World!'; 43 | } 44 | ``` 45 | 46 | ### Explanation 47 | 48 | I will put the explanation to the solution here. The length and depth of the explanation will vary depending on the challenge. 49 | 50 |
51 | 52 | ### Test Cases 53 | 54 | The Jest tests will go here. They are already included in the course files. You just need to run `npm test`. Sometimes I will also put manual tests here. 55 | 56 | ```JS 57 | test("Returning 'Hello, World!' as a string", () => { 58 | const result = helloWorld(); 59 | expect(result).toBe('Hello World!'); 60 | }); 61 | ``` 62 | -------------------------------------------------------------------------------- /01-basic-challenges-1/02-get-sum/get-sum-run.js: -------------------------------------------------------------------------------- 1 | const getSum = require('./get-sum'); 2 | 3 | const result = getSum(1, 10); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /01-basic-challenges-1/02-get-sum/get-sum-solution.js: -------------------------------------------------------------------------------- 1 | function getSum(a, b) { 2 | // return the sum of a and b 3 | return a + b; 4 | } 5 | 6 | module.exports = getSum; 7 | -------------------------------------------------------------------------------- /01-basic-challenges-1/02-get-sum/get-sum-test.js: -------------------------------------------------------------------------------- 1 | const getSum = require('./get-sum'); 2 | 3 | test('Calculating the sum of two numbers', () => { 4 | // Test case inputs 5 | const num1 = 5; 6 | const num2 = 7; 7 | 8 | // Call the function 9 | const result = getSum(num1, num2); 10 | 11 | // Check if the result is equal to the expected sum 12 | expect(result).toBe(12); 13 | }); 14 | -------------------------------------------------------------------------------- /01-basic-challenges-1/02-get-sum/get-sum.js: -------------------------------------------------------------------------------- 1 | function getSum() {} 2 | 3 | module.exports = getSum; 4 | -------------------------------------------------------------------------------- /01-basic-challenges-1/02-get-sum/readme.md: -------------------------------------------------------------------------------- 1 | # Challenge: Get Sum 2 | 3 | This is another very basic practice challenge just to get you into the hang of things. 4 | 5 | ## Instructions 6 | 7 | Write a function called `getSum` that takes in two numbers and returns the sum of those two numbers. 8 | 9 | ### Function Signature 10 | 11 | ```js 12 | /** 13 | * Returns the sum of two numbers. 14 | * @param {number} a - The first number. 15 | * @param {number} b - The second number. 16 | * @returns {number} - The sum of the two numbers. 17 | */ 18 | function getSum(a: number, b: number): number; 19 | ``` 20 | 21 | ### Examples 22 | 23 | ```JS 24 | getSum(1, 2) // 3 25 | getSum(10, 5) // 15 26 | getSum(2, 2) // 4 27 | getSum(10, 5) // 15 28 | ``` 29 | 30 | ### Constraints 31 | 32 | - The function must return a number 33 | 34 | ### Hints 35 | 36 | - You can use the `+` operator to add two numbers together. 37 | 38 | ## Solutions 39 | 40 |
41 | Click For Solution 42 | 43 | ```JS 44 | function getSum(a, b) { 45 | return a + b; 46 | } 47 | ``` 48 | 49 | ### Explanation 50 | 51 | This is a pretty simple challenge. We created a function that takes in two values and we added those two values together. We then returned the sum of those two values. 52 | 53 |
54 | 55 | ### Test Cases 56 | 57 | ```JS 58 | test('Calculating the sum of two numbers', () => { 59 | // Test case inputs 60 | const num1 = 5; 61 | const num2 = 7; 62 | 63 | // Call the function 64 | const result = getSum(num1, num2); 65 | 66 | // Check if the result is equal to the expected sum 67 | expect(result).toBe(12); 68 | }); 69 | ``` 70 | -------------------------------------------------------------------------------- /01-basic-challenges-1/03-calculator/calculator-run.js: -------------------------------------------------------------------------------- 1 | const calculator = require('./calculator'); 2 | 3 | const result = calculator(1, 2, '+'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /01-basic-challenges-1/03-calculator/calculator-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 2 | function calculator(num1, num2, operator) { 3 | // Declare a variable to store the result 4 | let result; 5 | 6 | // Use a switch statement to determine which operation to perform 7 | switch (operator) { 8 | case '+': 9 | result = num1 + num2; 10 | break; // Break out of the switch statement 11 | case '-': 12 | result = num1 - num2; 13 | break; 14 | case '*': 15 | result = num1 * num2; 16 | break; 17 | case '/': 18 | result = num1 / num2; 19 | break; 20 | default: 21 | // If the operator is not one of the above, throw an error 22 | throw new Error('Invalid operator'); 23 | } 24 | 25 | return result; 26 | } 27 | 28 | // Solution 2 29 | function calculator(num1, num2, operator) { 30 | // Declare a variable to store the result 31 | let result; 32 | 33 | // Use if/else if/else statements to determine which operation to perform 34 | if (operator === '+') { 35 | result = num1 + num2; 36 | } else if (operator === '-') { 37 | result = num1 - num2; 38 | } else if (operator === '*') { 39 | result = num1 * num2; 40 | } else if (operator === '/') { 41 | result = num1 / num2; 42 | } else { 43 | // If the operator is not one of the above, throw an error 44 | throw new Error('Invalid operator'); 45 | } 46 | 47 | return result; 48 | } 49 | 50 | module.exports = calculator; 51 | -------------------------------------------------------------------------------- /01-basic-challenges-1/03-calculator/calculator-test.js: -------------------------------------------------------------------------------- 1 | const calculator = require('./calculator'); 2 | 3 | test('Performing arithmetic operations using the calculator function', () => { 4 | // Test case inputs 5 | const num1 = 5; 6 | const num2 = 7; 7 | 8 | // Addition 9 | expect(calculator(num1, num2, '+')).toBe(12); 10 | 11 | // Subtraction 12 | expect(calculator(num1, num2, '-')).toBe(-2); 13 | 14 | // Multiplication 15 | expect(calculator(num1, num2, '*')).toBe(35); 16 | 17 | // Division 18 | expect(calculator(num1, num2, '/')).toBeCloseTo(0.7143, 4); 19 | }); 20 | -------------------------------------------------------------------------------- /01-basic-challenges-1/03-calculator/calculator.js: -------------------------------------------------------------------------------- 1 | function calculator() {} 2 | 3 | module.exports = calculator; 4 | -------------------------------------------------------------------------------- /01-basic-challenges-1/04-count-occurrences/count-occurences-run.js: -------------------------------------------------------------------------------- 1 | const countOccurrences = require('./count-occurrences'); 2 | 3 | const result = countOccurrences('hellLo world', 'l'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /01-basic-challenges-1/04-count-occurrences/count-occurences-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 2 | function countOccurrences(str, char) { 3 | // Declare a variable to store the number of occurrences 4 | let count = 0; 5 | 6 | // Loop through the string 7 | for (let i = 0; i < str.length; i++) { 8 | // If the current character is the same as the character we're looking for, increment the count 9 | if (str[i] === char) { 10 | count++; 11 | } 12 | } 13 | 14 | // Return the number of occurrences 15 | return count; 16 | } 17 | 18 | // Solution 2 19 | const countOccurrences = (str, char) => str.split(char).length - 1; // Split the string on the character and return the length of the resulting array minus 1 20 | 21 | module.exports = countOccurrences; 22 | -------------------------------------------------------------------------------- /01-basic-challenges-1/04-count-occurrences/count-occurrences-test.js: -------------------------------------------------------------------------------- 1 | const countOccurrences = require('./count-occurrences'); 2 | 3 | test('Count Occurrences of a Character', () => { 4 | expect(countOccurrences('hello', 'l')).toBe(2); 5 | expect(countOccurrences('programming', 'm')).toBe(2); 6 | expect(countOccurrences('banana', 'a')).toBe(3); 7 | }); 8 | -------------------------------------------------------------------------------- /01-basic-challenges-1/04-count-occurrences/count-occurrences.js: -------------------------------------------------------------------------------- 1 | function countOccurrences() {} 2 | 3 | module.exports = countOccurrences; 4 | -------------------------------------------------------------------------------- /01-basic-challenges-1/05-find-max-number/find-max-number-run.js: -------------------------------------------------------------------------------- 1 | const findMaxNumber = require('./find-max-number'); 2 | 3 | const result = findMaxNumber([2, 1, 9, 16, 10]); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /01-basic-challenges-1/05-find-max-number/find-max-number-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 - Simplest solution 2 | function findMaxNumber(arr) { 3 | // Math.max() can take any number of arguments, so we can use the spread operator 4 | return Math.max(...arr); 5 | } 6 | 7 | // Solution 2 8 | function findMaxNumber(arr) { 9 | // Declare a variable to store the maximum number. We can initialize it to the first element in the array 10 | let max = arr[0]; 11 | 12 | // Loop through the array starting at the second element. We start at the second element because we already set the maximum number to the first element 13 | for (let i = 1; i < arr.length; i++) { 14 | // If the current element is greater than the maximum number, set the maximum number to the current element 15 | if (arr[i] > max) { 16 | max = arr[i]; 17 | } 18 | } 19 | 20 | // Return the maximum number 21 | return max; 22 | } 23 | 24 | module.exports = findMaxNumber; 25 | -------------------------------------------------------------------------------- /01-basic-challenges-1/05-find-max-number/find-max-number-test.js: -------------------------------------------------------------------------------- 1 | const findMaxNumber = require('./find-max-number'); 2 | 3 | test('Finding the maximum number in an array', () => { 4 | expect(findMaxNumber([1, 5, 3, 9, 2])).toBe(9); 5 | expect(findMaxNumber([0, -1, -5, 2])).toBe(2); 6 | expect(findMaxNumber([10, 10, 10, 10])).toBe(10); 7 | }); 8 | -------------------------------------------------------------------------------- /01-basic-challenges-1/05-find-max-number/find-max-number.js: -------------------------------------------------------------------------------- 1 | function findMaxNumber() {} 2 | 3 | module.exports = findMaxNumber; 4 | -------------------------------------------------------------------------------- /01-basic-challenges-1/06-title-case/title-case-run.js: -------------------------------------------------------------------------------- 1 | const titleCase = require('./title-case'); 2 | 3 | const result = titleCase('the quick brown fox'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /01-basic-challenges-1/06-title-case/title-case-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 - Using a for loop 2 | function titleCase(str) { 3 | // Split the string into an array of words 4 | const words = str.toLowerCase().split(' '); 5 | 6 | // Loop through the array of words 7 | for (let i = 0; i < words.length; i++) { 8 | // Capitalize the first letter of each word 9 | words[i] = words[i][0].toUpperCase() + words[i].slice(1); 10 | } 11 | 12 | // Join the array of words into a string and return it 13 | return words.join(' '); 14 | } 15 | 16 | // Solution 2 - Using a regular expression 17 | function titleCase(str) { 18 | // Replace the first letter of each word with its uppercase equivalent 19 | return str.replace(/\b\w/g, (match) => match.toUpperCase()); 20 | } 21 | 22 | module.exports = titleCase; 23 | -------------------------------------------------------------------------------- /01-basic-challenges-1/06-title-case/title-case-test.js: -------------------------------------------------------------------------------- 1 | const titleCase = require('./title-case'); 2 | 3 | test('Converting string to title case', () => { 4 | expect(titleCase('hello world')).toBe('Hello World'); 5 | expect(titleCase('javascript programming')).toBe('Javascript Programming'); 6 | expect(titleCase('openai chatbot')).toBe('Openai Chatbot'); 7 | }); 8 | -------------------------------------------------------------------------------- /01-basic-challenges-1/06-title-case/title-case.js: -------------------------------------------------------------------------------- 1 | function titleCase() {} 2 | 3 | module.exports = titleCase; 4 | -------------------------------------------------------------------------------- /01-basic-challenges-1/07-reverse-string/reverse-string-run.js: -------------------------------------------------------------------------------- 1 | const reverseString = require('./reverse-string'); 2 | 3 | const result = reverseString('hello world'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /01-basic-challenges-1/07-reverse-string/reverse-string-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 2 | function reverseString(str) { 3 | // Split the string into an array of characters, reverse the array, and join the array into a string 4 | return str.split('').reverse().join(''); 5 | } 6 | 7 | // Solution 2 8 | function reverseString(str) { 9 | // Declare a variable to store the reversed string 10 | let reversed = ''; 11 | 12 | // Loop through the string backwards 13 | for (let i = str.length - 1; i >= 0; i--) { 14 | // Add each character to the reversed string 15 | reversed += str[i]; 16 | } 17 | 18 | // Return the reversed string 19 | return reversed; 20 | } 21 | 22 | module.exports = reverseString; 23 | -------------------------------------------------------------------------------- /01-basic-challenges-1/07-reverse-string/reverse-string-test.js: -------------------------------------------------------------------------------- 1 | const reverseString = require('./reverse-string'); 2 | 3 | test('Reversing a string', () => { 4 | expect(reverseString('Hello')).toBe('olleH'); 5 | expect(reverseString('JavaScript')).toBe('tpircSavaJ'); 6 | expect(reverseString('12345')).toBe('54321'); 7 | }); 8 | -------------------------------------------------------------------------------- /01-basic-challenges-1/07-reverse-string/reverse-string.js: -------------------------------------------------------------------------------- 1 | function reverseString() {} 2 | 3 | module.exports = reverseString; 4 | -------------------------------------------------------------------------------- /01-basic-challenges-1/08-palindrome/palindrome-run.js: -------------------------------------------------------------------------------- 1 | const isPalindrome = require('./palindrome'); 2 | 3 | const result1 = isPalindrome('racecar'); 4 | const result2 = isPalindrome('racecars'); 5 | 6 | console.log(result1, result2); 7 | -------------------------------------------------------------------------------- /01-basic-challenges-1/08-palindrome/palindrome-test.js: -------------------------------------------------------------------------------- 1 | const isPalindrome = require('./palindrome'); 2 | 3 | test('Checking for palindrome strings', () => { 4 | expect(isPalindrome('racecar')).toBe(true); 5 | expect(isPalindrome('Hello')).toBe(false); 6 | expect(isPalindrome('A man, a plan, a canal, Panama')).toBe(true); 7 | expect(isPalindrome('12321')).toBe(true); 8 | }); 9 | -------------------------------------------------------------------------------- /01-basic-challenges-1/08-palindrome/palindrome.js: -------------------------------------------------------------------------------- 1 | function isPalindrome() {} 2 | 3 | module.exports = isPalindrome; 4 | -------------------------------------------------------------------------------- /01-basic-challenges-1/09-count-vowels/count-vowels-run.js: -------------------------------------------------------------------------------- 1 | const countVowels = require('./count-vowels'); 2 | 3 | const result = countVowels('Hello World!'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /01-basic-challenges-1/09-count-vowels/count-vowels-solution.js: -------------------------------------------------------------------------------- 1 | function countVowels(str) { 2 | // Declare a variable to store the formatted string 3 | const formattedStr = str.toLowerCase(); 4 | // Declare a variable to store the number of vowels 5 | let count = 0; 6 | 7 | // Loop through the string 8 | for (let i = 0; i < formattedStr.length; i++) { 9 | // Declare a variable to store the current character 10 | const char = formattedStr[i]; 11 | 12 | // If the current character is a vowel, increment the count 13 | if ( 14 | char === 'a' || 15 | char === 'e' || 16 | char === 'i' || 17 | char === 'o' || 18 | char === 'u' 19 | ) { 20 | count++; 21 | } 22 | } 23 | 24 | // Return the number of vowels 25 | return count; 26 | } 27 | 28 | module.exports = countVowels; 29 | -------------------------------------------------------------------------------- /01-basic-challenges-1/09-count-vowels/count-vowels-test.js: -------------------------------------------------------------------------------- 1 | const countVowels = require('./count-vowels'); 2 | 3 | test('Counting vowels in a string', () => { 4 | expect(countVowels('Hello, World!')).toBe(3); 5 | expect(countVowels('JavaScript')).toBe(3); 6 | expect(countVowels('OpenAI Chatbot')).toBe(6); 7 | expect(countVowels('Coding Challenge')).toBe(5); 8 | }); 9 | -------------------------------------------------------------------------------- /01-basic-challenges-1/09-count-vowels/count-vowels.js: -------------------------------------------------------------------------------- 1 | function countVowels() {} 2 | 3 | module.exports = countVowels; 4 | -------------------------------------------------------------------------------- /01-basic-challenges-1/10-remove-duplicates/remove-duplicates-run.js: -------------------------------------------------------------------------------- 1 | const removeDuplicates = require('./remove-duplicates'); 2 | 3 | const result = removeDuplicates([ 4 | 1, 5 | 2, 6 | 3, 7 | 4, 8 | 5, 9 | 5, 10 | 5, 11 | 6, 12 | 7, 13 | 8, 14 | 'hello', 15 | 'hello', 16 | true, 17 | true, 18 | ]); 19 | 20 | console.log(result); 21 | -------------------------------------------------------------------------------- /01-basic-challenges-1/10-remove-duplicates/remove-duplicates-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 2 | function removeDuplicates(arr) { 3 | // Declare an empty array to store the unique values 4 | const uniqueArr = []; 5 | 6 | // Loop through the array that was passed in 7 | for (let i = 0; i < arr.length; i++) { 8 | // If the current element is not in the unique array, add it 9 | if (!uniqueArr.includes(arr[i])) { 10 | uniqueArr.push(arr[i]); 11 | } 12 | } 13 | 14 | // Return the unique array 15 | return uniqueArr; 16 | } 17 | 18 | // Solution 2 19 | function removeDuplicates(arr) { 20 | // Use the Set object to remove duplicates. This works because Sets only store unique values 21 | return Array.from(new Set(arr)); 22 | } 23 | 24 | module.exports = removeDuplicates; 25 | -------------------------------------------------------------------------------- /01-basic-challenges-1/10-remove-duplicates/remove-duplicates-test.js: -------------------------------------------------------------------------------- 1 | const removeDuplicates = require('./remove-duplicates'); 2 | 3 | test('Removing duplicates from an array', () => { 4 | expect(removeDuplicates([1, 2, 3, 2, 4, 1, 5])).toEqual([1, 2, 3, 4, 5]); 5 | expect( 6 | removeDuplicates(['apple', 'banana', 'orange', 'banana', 'kiwi']) 7 | ).toEqual(['apple', 'banana', 'orange', 'kiwi']); 8 | expect(removeDuplicates([true, true, false, true, false])).toEqual([ 9 | true, 10 | false, 11 | ]); 12 | }); 13 | -------------------------------------------------------------------------------- /01-basic-challenges-1/10-remove-duplicates/remove-duplicates.js: -------------------------------------------------------------------------------- 1 | function removeDuplicates() {} 2 | 3 | module.exports = removeDuplicates; 4 | -------------------------------------------------------------------------------- /02-basic-challenges-2/01-fizzbuzz-array/fizzbuzz-array-run.js: -------------------------------------------------------------------------------- 1 | const fizzBuzzArray = require('./fizzbuzz-array'); 2 | 3 | const result = fizzBuzzArray(15); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /02-basic-challenges-2/01-fizzbuzz-array/fizzbuzz-array-solution.js: -------------------------------------------------------------------------------- 1 | function fizzBuzzArray(num) { 2 | // Create an empty array to store the results 3 | const arr = []; 4 | 5 | // Loop through the numbers from 1 to the number passed in 6 | for (let i = 1; i <= num; i++) { 7 | // If the number is divisible by 3 and 5, add 'FizzBuzz' to the array 8 | if (i % 3 === 0 && i % 5 === 0) { 9 | arr.push('FizzBuzz'); 10 | // If the number is divisible by 3, add 'Fizz' to the array 11 | } else if (i % 3 === 0) { 12 | arr.push('Fizz'); 13 | // If the number is divisible by 5, add 'Buzz' to the array 14 | } else if (i % 5 === 0) { 15 | arr.push('Buzz'); 16 | } else { 17 | // Otherwise, add the number to the array 18 | arr.push(i); 19 | } 20 | } 21 | 22 | return arr; 23 | } 24 | 25 | module.exports = fizzBuzzArray; 26 | -------------------------------------------------------------------------------- /02-basic-challenges-2/01-fizzbuzz-array/fizzbuzz-array-test.js: -------------------------------------------------------------------------------- 1 | const fizzBuzzArray = require('./fizzbuzz-array'); 2 | 3 | test('FizzBuzz Array', () => { 4 | expect(fizzBuzzArray(15)).toEqual([ 5 | 1, 6 | 2, 7 | 'Fizz', 8 | 4, 9 | 'Buzz', 10 | 'Fizz', 11 | 7, 12 | 8, 13 | 'Fizz', 14 | 'Buzz', 15 | 11, 16 | 'Fizz', 17 | 13, 18 | 14, 19 | 'FizzBuzz', 20 | ]); 21 | }); 22 | -------------------------------------------------------------------------------- /02-basic-challenges-2/01-fizzbuzz-array/fizzbuzz-array.js: -------------------------------------------------------------------------------- 1 | function fizzBuzzArray() {} 2 | 3 | module.exports = fizzBuzzArray; 4 | -------------------------------------------------------------------------------- /02-basic-challenges-2/02-array-intersection/array-intersection-run.js: -------------------------------------------------------------------------------- 1 | const arrayIntersection = require('./array-intersection'); 2 | 3 | const result = arrayIntersection([1, 2, 3, 4, 5], [3, 4, 5, 6, 7]); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /02-basic-challenges-2/02-array-intersection/array-intersection-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 2 | function arrayIntersection(arr1, arr2) { 3 | // Declare an empty array to store the intersection 4 | const intersection = []; 5 | 6 | // Loop through arr1 7 | for (let i = 0; i < arr1.length; i++) { 8 | // If the current element is in arr2 and not already in the intersection array, add it 9 | if (arr2.includes(arr1[i]) && !intersection.includes(arr1[i])) { 10 | intersection.push(arr1[i]); 11 | } 12 | } 13 | 14 | return intersection; 15 | } 16 | 17 | // Solution 2 18 | function arrayIntersection(arr1, arr2) { 19 | // Create a set from arr1 20 | const set1 = new Set(arr1); 21 | // Declare an empty array to store the intersection 22 | const intersection = []; 23 | 24 | // Loop through arr2 25 | for (let num of arr2) { 26 | // If the current number is in set1, add it to the intersection array 27 | if (set1.has(num)) { 28 | intersection.push(num); 29 | } 30 | } 31 | 32 | return intersection; 33 | } 34 | 35 | module.exports = arrayIntersection; 36 | -------------------------------------------------------------------------------- /02-basic-challenges-2/02-array-intersection/array-intersection-test.js: -------------------------------------------------------------------------------- 1 | const arrayIntersection = require('./array-intersection'); 2 | 3 | test('Finding array intersection', () => { 4 | expect(arrayIntersection([1, 2, 3, 4, 5], [3, 4, 5, 6, 7])).toEqual([ 5 | 3, 4, 5, 6 | ]); 7 | expect(arrayIntersection([10, 20, 30], [30, 40, 50])).toEqual([30]); 8 | expect(arrayIntersection([1, 2, 3], [4, 5, 6])).toEqual([]); 9 | }); 10 | -------------------------------------------------------------------------------- /02-basic-challenges-2/02-array-intersection/array-intersection.js: -------------------------------------------------------------------------------- 1 | function arrayIntersection() {} 2 | 3 | module.exports = arrayIntersection; 4 | -------------------------------------------------------------------------------- /02-basic-challenges-2/03-display-likes/display-likes-run.js: -------------------------------------------------------------------------------- 1 | const displayLikes = require('./display-likes'); 2 | 3 | const result = displayLikes(['Alex', 'Jacob', 'Mark', 'Max', 'Jill']); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /02-basic-challenges-2/03-display-likes/display-likes-solution.js: -------------------------------------------------------------------------------- 1 | function displayLikes(names) { 2 | // Get the length of the array 3 | const length = names.length; 4 | 5 | // Return the appropriate string based on the length of the array 6 | if (length === 0) { 7 | return 'no one likes this'; 8 | } else if (length === 1) { 9 | return `${names[0]} likes this`; 10 | } else if (length === 2) { 11 | return `${names[0]} and ${names[1]} like this`; 12 | } else if (length === 3) { 13 | return `${names[0]}, ${names[1]} and ${names[2]} like this`; 14 | } else { 15 | return `${names[0]}, ${names[1]} and ${length - 2} others like this`; 16 | } 17 | } 18 | 19 | module.exports = displayLikes; 20 | -------------------------------------------------------------------------------- /02-basic-challenges-2/03-display-likes/display-likes-test.js: -------------------------------------------------------------------------------- 1 | const displayLikes = require('./display-likes'); 2 | 3 | test('Display Likes', () => { 4 | expect(displayLikes([])).toEqual('no one likes this'); 5 | expect(displayLikes(['Peter'])).toEqual('Peter likes this'); 6 | expect(displayLikes(['Jacob', 'Alex'])).toEqual('Jacob and Alex like this'); 7 | expect(displayLikes(['Max', 'John', 'Mark'])).toEqual( 8 | 'Max, John and Mark like this' 9 | ); 10 | expect(displayLikes(['Alex', 'Jacob', 'Mark', 'Max'])).toEqual( 11 | 'Alex, Jacob and 2 others like this' 12 | ); 13 | expect(displayLikes(['Alex', 'Jacob', 'Mark', 'Max', 'Jill'])).toEqual( 14 | 'Alex, Jacob and 3 others like this' 15 | ); 16 | }); 17 | -------------------------------------------------------------------------------- /02-basic-challenges-2/03-display-likes/display-likes.js: -------------------------------------------------------------------------------- 1 | function displayLikes() {} 2 | 3 | module.exports = displayLikes; 4 | -------------------------------------------------------------------------------- /02-basic-challenges-2/04-find-missing-number/find-missing-number-run.js: -------------------------------------------------------------------------------- 1 | const findMissingNumber = require('./find-missing-number'); 2 | 3 | const result = findMissingNumber([10, 8, 6, 7, 5, 4, 2, 3, 1]); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /02-basic-challenges-2/04-find-missing-number/find-missing-number-solution.js: -------------------------------------------------------------------------------- 1 | function findMissingNumber(arr) { 2 | // If the array is empty or undefined, return undefined 3 | if (!arr || arr.length === 0) { 4 | return undefined; 5 | } 6 | // Add 1 to the length of the array to account for the missing number 7 | const n = arr.length + 1; 8 | // Calculate the expected sum of the numbers from 1 to n 9 | const expectedSum = (n * (n + 1)) / 2; 10 | // Calculate the actual sum of the numbers in the array 11 | const actualSum = arr.reduce((sum, num) => sum + num, 0); 12 | // Return the difference between the expected sum and the actual sum 13 | return expectedSum - actualSum; 14 | } 15 | 16 | module.exports = findMissingNumber; 17 | -------------------------------------------------------------------------------- /02-basic-challenges-2/04-find-missing-number/find-missing-number-test.js: -------------------------------------------------------------------------------- 1 | const findMissingNumber = require('./find-missing-number'); 2 | 3 | test('Finding the missing number', () => { 4 | expect(findMissingNumber([1, 2, 3, 5])).toBe(4); 5 | expect(findMissingNumber([10, 8, 6, 7, 5, 4, 2, 3, 1])).toBe(9); 6 | expect(findMissingNumber([1, 3, 4, 5, 6])).toBe(2); 7 | }); 8 | -------------------------------------------------------------------------------- /02-basic-challenges-2/04-find-missing-number/find-missing-number.js: -------------------------------------------------------------------------------- 1 | function findMissingNumber() {} 2 | 3 | module.exports = findMissingNumber; 4 | -------------------------------------------------------------------------------- /02-basic-challenges-2/05-find-missing-letter/find-missing-letter-run.js: -------------------------------------------------------------------------------- 1 | const findMissingLetter = require('./find-missing-letter'); 2 | 3 | result = findMissingLetter(['a', 'b', 'c', 'd', 'f', 'g']); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /02-basic-challenges-2/05-find-missing-letter/find-missing-letter-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 2 | function findMissingLetter(arr) { 3 | // Create a string of the alphabet 4 | const alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 5 | // Find the index of the first letter in the array in the alphabet string 6 | const startIndex = alphabet.indexOf(arr[0]); 7 | 8 | // Loop through the array 9 | for (let i = 0; i < arr.length; i++) { 10 | // If the current letter in the array is not the same as the current letter in the alphabet string, return the current letter in the alphabet string 11 | if (arr[i] !== alphabet[startIndex + i]) { 12 | return alphabet[startIndex + i]; 13 | } 14 | } 15 | 16 | // If no letter is missing, return an empty string 17 | return ''; 18 | } 19 | 20 | // Solution 2 21 | function findMissingLetter(arr) { 22 | // Find the char code of the first letter in the array 23 | let start = arr[0].charCodeAt(0); 24 | // Loop through the array 25 | for (let i = 1; i < arr.length; i++) { 26 | // Find the char code of the current letter in the array 27 | const current = arr[i].charCodeAt(0); 28 | // If the difference between the current char code and the start char code is greater than 1, return the letter that is missing 29 | if (current - start > 1) { 30 | // Convert the char code to a letter 31 | return String.fromCharCode(start + 1); 32 | } 33 | // Update the start char code 34 | start = current; 35 | } 36 | // If no letter is missing, return an empty string 37 | return ''; 38 | } 39 | 40 | module.exports = findMissingLetter; 41 | -------------------------------------------------------------------------------- /02-basic-challenges-2/05-find-missing-letter/find-missing-letter-test.js: -------------------------------------------------------------------------------- 1 | const findMissingLetter = require('./find-missing-letter'); 2 | 3 | test('Find Missing Letter', () => { 4 | expect(findMissingLetter(['a', 'b', 'c', 'e'])).toBe('d'); 5 | expect(findMissingLetter(['X', 'Z'])).toBe('Y'); 6 | expect(findMissingLetter(['m', 'n', 'o', 'q', 'r'])).toBe('p'); 7 | expect(findMissingLetter(['F', 'G', 'H', 'J'])).toBe('I'); 8 | }); 9 | -------------------------------------------------------------------------------- /02-basic-challenges-2/05-find-missing-letter/find-missing-letter.js: -------------------------------------------------------------------------------- 1 | function findMissingLetter() {} 2 | 3 | module.exports = findMissingLetter; 4 | -------------------------------------------------------------------------------- /02-basic-challenges-2/06-are-all-chars-unique/are-all-chars-unique-run.js: -------------------------------------------------------------------------------- 1 | const areAllCharactersUnique = require('./are-all-chars-unique'); 2 | 3 | const result1 = areAllCharactersUnique('abcdefg'); 4 | const result2 = areAllCharactersUnique('abcdefgA'); 5 | const result3 = areAllCharactersUnique('programming'); 6 | 7 | console.log(result1); 8 | console.log(result2); 9 | console.log(result3); 10 | -------------------------------------------------------------------------------- /02-basic-challenges-2/06-are-all-chars-unique/are-all-chars-unique-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 2 | function areAllCharactersUnique(str) { 3 | // Create a new set 4 | const charSet = new Set(); 5 | 6 | // Loop through the string 7 | for (let i = 0; i < str.length; i++) { 8 | // Get the current character 9 | const char = str[i]; 10 | // If the set already has the current character, return false 11 | if (charSet.has(char)) { 12 | return false; 13 | } 14 | // Add the current character to the set 15 | charSet.add(char); 16 | } 17 | 18 | // If no characters are repeated, return true 19 | return true; 20 | } 21 | 22 | // Solution 2 23 | function areAllCharactersUnique(str) { 24 | // Create an object to keep track of the characters in the string 25 | const charCount = {}; 26 | 27 | // Loop through the string 28 | for (let i = 0; i < str.length; i++) { 29 | // Get the current character 30 | const char = str[i]; 31 | // If the character is already in the object, return false 32 | if (charCount[char]) { 33 | return false; 34 | } 35 | // Add the current character to the object 36 | charCount[char] = true; 37 | } 38 | 39 | // If no characters are repeated, return true 40 | return true; 41 | } 42 | 43 | module.exports = areAllCharactersUnique; 44 | -------------------------------------------------------------------------------- /02-basic-challenges-2/06-are-all-chars-unique/are-all-chars-unique-test.js: -------------------------------------------------------------------------------- 1 | const areAllCharactersUnique = require('./are-all-chars-unique'); 2 | 3 | test('Unique Characters in a String', () => { 4 | expect(areAllCharactersUnique('abcdefg')).toBe(true); 5 | expect(areAllCharactersUnique('abcdefgA')).toBe(true); 6 | expect(areAllCharactersUnique('programming')).toBe(false); 7 | expect(areAllCharactersUnique('')).toBe(true); 8 | expect(areAllCharactersUnique('a')).toBe(true); 9 | }); 10 | -------------------------------------------------------------------------------- /02-basic-challenges-2/06-are-all-chars-unique/are-all-chars-unique.js: -------------------------------------------------------------------------------- 1 | function areAllCharactersUnique() {} 2 | 3 | module.exports = areAllCharactersUnique; 4 | -------------------------------------------------------------------------------- /02-basic-challenges-2/07-first-non-repeating/first-non-repeating-run.js: -------------------------------------------------------------------------------- 1 | const findFirstNonRepeatingCharacter = require('./first-non-repeating'); 2 | 3 | const result1 = findFirstNonRepeatingCharacter('programming'); 4 | const result2 = findFirstNonRepeatingCharacter('abacddbec'); 5 | 6 | console.log(result1); 7 | console.log(result2); 8 | -------------------------------------------------------------------------------- /02-basic-challenges-2/07-first-non-repeating/first-non-repeating-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 2 | function findFirstNonRepeatingCharacter(str) { 3 | const charCount = {}; 4 | 5 | // Count the occurrences of each character 6 | for (const char of str) { 7 | charCount[char] = (charCount[char] || 0) + 1; 8 | } 9 | 10 | // Find the first non-repeating character 11 | for (const char of str) { 12 | if (charCount[char] === 1) { 13 | return char; 14 | } 15 | } 16 | 17 | // If no non-repeating character is found, return null 18 | return null; 19 | } 20 | 21 | // Solution 2 22 | function findFirstNonRepeatingCharacter(str) { 23 | // Create a new map 24 | const charCount = new Map(); 25 | 26 | // Loop through the string 27 | for (const char of str) { 28 | // If the map already has the current character, increment the count 29 | charCount.set(char, (charCount.get(char) || 0) + 1); 30 | } 31 | 32 | // Loop through the string 33 | for (const char of str) { 34 | // If the count of the current character is 1, return the current character 35 | if (charCount.get(char) === 1) { 36 | return char; 37 | } 38 | } 39 | 40 | // If no characters are repeated, return null 41 | return null; 42 | } 43 | 44 | module.exports = findFirstNonRepeatingCharacter; 45 | -------------------------------------------------------------------------------- /02-basic-challenges-2/07-first-non-repeating/first-non-repeating-test.js: -------------------------------------------------------------------------------- 1 | const findFirstNonRepeatingCharacter = require('./first-non-repeating'); 2 | 3 | test('Find First Non-Repeating Character', () => { 4 | expect(findFirstNonRepeatingCharacter('aabccdeff')).toBe('b'); 5 | expect(findFirstNonRepeatingCharacter('aabbcc')).toBe(null); 6 | expect(findFirstNonRepeatingCharacter('hello world')).toBe('h'); 7 | }); 8 | -------------------------------------------------------------------------------- /02-basic-challenges-2/07-first-non-repeating/first-non-repeating.js: -------------------------------------------------------------------------------- 1 | function findFirstNonRepeatingCharacter() {} 2 | 3 | module.exports = findFirstNonRepeatingCharacter; 4 | -------------------------------------------------------------------------------- /02-basic-challenges-2/08-dice-game/dice-game-run.js: -------------------------------------------------------------------------------- 1 | const diceGameSimulation = require('./dice-game'); 2 | 3 | const result = diceGameSimulation(10); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /02-basic-challenges-2/08-dice-game/dice-game-solution.js: -------------------------------------------------------------------------------- 1 | // Function to simulate rolling a 6-sided die and returning a random number between 1 and 6 2 | function rollDice() { 3 | return Math.floor(Math.random() * 6) + 1; 4 | } 5 | 6 | // Function to simulate the dice game for a specified number of simulations 7 | function diceGameSimulation(numSimulations) { 8 | const results = []; // Initialize an array to store simulation results 9 | 10 | // Loop through the specified number of simulations 11 | for (let i = 0; i < numSimulations; i++) { 12 | const dice1 = rollDice(); // Simulate the roll of the first dice 13 | const dice2 = rollDice(); // Simulate the roll of the second dice 14 | const sum = dice1 + dice2; // Calculate the sum of the dice values 15 | 16 | let result = ''; // Initialize a variable to store the result of the current simulation 17 | 18 | // Check if the sum of the dice values is 7 or 11 19 | if (sum === 7 || sum === 11) { 20 | result = 'win'; // Set the result to 'win' if the sum is 7 or 11 21 | } else if (sum === 2 || sum === 3 || sum === 12) { 22 | result = 'lose'; // Set the result to 'lose' if the sum is 2, 3, or 12 23 | } else { 24 | result = 'roll again'; // Set the result to 'roll again' for any other sum 25 | } 26 | 27 | // Add the simulation result to the results array 28 | results.push({ dice1, dice2, sum, result }); 29 | } 30 | 31 | return results; // Return the array of simulation results 32 | } 33 | 34 | module.exports = diceGameSimulation; // Export the diceGameSimulation function 35 | ``; 36 | -------------------------------------------------------------------------------- /02-basic-challenges-2/08-dice-game/dice-game-test.js: -------------------------------------------------------------------------------- 1 | const diceGameSimulation = require('./dice-game'); 2 | 3 | describe('diceGameSimulation', () => { 4 | test('should simulate the dice game correctly', () => { 5 | const numSimulations = 100; 6 | const simulationResults = diceGameSimulation(numSimulations); 7 | 8 | expect(simulationResults).toHaveLength(numSimulations); 9 | 10 | simulationResults.forEach((result) => { 11 | const { dice1, dice2, sum, result: gameResult } = result; 12 | 13 | expect(dice1).toBeGreaterThanOrEqual(1); 14 | expect(dice1).toBeLessThanOrEqual(6); 15 | 16 | expect(dice2).toBeGreaterThanOrEqual(1); 17 | expect(dice2).toBeLessThanOrEqual(6); 18 | 19 | expect(sum).toBeGreaterThanOrEqual(2); 20 | expect(sum).toBeLessThanOrEqual(12); 21 | 22 | if (sum === 7 || sum === 11) { 23 | expect(gameResult).toBe('win'); 24 | } else if (sum === 2 || sum === 3 || sum === 12) { 25 | expect(gameResult).toBe('lose'); 26 | } else { 27 | expect(gameResult).toBe('roll again'); 28 | } 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /02-basic-challenges-2/08-dice-game/dice-game.js: -------------------------------------------------------------------------------- 1 | function diceGameSimulation() {} 2 | 3 | module.exports = diceGameSimulation; 4 | -------------------------------------------------------------------------------- /02-basic-challenges-2/09-format-phone-number/format-phone-number-run.js: -------------------------------------------------------------------------------- 1 | const formatPhoneNumber = require('./format-phone-number'); 2 | 3 | const result = formatPhoneNumber([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /02-basic-challenges-2/09-format-phone-number/format-phone-number-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 2 | function formatPhoneNumber(numbers) { 3 | // Get the first 3 numbers and join them together 4 | const areaCode = numbers.slice(0, 3).join(''); 5 | // Get the next 3 numbers and join them together 6 | const prefix = numbers.slice(3, 6).join(''); 7 | // Get the last 4 numbers and join them together 8 | const lineNumber = numbers.slice(6).join(''); 9 | 10 | // Return the formatted phone number 11 | return `(${areaCode}) ${prefix}-${lineNumber}`; 12 | } 13 | 14 | // Solution 2 15 | function formatPhoneNumber(numbers) { 16 | // Join all the numbers together 17 | const formatted = numbers.join(''); 18 | // Return the formatted phone number 19 | return `(${formatted.substring(0, 3)}) ${formatted.substring( 20 | 3, 21 | 6 22 | )}-${formatted.substring(6)}`; 23 | } 24 | 25 | // Solution 3 26 | // Arrow function with implicit return 27 | const formatPhoneNumber = (numbers) => 28 | `(${numbers.slice(0, 3).join('')}) ${numbers.slice(3, 6).join('')}-${numbers 29 | .slice(6) 30 | .join('')}`; 31 | 32 | module.exports = formatPhoneNumber; 33 | -------------------------------------------------------------------------------- /02-basic-challenges-2/09-format-phone-number/format-phone-number-test.js: -------------------------------------------------------------------------------- 1 | const formatPhoneNumber = require('./format-phone-number'); 2 | 3 | test('Format Phone Number', () => { 4 | expect(formatPhoneNumber([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])).toBe( 5 | '(123) 456-7890' 6 | ); 7 | expect(formatPhoneNumber([5, 0, 2, 4, 8, 1, 9, 6, 3, 7])).toBe( 8 | '(502) 481-9637' 9 | ); 10 | expect(formatPhoneNumber([9, 9, 9, 9, 9, 9, 9, 9, 9, 9])).toBe( 11 | '(999) 999-9999' 12 | ); 13 | }); 14 | -------------------------------------------------------------------------------- /02-basic-challenges-2/09-format-phone-number/format-phone-number.js: -------------------------------------------------------------------------------- 1 | function formatPhoneNumber() {} 2 | 3 | module.exports = formatPhoneNumber; 4 | -------------------------------------------------------------------------------- /02-basic-challenges-2/10-validate-email/validate-email-run.js: -------------------------------------------------------------------------------- 1 | const validateEmail = require('./validate-email'); 2 | 3 | const result1 = validateEmail('brad@gmail.com'); 4 | const result2 = validateEmail('bradgmailcom'); 5 | 6 | console.log(result1); 7 | console.log(result2); 8 | -------------------------------------------------------------------------------- /02-basic-challenges-2/10-validate-email/validate-email-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 2 | function validateEmail(email) { 3 | // Create a regular expression to match the email format 4 | const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/; 5 | // Return whether the email matches the regular expression 6 | return emailRegex.test(email); 7 | } 8 | 9 | // Solution 2 10 | function validateEmail(email) { 11 | // Check if the email contains the "@" symbol 12 | if (email.indexOf('@') === -1) { 13 | return false; 14 | } 15 | 16 | // Split the email into the local part and domain 17 | const [localPart, domain] = email.split('@'); 18 | 19 | // Check if the local part and domain meet the minimum length requirements 20 | if (localPart.length === 0 || domain.length < 3) { 21 | return false; 22 | } 23 | 24 | // Check if the domain extension consists of at least two characters 25 | const domainExtension = domain.split('.'); 26 | if ( 27 | domainExtension.length < 2 || 28 | domainExtension[1].length < 2 29 | ) { 30 | return false; 31 | } 32 | 33 | // If all checks pass, return true 34 | return true; 35 | } 36 | 37 | module.exports = validateEmail; 38 | -------------------------------------------------------------------------------- /02-basic-challenges-2/10-validate-email/validate-email-test.js: -------------------------------------------------------------------------------- 1 | const validateEmail = require('./validate-email'); 2 | 3 | test('Valid Email Addresses', () => { 4 | expect(validateEmail('john@example.com')).toBe(true); 5 | expect(validateEmail('jane.doe@domain.org')).toBe(true); 6 | }); 7 | 8 | test('Invalid Email Addresses', () => { 9 | expect(validateEmail('invalid-email')).toBe(false); 10 | expect(validateEmail('@domain.com')).toBe(false); 11 | expect(validateEmail('user@domain')).toBe(false); 12 | }); 13 | -------------------------------------------------------------------------------- /02-basic-challenges-2/10-validate-email/validate-email.js: -------------------------------------------------------------------------------- 1 | function validateEmail() {} 2 | 3 | module.exports = validateEmail; 4 | -------------------------------------------------------------------------------- /03-high-order-array-methods/01-simple-examples/simple-examples-done.js: -------------------------------------------------------------------------------- 1 | const numbers = [1, 2, 3, 4, 5]; 2 | 3 | /** 4 | * map: Transforms array elements with a provided function, creating a new array. 5 | */ 6 | const doubledNumbers = numbers.map((num) => num * 2); 7 | 8 | // console.log(doubledNumbers); 9 | 10 | /** 11 | * filter: Creates a new array with elements that satisfy a specified condition. 12 | */ 13 | 14 | const evenNumbers = numbers.filter((num) => num > 2); 15 | 16 | // console.log(evenNumbers); 17 | 18 | /** 19 | * reduce: Accumulates array elements into a single value using a provided function. 20 | */ 21 | 22 | const sum = numbers.reduce((total, num) => total + num, 0); 23 | 24 | // console.log(sum); 25 | 26 | /** 27 | * forEach: Iterates through array elements and applies a function without creating a new array. 28 | */ 29 | 30 | // numbers.forEach((num) => console.log(num)); 31 | 32 | /** 33 | * find: Returns the first array element that satisfies a specified condition. 34 | */ 35 | 36 | const foundNumber = numbers.find((num) => num > 2); 37 | 38 | // console.log(foundNumber); 39 | 40 | /** 41 | * some: Checks if at least one array element satisfies a condition. 42 | */ 43 | 44 | const hasEvenNumber = numbers.some((num) => num > 5); 45 | 46 | // console.log(hasEvenNumber); 47 | 48 | /** 49 | * every: Checks if all array elements satisfy a condition. 50 | */ 51 | 52 | const allNumsGreaterThanZero = numbers.every((num) => num > 0); 53 | 54 | console.log(allNumsGreaterThanZero); 55 | -------------------------------------------------------------------------------- /03-high-order-array-methods/01-simple-examples/simple-examples.js: -------------------------------------------------------------------------------- 1 | const numbers = [1, 2, 3, 4, 5]; 2 | 3 | /** 4 | * map: Transforms array elements with a provided function, creating a new array. 5 | */ 6 | 7 | 8 | /** 9 | * filter: Creates a new array with elements that satisfy a specified condition. 10 | */ 11 | 12 | 13 | 14 | /** 15 | * reduce: Accumulates array elements into a single value using a provided function. 16 | */ 17 | 18 | 19 | 20 | /** 21 | * forEach: Iterates through array elements and applies a function without creating a new array. 22 | */ 23 | 24 | 25 | 26 | /** 27 | * find: Returns the first array element that satisfies a specified condition. 28 | */ 29 | 30 | 31 | /** 32 | * some: Checks if at least one array element satisfies a condition. 33 | */ 34 | 35 | 36 | 37 | /** 38 | * every: Checks if all array elements satisfy a condition. 39 | */ 40 | 41 | 42 | -------------------------------------------------------------------------------- /03-high-order-array-methods/02-sum-of-even-squares/sum-of-even-squares-run.js: -------------------------------------------------------------------------------- 1 | const sumOfEvenSquares = require('./sum-of-even-squares'); 2 | 3 | const result = sumOfEvenSquares([1, 2, 3, 4, 5, 6]); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /03-high-order-array-methods/02-sum-of-even-squares/sum-of-even-squares-solution.js: -------------------------------------------------------------------------------- 1 | function sumOfEvenSquares(numbers) { 2 | // Filter out the even numbers from the input array. 3 | const evenSquares = numbers 4 | .filter((num) => num % 2 === 0) 5 | // Square each even number. 6 | .map((num) => num ** 2) 7 | // Accumulate the squared numbers to compute the sum. 8 | .reduce((sum, square) => sum + square, 0); 9 | 10 | // Return the sum of squares of even numbers. 11 | return evenSquares; 12 | } -------------------------------------------------------------------------------- /03-high-order-array-methods/02-sum-of-even-squares/sum-of-even-squares-test.js: -------------------------------------------------------------------------------- 1 | const sumOfEvenSquares = require('./sum-of-even-squares'); 2 | 3 | test('Sum of even squares', () => { 4 | expect(sumOfEvenSquares([1, 2, 3, 4, 5])).toBe(20); 5 | expect(sumOfEvenSquares([-1, 0, 1, 2, 3, 4])).toBe(20); 6 | expect(sumOfEvenSquares([])).toBe(0); 7 | }); 8 | -------------------------------------------------------------------------------- /03-high-order-array-methods/02-sum-of-even-squares/sum-of-even-squares.js: -------------------------------------------------------------------------------- 1 | function sumOfEvenSquares() {} 2 | 3 | module.exports = sumOfEvenSquares; 4 | -------------------------------------------------------------------------------- /03-high-order-array-methods/03-calculate-total-sales/calculate-total-sales-run.js: -------------------------------------------------------------------------------- 1 | const calculateTotalSalesWithTax = require('./calculate-total-sales.js'); 2 | 3 | const products = [ 4 | { name: 'Apple', price: 0.5, quantity: 10 }, 5 | { name: 'Banana', price: 0.3, quantity: 20 }, 6 | { name: 'Orange', price: 0.6, quantity: 15 }, 7 | ]; 8 | 9 | const result = calculateTotalSalesWithTax(products, 8); 10 | 11 | console.log(result); 12 | -------------------------------------------------------------------------------- /03-high-order-array-methods/03-calculate-total-sales/calculate-total-sales-solution.js: -------------------------------------------------------------------------------- 1 | function calculateTotalSalesWithTax(products, taxRate) { 2 | // Calculate total sales amount using the product price and quantity using the reduce method 3 | const totalSales = products.reduce( 4 | (sum, product) => sum + product.price * product.quantity, 5 | 0 6 | ); 7 | // Calculate the tax amount using the total sales amount and the tax rate 8 | const taxAmount = (totalSales * taxRate) / 100; 9 | // Calculate the total sales amount with tax 10 | const totalSalesWithTax = totalSales + taxAmount; 11 | // Return the total sales amount with tax rounded to 2 decimal places 12 | return parseFloat(totalSalesWithTax.toFixed(2)); 13 | } 14 | 15 | module.exports = calculateTotalSalesWithTax; 16 | -------------------------------------------------------------------------------- /03-high-order-array-methods/03-calculate-total-sales/calculate-total-sales-test.js: -------------------------------------------------------------------------------- 1 | const calculateTotalSalesWithTax = require("./calculate-total-sales"); 2 | 3 | test("Calculating total sales amount with tax", () => { 4 | expect( 5 | calculateTotalSalesWithTax( 6 | [ 7 | { name: "Apple", price: 0.5, quantity: 10 }, 8 | { name: "Banana", price: 0.3, quantity: 20 }, 9 | { name: "Orange", price: 0.6, quantity: 15 }, 10 | ], 11 | 8 12 | ) 13 | ).toBe(21.6); 14 | 15 | expect( 16 | calculateTotalSalesWithTax( 17 | [ 18 | { name: "Chocolate", price: 2.5, quantity: 5 }, 19 | { name: "Chips", price: 1.2, quantity: 10 }, 20 | { name: "Soda", price: 1.0, quantity: 8 }, 21 | { name: "Candy", price: 0.5, quantity: 15 }, 22 | ], 23 | 5 24 | ) 25 | ).toBe(42); 26 | }); 27 | -------------------------------------------------------------------------------- /03-high-order-array-methods/03-calculate-total-sales/calculate-total-sales.js: -------------------------------------------------------------------------------- 1 | function calculateTotalSalesWithTax() {} 2 | 3 | module.exports = calculateTotalSalesWithTax; 4 | -------------------------------------------------------------------------------- /03-high-order-array-methods/04-highest-scoring-word/highest-scoring-word-run.js: -------------------------------------------------------------------------------- 1 | const highestScoringWord = require('./highest-scoring-word'); 2 | 3 | const result = highestScoringWord('Hello my name is xavier'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /03-high-order-array-methods/04-highest-scoring-word/highest-scoring-word-test.js: -------------------------------------------------------------------------------- 1 | const highestScoringWord = require('./highest-scoring-word'); 2 | 3 | test('Finding the highest scoring word', () => { 4 | expect(highestScoringWord('hello my name is xavier')).toBe('xavier'); 5 | expect(highestScoringWord('what time are we climbing up the volcano')).toBe( 6 | 'volcano' 7 | ); 8 | expect(highestScoringWord('take me to semynak')).toBe('semynak'); 9 | }); 10 | -------------------------------------------------------------------------------- /03-high-order-array-methods/04-highest-scoring-word/highest-scoring-word.js: -------------------------------------------------------------------------------- 1 | function highestScoringWord() {} 2 | 3 | module.exports = highestScoringWord; 4 | -------------------------------------------------------------------------------- /03-high-order-array-methods/05-valid-anagrams/valid-anagrams-run.js: -------------------------------------------------------------------------------- 1 | const validAnagrams = require('./valid-anagrams'); 2 | 3 | const result = validAnagrams('app', 'ppa'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /03-high-order-array-methods/05-valid-anagrams/valid-anagrams-solution.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Checks if two strings are valid anagrams of each other. 3 | * 4 | * @param {string} str1 - The first input string. 5 | * @param {string} str2 - The second input string. 6 | * @returns {boolean} - True if the strings are valid anagrams, false otherwise. 7 | */ 8 | function validAnagrams(str1, str2) { 9 | // Split the strings into arrays of characters, then reduce each array into an object of character frequencies for the first string 10 | const freqCount1 = str1.split('').reduce((acc, char) => { 11 | // Increment the frequency of the character or initialize it to 1 if not present 12 | acc[char] = (acc[char] || 0) + 1; 13 | return acc; 14 | }, {}); 15 | 16 | // Split the strings into arrays of characters, then reduce each array into an object of character frequencies for the second string 17 | const freqCount2 = str2.split('').reduce((acc, char) => { 18 | // Increment the frequency of the character or initialize it to 1 if not present 19 | acc[char] = (acc[char] || 0) + 1; 20 | return acc; 21 | }, {}); 22 | 23 | // Compare the two objects of character frequencies by checking if the frequency of each character in the first object is equal to the frequency of the same character in the second object 24 | return Object.keys(freqCount1).every( 25 | (char) => freqCount1[char] === freqCount2[char] 26 | ) && Object.keys(freqCount2).every( 27 | (char) => freqCount1[char] === freqCount2[char] 28 | ); 29 | } 30 | 31 | // Example usage: 32 | const result = validAnagrams('listen', 'silent'); 33 | console.log(result); // Output: true 34 | -------------------------------------------------------------------------------- /03-high-order-array-methods/05-valid-anagrams/valid-anagrams-test.js: -------------------------------------------------------------------------------- 1 | const validAnagrams = require('./valid-anagrams'); 2 | 3 | test('Checking for Valid Anagrams', () => { 4 | expect(validAnagrams('listen', 'silent')).toBe(true); 5 | expect(validAnagrams('hello', 'world')).toBe(false); 6 | expect(validAnagrams('astronomer', 'moonstarer')).toBe(true); 7 | expect(validAnagrams('apple', 'banana')).toBe(false); 8 | expect(validAnagrams('aaa', 'aaab')).toBe(false); 9 | }); 10 | -------------------------------------------------------------------------------- /03-high-order-array-methods/05-valid-anagrams/valid-anagrams.js: -------------------------------------------------------------------------------- 1 | function validAnagrams() {} 2 | 3 | module.exports = validAnagrams; 4 | -------------------------------------------------------------------------------- /03-high-order-array-methods/06-hashtag-generator/hashtag-generator-run.js: -------------------------------------------------------------------------------- 1 | const generateHashtag = require('./hashtag-generator'); 2 | 3 | const result = generateHashtag('hello world'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /03-high-order-array-methods/06-hashtag-generator/hashtag-generator-solution.js: -------------------------------------------------------------------------------- 1 | function generateHashtag(str) { 2 | // If the string is empty or contains only whitespace characters, return false. 3 | if (str.trim() === '') { 4 | return false; 5 | } 6 | 7 | // Split the string into an array of words. 8 | const words = str.trim().split(/\s+/); 9 | // Return a new array with the first letter of each word capitalized. 10 | const capitalizedWords = words.map( 11 | (word) => word.charAt(0).toUpperCase() + word.slice(1) 12 | ); 13 | 14 | // Join the words together into a string, prefixed with a hash. 15 | const hashtag = '#' + capitalizedWords.join(''); 16 | 17 | // If the hashtag is longer than 140 characters, return false, otherwise return the hashtag. 18 | return hashtag.length > 140 ? false : hashtag; 19 | } 20 | 21 | // Solution 2 22 | function generateHashtag(str) { 23 | // Split the string into an array of words. Use reduce to build the hashtag by passing in `#` as the initial value and then concatenating the first letter of each word capitalized and the rest of the word. 24 | const hashtag = str.split(' ').reduce(function (tag, word) { 25 | return tag + word.charAt(0).toUpperCase() + word.substring(1); 26 | }, '#'); 27 | 28 | // If the hashtag is only one character long or longer than 140 characters, return false, otherwise return the hashtag. 29 | return hashtag.length == 1 || hashtag.length > 140 ? false : hashtag; 30 | } 31 | 32 | module.exports = generateHashtag; 33 | -------------------------------------------------------------------------------- /03-high-order-array-methods/06-hashtag-generator/hashtag-generator-test.js: -------------------------------------------------------------------------------- 1 | const generateHashtag = require('./hashtag-generator'); 2 | 3 | test('Generating Hashtags', () => { 4 | expect(generateHashtag(' Hello there thanks for trying my Kata')).toBe( 5 | '#HelloThereThanksForTryingMyKata' 6 | ); 7 | expect(generateHashtag(' Hello World ')).toBe('#HelloWorld'); 8 | expect(generateHashtag('')).toBe(false); 9 | expect( 10 | generateHashtag( 11 | 'This is a very very very very very very very very very very very very very very long input that should result in a false hashtag because it exceeds the character limit of 140' 12 | ) 13 | ).toBe(false); 14 | }); 15 | -------------------------------------------------------------------------------- /03-high-order-array-methods/06-hashtag-generator/hashtag-generator.js: -------------------------------------------------------------------------------- 1 | function generateHashtag() {} 2 | 3 | module.exports = generateHashtag; 4 | -------------------------------------------------------------------------------- /03-high-order-array-methods/07-valid-ipv4/valid-ipv4-run.js: -------------------------------------------------------------------------------- 1 | const isValidIPv4 = require('./valid-ipv4.js'); 2 | 3 | const result1 = isValidIPv4('122.164.23.21'); 4 | const result2 = isValidIPv4('122.164.23.21.33'); 5 | 6 | console.log(result1, result2); 7 | -------------------------------------------------------------------------------- /03-high-order-array-methods/07-valid-ipv4/valid-ipv4-solution.js: -------------------------------------------------------------------------------- 1 | const isValidIPv4 = (input) => { 2 | // Split the input string into an array of octets. 3 | const octets = input.split('.'); 4 | // If the input string does not contain exactly 4 octets, return false. 5 | if (octets.length !== 4) { 6 | return false; 7 | } 8 | // Otherwise, return true if every octet is a number between 0 and 255. 9 | return octets.every((octet) => { 10 | const num = parseInt(octet); // Convert the octet to a number. 11 | return num >= 0 && num <= 255 && octet === num.toString(); // Return true if the octet is between 0 and 255 and the octet is equal to the number converted back to a string. 12 | }); 13 | }; 14 | 15 | module.exports = isValidIPv4; 16 | -------------------------------------------------------------------------------- /03-high-order-array-methods/07-valid-ipv4/valid-ipv4-test.js: -------------------------------------------------------------------------------- 1 | const isValidIPv4 = require('./valid-ipv4'); 2 | 3 | test('Checking Valid IPv4 Addresses', () => { 4 | expect(isValidIPv4('1.2.3.4')).toBe(true); 5 | expect(isValidIPv4('123.45.67.89')).toBe(true); 6 | expect(isValidIPv4('1.2.3')).toBe(false); 7 | expect(isValidIPv4('1.2.3.4.5')).toBe(false); 8 | expect(isValidIPv4('123.456.78.90')).toBe(false); 9 | expect(isValidIPv4('123.045.067.089')).toBe(false); 10 | }); 11 | -------------------------------------------------------------------------------- /03-high-order-array-methods/07-valid-ipv4/valid-ipv4.js: -------------------------------------------------------------------------------- 1 | const isValidIPv4 = () => {}; 2 | 3 | module.exports = isValidIPv4; 4 | -------------------------------------------------------------------------------- /03-high-order-array-methods/08-analyze-car-milage/analyze-car-milage-run.js: -------------------------------------------------------------------------------- 1 | const analyzeCarMileage = require('./analyze-car-milage'); 2 | 3 | const cars = [ 4 | { make: 'Toyota', model: 'Camry', year: 2020, mileage: 30800.22 }, 5 | { make: 'Honda', model: 'Civic', year: 2019, mileage: 32000.12 }, 6 | { make: 'Chevrolet', model: 'Impala', year: 2021, mileage: 17500 }, 7 | { make: 'Audi', model: 'R8', year: 2020, mileage: 13000 }, 8 | { make: 'Tesla', model: 'Model 3', year: 2018, mileage: 50000 }, 9 | ]; 10 | 11 | const result = analyzeCarMileage(cars); 12 | 13 | console.log(result); 14 | -------------------------------------------------------------------------------- /03-high-order-array-methods/08-analyze-car-milage/analyze-car-milage-solution.js: -------------------------------------------------------------------------------- 1 | function analyzeCarMileage(cars) { 2 | // Get the total mileage of all cars by adding the mileage of each car to the sum 3 | const totalMileage = cars.reduce((sum, car) => sum + car.mileage, 0); 4 | // Get the average mileage by dividing the total mileage by the number of cars 5 | const averageMileage = totalMileage / cars.length; 6 | // Get the car with the highest mileage by comparing the mileage of each car to the highest mileage so far 7 | const highestMileageCar = cars.reduce( 8 | (highest, car) => (car.mileage > highest.mileage ? car : highest), 9 | cars[0] 10 | ); 11 | // Get the car with the lowest mileage by comparing the mileage of each car to the lowest mileage so far 12 | const lowestMileageCar = cars.reduce( 13 | (lowest, car) => (car.mileage < lowest.mileage ? car : lowest), 14 | cars[0] 15 | ); 16 | 17 | // Return an object with the average mileage, the car with the highest mileage, the car with the lowest mileage, and the total mileage 18 | return { 19 | averageMileage: parseFloat(averageMileage.toFixed(2)), 20 | highestMileageCar, 21 | lowestMileageCar, 22 | totalMileage, 23 | }; 24 | } 25 | 26 | module.exports = analyzeCarMileage; 27 | -------------------------------------------------------------------------------- /03-high-order-array-methods/08-analyze-car-milage/analyze-car-milage-test.js: -------------------------------------------------------------------------------- 1 | const analyzeCarMileage = require('./analyze-car-milage'); 2 | 3 | test('Analyzing Car Mileage Data', () => { 4 | const cars = [ 5 | { make: 'Toyota', model: 'Corolla', year: 2020, mileage: 25000 }, 6 | { make: 'Honda', model: 'Civic', year: 2019, mileage: 30000 }, 7 | { make: 'Ford', model: 'Mustang', year: 2021, mileage: 15000 }, 8 | ]; 9 | 10 | const analysis = analyzeCarMileage(cars); 11 | 12 | expect(analysis.averageMileage).toBeCloseTo(23333.33); 13 | expect(analysis.highestMileageCar).toEqual({ 14 | make: 'Honda', 15 | model: 'Civic', 16 | year: 2019, 17 | mileage: 30000, 18 | }); 19 | expect(analysis.lowestMileageCar).toEqual({ 20 | make: 'Ford', 21 | model: 'Mustang', 22 | year: 2021, 23 | mileage: 15000, 24 | }); 25 | expect(analysis.totalMileage).toBe(70000); 26 | }); 27 | -------------------------------------------------------------------------------- /03-high-order-array-methods/08-analyze-car-milage/analyze-car-milage.js: -------------------------------------------------------------------------------- 1 | function analyzeCarMileage() {} 2 | 3 | module.exports = analyzeCarMileage; 4 | -------------------------------------------------------------------------------- /03-high-order-array-methods/09-password-validator/password-validator-run.js: -------------------------------------------------------------------------------- 1 | const validatePassword = require('./password-validator'); 2 | 3 | const result1 = validatePassword('Abc12345'); 4 | const result2 = validatePassword('password'); 5 | 6 | console.log(result1, result2); 7 | -------------------------------------------------------------------------------- /03-high-order-array-methods/09-password-validator/password-validator-solution.js: -------------------------------------------------------------------------------- 1 | function validatePassword(password) { 2 | // Check if password is at least 8 characters long 3 | const isLengthValid = password.length >= 8; 4 | 5 | // Check if password contains at least one uppercase letter 6 | // The `some` method returns true if at least one element in the array satisfies the condition 7 | const hasUppercase = password 8 | .split('') 9 | .some((char) => char === char.toUpperCase() && char !== char.toLowerCase()); 10 | 11 | // Check if password contains at least one lowercase letter 12 | const hasLowercase = password 13 | .split('') 14 | .some((char) => char === char.toLowerCase() && char !== char.toUpperCase()); 15 | 16 | // Check if password contains at least one digit 17 | const hasDigit = password 18 | .split('') 19 | .some((char) => !isNaN(parseInt(char, 10))); 20 | 21 | return isLengthValid && hasUppercase && hasLowercase && hasDigit; 22 | } 23 | 24 | module.exports = validatePassword; 25 | -------------------------------------------------------------------------------- /03-high-order-array-methods/09-password-validator/password-validator-test.js: -------------------------------------------------------------------------------- 1 | const validatePassword = require('./password-validator'); 2 | 3 | test('Password Validation', () => { 4 | expect(validatePassword('Abc12345')).toBe(true); 5 | expect(validatePassword('password123')).toBe(false); 6 | expect(validatePassword('Pass')).toBe(false); 7 | expect(validatePassword('HelloWorld')).toBe(false); 8 | }); 9 | -------------------------------------------------------------------------------- /03-high-order-array-methods/09-password-validator/password-validator.js: -------------------------------------------------------------------------------- 1 | function validatePassword() {} 2 | 3 | module.exports = validatePassword; 4 | -------------------------------------------------------------------------------- /03-high-order-array-methods/10-find-missing-letter-refactor/find-missing-letter-refactor-run.js: -------------------------------------------------------------------------------- 1 | const findMissingLetter = require('./find-missing-letter-refactor'); 2 | 3 | const result = findMissingLetter(['a', 'b', 'c', 'e']); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /03-high-order-array-methods/10-find-missing-letter-refactor/find-missing-letter-refactor-test.js: -------------------------------------------------------------------------------- 1 | const findMissingLetter = require('./find-missing-letter-refactor'); 2 | 3 | test('Find Missing Letter', () => { 4 | expect(findMissingLetter(['a', 'b', 'c', 'e'])).toBe('d'); 5 | expect(findMissingLetter(['X', 'Z'])).toBe('Y'); 6 | expect(findMissingLetter(['m', 'n', 'o', 'q', 'r'])).toBe('p'); 7 | expect(findMissingLetter(['F', 'G', 'H', 'J'])).toBe('I'); 8 | }); 9 | -------------------------------------------------------------------------------- /03-high-order-array-methods/10-find-missing-letter-refactor/find-missing-letter-refactor.js: -------------------------------------------------------------------------------- 1 | function findMissingLetter() {} 2 | 3 | module.exports = findMissingLetter; 4 | -------------------------------------------------------------------------------- /04-recursion/01-recursion-intro/count-down-run.js: -------------------------------------------------------------------------------- 1 | const countDown = require('./count-down'); 2 | 3 | countDown(10); 4 | -------------------------------------------------------------------------------- /04-recursion/01-recursion-intro/count-down-solution.js: -------------------------------------------------------------------------------- 1 | function countDown(num) { 2 | // Base case - if num is less than or equal to 0, log 'All done!' and return 3 | if (num <= 0) { 4 | console.log('All done!'); 5 | return; 6 | } 7 | 8 | // Recursive case - log num, decrement num, and call countDown again 9 | console.log(num); 10 | num--; 11 | countDown(num); 12 | } 13 | 14 | module.exports = countDown; 15 | -------------------------------------------------------------------------------- /04-recursion/01-recursion-intro/count-down-test.js: -------------------------------------------------------------------------------- 1 | const countDown = require('./count-down'); 2 | 3 | describe('countDown', () => { 4 | let originalLog; 5 | 6 | beforeAll(() => { 7 | // Mock console.log to prevent logs from cluttering the test output 8 | originalLog = console.log; 9 | console.log = jest.fn(); 10 | }); 11 | 12 | afterAll(() => { 13 | // Restore console.log after all tests are done 14 | console.log = originalLog; 15 | }); 16 | 17 | it('should log numbers in reverse order and print "All done!"', () => { 18 | countDown(3); 19 | expect(console.log).toHaveBeenNthCalledWith(1, 3); // 3 is logged first 20 | expect(console.log).toHaveBeenNthCalledWith(2, 2); // 2 is logged next 21 | expect(console.log).toHaveBeenNthCalledWith(3, 1); // 1 is logged last 22 | expect(console.log).toHaveBeenNthCalledWith(4, 'All done!'); // 'All done!' is logged after counting down 23 | }); 24 | 25 | it('should handle num <= 0', () => { 26 | countDown(0); 27 | expect(console.log).toHaveBeenCalledWith('All done!'); // 'All done!' is logged when num is 0 28 | 29 | console.log.mockClear(); // Clear the previous logs 30 | countDown(-1); 31 | expect(console.log).toHaveBeenCalledWith('All done!'); // 'All done!' is logged when num is negative 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /04-recursion/01-recursion-intro/count-down.js: -------------------------------------------------------------------------------- 1 | function countDown() {} 2 | 3 | module.exports = countDown; 4 | -------------------------------------------------------------------------------- /04-recursion/02-unwinding/sum-up-to-run.js: -------------------------------------------------------------------------------- 1 | const sumUpTo = require('./sum-up-to'); 2 | 3 | const result = sumUpTo(6); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /04-recursion/02-unwinding/sum-up-to-solution.js: -------------------------------------------------------------------------------- 1 | function sumUpTo(n) { 2 | // Base case - when n is 1, we return 1 3 | // if n is 0 or negative, we handle that case otherwise infinite recursion 4 | if (n <= 1) { 5 | return n; 6 | } 7 | 8 | // Recursive case - when n is greater than 1, we return the sum of n and sumUpTo(n - 1) 9 | return n + sumUpTo(n - 1); 10 | } 11 | -------------------------------------------------------------------------------- /04-recursion/02-unwinding/sum-up-to-test.js: -------------------------------------------------------------------------------- 1 | const sumUpTo = require('./sum-up-to'); 2 | 3 | test('Summing up positive integers', () => { 4 | expect(sumUpTo(5)).toBe(15); 5 | expect(sumUpTo(10)).toBe(55); 6 | expect(sumUpTo(1)).toBe(1); 7 | expect(sumUpTo(0)).toBe(0); 8 | }); 9 | -------------------------------------------------------------------------------- /04-recursion/02-unwinding/sum-up-to.js: -------------------------------------------------------------------------------- 1 | function sumUpTo() {} 2 | 3 | module.exports = sumUpTo; 4 | -------------------------------------------------------------------------------- /04-recursion/03-reverse-string-recursion/reverse-string-recursion-run.js: -------------------------------------------------------------------------------- 1 | const reverseString = require('./reverse-string-recursion'); 2 | 3 | const result = reverseString('hello'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /04-recursion/03-reverse-string-recursion/reverse-string-recursion-solution.js: -------------------------------------------------------------------------------- 1 | function reverseString(str) { 2 | // Base case - if str is empty, return empty string 3 | if (str === '') { 4 | return ''; 5 | } else { 6 | // Recursive case - return the last character of str and call reverseString again 7 | return reverseString(str.substr(1)) + str.charAt(0); 8 | } 9 | } 10 | 11 | // Shorter version 12 | const reverseString = (str) => 13 | str === '' ? '' : reverseString(str.substr(1)) + str.charAt(0); 14 | 15 | reverseString('Hello'); 16 | 17 | module.exports = reverseString; 18 | -------------------------------------------------------------------------------- /04-recursion/03-reverse-string-recursion/reverse-string-recursion-test.js: -------------------------------------------------------------------------------- 1 | const reverseString = require('./reverse-string-recursion'); 2 | 3 | test('Reversing a string', () => { 4 | expect(reverseString('Hello')).toBe('olleH'); 5 | expect(reverseString('JavaScript')).toBe('tpircSavaJ'); 6 | expect(reverseString('12345')).toBe('54321'); 7 | }); 8 | -------------------------------------------------------------------------------- /04-recursion/03-reverse-string-recursion/reverse-string-recursion.js: -------------------------------------------------------------------------------- 1 | function reverseString() {} 2 | 3 | module.exports = reverseString; 4 | -------------------------------------------------------------------------------- /04-recursion/04-fibonacci-sequence/fibonacci-run.js: -------------------------------------------------------------------------------- 1 | const fibonacci = require('./fibonacci'); 2 | 3 | const result = fibonacci(8); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /04-recursion/04-fibonacci-sequence/fibonacci-solution.js: -------------------------------------------------------------------------------- 1 | function fibonacci(num) { 2 | // Base case - if num is less than 2, return num 3 | if (num < 2) return num; 4 | 5 | // Recursive case - return the sum of the previous two numbers 6 | return fibonacci(num - 1) + fibonacci(num - 2); 7 | } 8 | 9 | // Shorter version 10 | const fibonacci = (num) => 11 | num < 2 ? num : fibonacci(num - 1) + fibonacci(num - 2); 12 | 13 | module.exports = fibonacci; 14 | -------------------------------------------------------------------------------- /04-recursion/04-fibonacci-sequence/fibonacci-test.js: -------------------------------------------------------------------------------- 1 | const fibonacci = require('./fibonacci'); 2 | 3 | describe('fibonacci', () => { 4 | it('should return the correct Fibonacci number', () => { 5 | expect(fibonacci(0)).toBe(0); // The 0th Fibonacci number is 0 6 | expect(fibonacci(1)).toBe(1); // The 1st Fibonacci number is 1 7 | expect(fibonacci(2)).toBe(1); // The 2nd Fibonacci number is 1 (0 + 1) 8 | expect(fibonacci(3)).toBe(2); // The 3rd Fibonacci number is 2 (1 + 1) 9 | expect(fibonacci(4)).toBe(3); // The 4th Fibonacci number is 3 (1 + 2) 10 | expect(fibonacci(5)).toBe(5); // The 5th Fibonacci number is 5 (2 + 3) 11 | expect(fibonacci(6)).toBe(8); // The 6th Fibonacci number is 8 (3 + 5) 12 | expect(fibonacci(7)).toBe(13); // The 7th Fibonacci number is 13 (5 + 8) 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /04-recursion/04-fibonacci-sequence/fibonacci.js: -------------------------------------------------------------------------------- 1 | function fibonacci() {} 2 | 3 | module.exports = fibonacci; 4 | -------------------------------------------------------------------------------- /04-recursion/05-factorial/factorial-run.js: -------------------------------------------------------------------------------- 1 | const factorial = require('./factorial'); 2 | 3 | const result = factorial(5); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /04-recursion/05-factorial/factorial-solution.js: -------------------------------------------------------------------------------- 1 | function factorial(num) { 2 | // Base case: 0! and 1! are both 1 3 | if (num === 0 || num === 1) { 4 | return 1; 5 | } 6 | 7 | // Recursive case: n! = n * (n - 1)! 8 | return num * factorial(num - 1); 9 | } 10 | 11 | // Shorter version 12 | const factorial = (num) => 13 | num === 0 || num === 1 ? 1 : num * factorial(num - 1); 14 | 15 | module.exports = factorial; 16 | -------------------------------------------------------------------------------- /04-recursion/05-factorial/factorial-test.js: -------------------------------------------------------------------------------- 1 | const factorial = require('./factorial'); 2 | 3 | test('Factorial of 0 should be 1', () => { 4 | expect(factorial(0)).toBe(1); 5 | }); 6 | 7 | test('Factorial of 5 should be 120', () => { 8 | expect(factorial(5)).toBe(120); 9 | }); 10 | 11 | test('Factorial of 10 should be 3628800', () => { 12 | expect(factorial(10)).toBe(3628800); 13 | }); 14 | -------------------------------------------------------------------------------- /04-recursion/05-factorial/factorial.js: -------------------------------------------------------------------------------- 1 | function factorial() {} 2 | 3 | module.exports = factorial; 4 | -------------------------------------------------------------------------------- /04-recursion/06-power/power-run.js: -------------------------------------------------------------------------------- 1 | const power = require('./power'); 2 | 3 | const result = power(2, 4); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /04-recursion/06-power/power-solution.js: -------------------------------------------------------------------------------- 1 | // No recursion 2 | function power(base, exponent) { 3 | // Initialize result to 1 4 | let result = 1; 5 | 6 | // Multiply base by itself exponent times 7 | for (let i = 0; i < exponent; i++) { 8 | result *= base; 9 | } 10 | return result; 11 | } 12 | 13 | function power(base, exponent) { 14 | // Base case - if exponent is 0, return 1 15 | if (exponent === 0) { 16 | return 1; 17 | } else { 18 | // Recursive case - return base multiplied by itself exponent - 1 times 19 | return base * power(base, exponent - 1); 20 | } 21 | } 22 | 23 | module.exports = power; 24 | -------------------------------------------------------------------------------- /04-recursion/06-power/power-test.js: -------------------------------------------------------------------------------- 1 | const power = require('./power'); 2 | 3 | test('Calculate Power of Base to Exponent', () => { 4 | expect(power(2, 3)).toEqual(8); 5 | expect(power(5, 2)).toEqual(25); 6 | expect(power(3, 4)).toEqual(81); 7 | }); 8 | -------------------------------------------------------------------------------- /04-recursion/06-power/power.js: -------------------------------------------------------------------------------- 1 | function power() {} 2 | 3 | module.exports = power; 4 | -------------------------------------------------------------------------------- /04-recursion/07-array-sum/array-sum-run.js: -------------------------------------------------------------------------------- 1 | const arraySum = require('./array-sum'); 2 | 3 | const result = arraySum([1, 2, 3, 4, 5]); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /04-recursion/07-array-sum/array-sum-solution.js: -------------------------------------------------------------------------------- 1 | function arraySum(arr) { 2 | if (arr.length === 0) { 3 | return 0; // Base case: Empty array, return 0 4 | } else { 5 | return arr[0] + arraySum(arr.slice(1)); // Recursive case: Sum the first element and the sum of the rest of the array 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /04-recursion/07-array-sum/array-sum-test.js: -------------------------------------------------------------------------------- 1 | const arraySum = require('./array-sum'); 2 | 3 | test('Calculate Sum of Array Using Recursion', () => { 4 | expect(arraySum([1, 2, 3, 4, 5])).toEqual(15); 5 | expect(arraySum([-1, -2, -3, -4, -5])).toEqual(-15); 6 | expect(arraySum([])).toEqual(0); 7 | }); 8 | -------------------------------------------------------------------------------- /04-recursion/07-array-sum/array-sum.js: -------------------------------------------------------------------------------- 1 | function arraySum() {} 2 | 3 | module.exports = arraySum; 4 | -------------------------------------------------------------------------------- /04-recursion/08-number-range/number-range-run.js: -------------------------------------------------------------------------------- 1 | const numberRange = require('./number-range'); 2 | 3 | const result = numberRange(1, 5); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /04-recursion/08-number-range/number-range-solution.js: -------------------------------------------------------------------------------- 1 | // Define the function named rangeOfNumbers that takes two parameters: startNum and endNum 2 | function rangeOfNumbers(startNum, endNum) { 3 | // Check if the startNum is equal to endNum (base case) 4 | if (startNum === endNum) { 5 | // If they are equal, return an array containing just the startNum 6 | return [startNum]; 7 | } 8 | 9 | // If they are not equal, create a variable named 'numbers' 10 | // Call the rangeOfNumbers function recursively on a smaller range 11 | // This creates an array of numbers from startNum to endNum - 1 12 | const numbers = rangeOfNumbers(startNum, endNum - 1); 13 | 14 | // Push the current value of endNum to the 'numbers' array 15 | numbers.push(endNum); 16 | 17 | // Return the 'numbers' array containing all the numbers from startNum to endNum 18 | return numbers; 19 | } 20 | -------------------------------------------------------------------------------- /04-recursion/08-number-range/number-range-test.js: -------------------------------------------------------------------------------- 1 | const numberRange = require('./number-range'); 2 | 3 | test('Calculating the range of numbers', () => { 4 | expect(numberRange(1, 5)).toEqual([1, 2, 3, 4, 5]); 5 | expect(numberRange(3, 10)).toEqual([3, 4, 5, 6, 7, 8, 9, 10]); 6 | expect(numberRange(7, 7)).toEqual([7]); 7 | }); 8 | -------------------------------------------------------------------------------- /04-recursion/08-number-range/number-range.js: -------------------------------------------------------------------------------- 1 | function numberRange() {} 2 | 3 | module.exports = numberRange; 4 | -------------------------------------------------------------------------------- /04-recursion/09-flatten-array/flatten-array-run.js: -------------------------------------------------------------------------------- 1 | const flattenArray = require('./flatten-array'); 2 | 3 | const result = flattenArray([1, 2, 3, [4, 5, [6, 7, 8], 9], 10]); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /04-recursion/09-flatten-array/flatten-array-solution.js: -------------------------------------------------------------------------------- 1 | function flattenArray(arr) { 2 | // Create an empty array to store the result 3 | let result = []; 4 | 5 | // Loop through each item in arr 6 | for (const item of arr) { 7 | // If item is an array, call flattenArray again and concat the result to result 8 | if (Array.isArray(item)) { 9 | result = result.concat(flattenArray(item)); 10 | } else { 11 | // If item is not an array, push it to result 12 | result.push(item); 13 | } 14 | } 15 | 16 | return result; 17 | } 18 | 19 | module.exports = flattenArray; 20 | -------------------------------------------------------------------------------- /04-recursion/09-flatten-array/flatten-array-test.js: -------------------------------------------------------------------------------- 1 | const flattenArray = require('./flatten-array'); 2 | 3 | test('Flatten Nested Arrays', () => { 4 | expect(flattenArray([1, [2, 3], [4, 5, [6]]])).toEqual([1, 2, 3, 4, 5, 6]); 5 | expect( 6 | flattenArray([ 7 | [1, 2], 8 | [3, [4, 5]], 9 | [6, [7]], 10 | ]) 11 | ).toEqual([1, 2, 3, 4, 5, 6, 7]); 12 | expect(flattenArray([1, [2, [3, [4, [5]]]]])).toEqual([1, 2, 3, 4, 5]); 13 | }); 14 | -------------------------------------------------------------------------------- /04-recursion/09-flatten-array/flatten-array.js: -------------------------------------------------------------------------------- 1 | function flattenArray() {} 2 | 3 | module.exports = flattenArray; 4 | -------------------------------------------------------------------------------- /04-recursion/10-permutations/permutations-run.js: -------------------------------------------------------------------------------- 1 | const permutations = require('./permutations'); 2 | 3 | const result = permutations('abc'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /04-recursion/10-permutations/permutations-solution.js: -------------------------------------------------------------------------------- 1 | function permutations(str) { 2 | // Create an array to store the permutations 3 | const result = []; 4 | 5 | // If str is an empty string, push an empty string to result and return 6 | if (str.length === 0) { 7 | result.push(''); 8 | return result; 9 | } 10 | 11 | // Loop through each character in str 12 | for (let i = 0; i < str.length; i++) { 13 | // Get the first character 14 | const firstChar = str[i]; 15 | // Get the rest of the string 16 | const restOfString = str.slice(0, i) + str.slice(i + 1); 17 | // Get the permutations of the rest of the string 18 | const subPermutations = permutations(restOfString); 19 | 20 | // Loop through each permutation in subPermutations 21 | for (let j = 0; j < subPermutations.length; j++) { 22 | // Push the first character and the permutation to result 23 | result.push(firstChar + subPermutations[j]); 24 | } 25 | } 26 | 27 | // Return result 28 | return result; 29 | } 30 | 31 | module.exports = permutations; 32 | -------------------------------------------------------------------------------- /04-recursion/10-permutations/permutations-test.js: -------------------------------------------------------------------------------- 1 | const permutations = require('./permutations'); 2 | 3 | test('Permutations', () => { 4 | expect(permutations('abc')).toEqual([ 5 | 'abc', 6 | 'acb', 7 | 'bac', 8 | 'bca', 9 | 'cab', 10 | 'cba', 11 | ]); 12 | expect(permutations('dog')).toEqual([ 13 | 'dog', 14 | 'dgo', 15 | 'odg', 16 | 'ogd', 17 | 'gdo', 18 | 'god', 19 | ]); 20 | expect(permutations('')).toEqual(['']); 21 | }); 22 | -------------------------------------------------------------------------------- /04-recursion/10-permutations/permutations.js: -------------------------------------------------------------------------------- 1 | function permutations() {} 2 | 3 | module.exports = permutations; 4 | -------------------------------------------------------------------------------- /05-complexity/03-constant-time-complexity/constant-time-done.js: -------------------------------------------------------------------------------- 1 | /* 2 | Example of constant time O(1) 3 | 4 | Constant time means that the time required to complete a function is the same regardless of the size of the input data set. 5 | */ 6 | 7 | function accessElement(arr, index) { 8 | return arr[index]; 9 | } 10 | 11 | const arr1 = [1, 2, 3, 4, 5]; 12 | console.time('Access Element 1'); 13 | console.log(accessElement(arr1, 1)); 14 | console.timeEnd('Access Element 1'); 15 | 16 | const arr2 = Array.from({ length: 10000 }, (_, index) => index + 1); 17 | 18 | console.time('Access Element 2'); 19 | console.log(accessElement(arr2, 1)); 20 | console.timeEnd('Access Element 2'); 21 | -------------------------------------------------------------------------------- /05-complexity/03-constant-time-complexity/constant-time.js: -------------------------------------------------------------------------------- 1 | /* 2 | Example of constant time O(1) 3 | 4 | Constant time means that the time required to complete a function is the same regardless of the size of the input data set. 5 | */ 6 | -------------------------------------------------------------------------------- /05-complexity/04-linear-time-complexity/linear-time-done.js: -------------------------------------------------------------------------------- 1 | /* 2 | Linear Time O(n) 3 | 4 | Linear time means that the time required to complete a function is directly proportional to the size of the input data set. 5 | */ 6 | 7 | function sumArray(arr) { 8 | let sum = 0; 9 | for (let i = 0; i < arr.length; i++) { 10 | sum += arr[i]; 11 | } 12 | return sum; 13 | } 14 | 15 | const arr1 = [1, 2, 3, 4, 5]; 16 | console.time('Sum Array 1'); 17 | sumArray(arr1); 18 | console.timeEnd('Sum Array 1'); 19 | 20 | const arr2 = Array.from({ length: 10000000 }, (_, index) => index + 1); 21 | 22 | console.time('Sum Array 2'); 23 | sumArray(arr2); 24 | console.timeEnd('Sum Array 2'); 25 | -------------------------------------------------------------------------------- /05-complexity/04-linear-time-complexity/linear-time.js: -------------------------------------------------------------------------------- 1 | /* 2 | Linear Time O(n) 3 | 4 | Linear time means that the time required to complete a function is directly proportional to the size of the input data set. 5 | */ 6 | -------------------------------------------------------------------------------- /05-complexity/05-quadratic-time-complexity/quadradic-time-done.js: -------------------------------------------------------------------------------- 1 | /* 2 | Quadradic Time O(n^2) 3 | 4 | Quadradic time means that the time required to complete a function is proportional to the square of the input data set. 5 | */ 6 | 7 | function sumArray(arr) { 8 | let sum = 0; 9 | let sum2 = 0; 10 | for (let i = 0; i < arr.length; i++) { 11 | sum += arr[i]; 12 | for (let j = 0; j < arr.length; j++) { 13 | sum2 += arr[j]; 14 | } 15 | } 16 | return sum + sum2; 17 | } 18 | 19 | const arr1 = [1, 2, 3, 4, 5]; 20 | console.time('Sum Array 1'); 21 | sumArray(arr1); 22 | console.timeEnd('Sum Array 1'); 23 | 24 | const arr2 = Array.from({ length: 10000000 }, (_, index) => index + 1); 25 | 26 | console.time('Sum Array 2'); 27 | sumArray(arr2); 28 | console.timeEnd('Sum Array 2'); 29 | -------------------------------------------------------------------------------- /05-complexity/05-quadratic-time-complexity/quadradic-time.js: -------------------------------------------------------------------------------- 1 | /* 2 | Quadradic Time O(n^2) 3 | 4 | Quadradic time means that the time required to complete a function is proportional to the square of the input data set. 5 | */ 6 | -------------------------------------------------------------------------------- /05-complexity/06-logarithmic-time-complexity/logarithmic-time-done.js: -------------------------------------------------------------------------------- 1 | /* 2 | Logarithmic Time (O(log n)) 3 | 4 | Logarithmic time means that the time required to complete a function is proportional to the logarithm of the input data set. 5 | 6 | */ 7 | 8 | function findPower(base, exponent) { 9 | if (exponent === 0) { 10 | return 1; 11 | } 12 | 13 | if (exponent % 2 === 0) { 14 | const halfPower = findPower(base, exponent / 2); 15 | return halfPower * halfPower; 16 | } else { 17 | const halfPower = findPower(base, (exponent - 1) / 2); 18 | return base * halfPower * halfPower; 19 | } 20 | } 21 | 22 | console.time('Find Power 1'); 23 | findPower(2, 100); 24 | console.timeEnd('Find Power 1'); 25 | 26 | console.time('Find Power 2'); 27 | findPower(2, 1000000000); 28 | console.timeEnd('Find Power 2'); 29 | -------------------------------------------------------------------------------- /05-complexity/06-logarithmic-time-complexity/logarithmic-time.js: -------------------------------------------------------------------------------- 1 | /* 2 | Logarithmic Time (O(log n)) 3 | 4 | Logarithmic time means that the time required to complete a function is proportional to the logarithm of the input data set. 5 | 6 | */ 7 | 8 | -------------------------------------------------------------------------------- /05-complexity/07-space-complexity/space-complexity.js: -------------------------------------------------------------------------------- 1 | /* 2 | Space Complexity: O(1) 3 | Time Complexity: O(1) 4 | */ 5 | 6 | function add(num1, num2) { 7 | return num1 + num2; 8 | } 9 | 10 | /* 11 | Space Complexity: O(n) 12 | Time Complexity: O(n) 13 | */ 14 | 15 | function createArray(num) { 16 | const arr = []; 17 | 18 | for (let i = 0; i < num; i++) { 19 | arr.push(i); 20 | } 21 | 22 | return arr; 23 | } 24 | 25 | /* 26 | Space Complexity: O(n^2) 27 | Time Complexity: O(n^2) 28 | */ 29 | 30 | function createMatrix(num) { 31 | const matrix = []; 32 | 33 | for (let i = 0; i < num; i++) { 34 | matrix[i] = []; 35 | 36 | for (let j = 0; j < num; j++) { 37 | matrix[i][j] = i + j; 38 | } 39 | } 40 | 41 | return matrix; 42 | } 43 | 44 | /* 45 | Space Complexity: O(log n) 46 | Time Complexity: O(log n) 47 | */ 48 | 49 | function findPower(base, exponent) { 50 | if (exponent === 0) { 51 | return 1; 52 | } 53 | 54 | if (exponent % 2 === 0) { 55 | const halfPower = findPower(base, exponent / 2); 56 | return halfPower * halfPower; 57 | } else { 58 | const halfPower = findPower(base, (exponent - 1) / 2); 59 | return base * halfPower * halfPower; 60 | } 61 | } 62 | 63 | /* 64 | Space Complexity: O(1) 65 | Time Complexity: O(n) 66 | */ 67 | 68 | function findSum(arr) { 69 | let sum = 0; 70 | 71 | for (let i = 0; i < arr.length; i++) { 72 | sum += arr[i]; 73 | } 74 | 75 | return sum; 76 | } 77 | -------------------------------------------------------------------------------- /05-complexity/08-max-subarray-quadratic/max-subarray-quadratic-run.js: -------------------------------------------------------------------------------- 1 | const maxSubarraySum = require('./max-subarray-quadratic'); 2 | 3 | const arr = [2, 5, 3, 1, 11, 7, 6, 4]; 4 | 5 | const result = maxSubarraySum(arr, 3); 6 | 7 | console.log(result); 8 | -------------------------------------------------------------------------------- /05-complexity/08-max-subarray-quadratic/max-subarray-quadratic-solution.js: -------------------------------------------------------------------------------- 1 | // Define a function called maxSubarraySum which takes an array 'arr' and a positive integer 'k' as input 2 | function maxSubarraySum(arr, k) { 3 | // Initialize a variable 'maxSum' to store the maximum sum of subarrays 4 | let maxSum = 0; 5 | 6 | // Iterate through the array from index 0 to (length - k) 7 | // We only need to consider subarrays of length 'k', so we stop when there's not enough elements left 8 | for (let i = 0; i <= arr.length - k; i++) { 9 | // Initialize a variable 'currentSum' to store the sum of the current subarray 10 | let currentSum = 0; 11 | 12 | // Nested loop: Iterate through the subarray of length 'k' starting from index 'i'. This will loop through the current windows 13 | for (let j = i; j < i + k; j++) { 14 | // Add the value at index 'j' to 'currentSum' 15 | currentSum += arr[j]; 16 | } 17 | 18 | // Update 'maxSum' to be the maximum value between 'maxSum' and 'currentSum' 19 | maxSum = Math.max(maxSum, currentSum); 20 | } 21 | 22 | // Return the maximum sum of any subarray of length 'k' 23 | return maxSum; 24 | } 25 | -------------------------------------------------------------------------------- /05-complexity/08-max-subarray-quadratic/max-subarray-quadratic-test.js: -------------------------------------------------------------------------------- 1 | const maxSubarraySum = require('./max-subarray-quadratic'); 2 | 3 | test('Finding maximum subarray sum using O(n^2) solution', () => { 4 | const arr1 = [2, 5, 3, 1, 11, 7, 6, 4]; 5 | const k1 = 3; 6 | expect(maxSubarraySum(arr1, k1)).toBe(24); 7 | 8 | const arr2 = [-2, -5, -3, -1, -11, -7, -6, -4]; 9 | const k2 = 4; 10 | expect(maxSubarraySum(arr2, k2)).toBe(-11); 11 | }); 12 | -------------------------------------------------------------------------------- /05-complexity/08-max-subarray-quadratic/max-subarray-quadratic.js: -------------------------------------------------------------------------------- 1 | function maxSubarraySum() {} 2 | 3 | module.exports = maxSubarraySum; 4 | -------------------------------------------------------------------------------- /05-complexity/10-max-subarray-linear/max-subarray-linear-run.js: -------------------------------------------------------------------------------- 1 | const maxSubarraySum = require('./max-subarray-linear'); 2 | 3 | const arr = [2, 5, 3, 1, 11, 7, 6, 4]; 4 | 5 | const result = maxSubarraySum(arr, 3); 6 | 7 | console.log(result); 8 | -------------------------------------------------------------------------------- /05-complexity/10-max-subarray-linear/max-subarray-linear-solution.js: -------------------------------------------------------------------------------- 1 | function maxSubarraySum(arr, k) { 2 | // Initialize variables to track maximum sum and current sum 3 | let maxSum = 0; 4 | let currentSum = 0; 5 | 6 | // Calculate the sum of the first k elements 7 | for (let i = 0; i < k; i++) { 8 | maxSum += arr[i]; 9 | } 10 | 11 | // Set the initial value of currentSum as maxSum 12 | currentSum = maxSum; 13 | 14 | // Slide the window and calculate maximum sum 15 | for (let i = k; i < arr.length; i++) { 16 | // Update currentSum by subtracting the element that left the window and adding the new element 17 | currentSum = currentSum - arr[i - k] + arr[i]; 18 | 19 | // Log the update for visualization (optional) 20 | console.log(`${currentSum} - ${arr[i - k]} + ${arr[i]}`); 21 | 22 | // Update maxSum with the maximum value between maxSum and currentSum 23 | maxSum = Math.max(maxSum, currentSum); 24 | } 25 | 26 | // Return the maximum sum 27 | return maxSum; 28 | } 29 | -------------------------------------------------------------------------------- /05-complexity/10-max-subarray-linear/max-subarray-linear-test.js: -------------------------------------------------------------------------------- 1 | const maxSubarraySum = require('./max-subarray-linear'); 2 | 3 | test('Finding maximum subarray sum using O(n^2) solution', () => { 4 | const arr1 = [2, 5, 3, 1, 11, 7, 6, 4]; 5 | const k1 = 3; 6 | expect(maxSubarraySum(arr1, k1)).toBe(24); 7 | 8 | const arr2 = [-2, -5, -3, -1, -11, -7, -6, -4]; 9 | const k2 = 4; 10 | expect(maxSubarraySum(arr2, k2)).toBe(-9); 11 | }); 12 | -------------------------------------------------------------------------------- /05-complexity/10-max-subarray-linear/max-subarray-linear.js: -------------------------------------------------------------------------------- 1 | function maxSubarraySum() {} 2 | 3 | module.exports = maxSubarraySum; 4 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/03-maps/maps-done.js: -------------------------------------------------------------------------------- 1 | const nameMap = new Map([ 2 | [1, 'John'], 3 | [2, 'Jane'], 4 | [3, 'Joe'], 5 | ]); 6 | 7 | const myFunction = () => {}; 8 | const emptyObj = {}; 9 | 10 | const map2 = new Map([ 11 | ['name', 'John'], 12 | [1, 'number one'], 13 | [true, 'really true'], 14 | [null, 'null'], 15 | [myFunction, 'empty function'], 16 | [emptyObj, 'empty object'], 17 | ]); 18 | 19 | // Getting values 20 | console.log(nameMap.get(1)); 21 | console.log(map2.get(myFunction)); 22 | console.log(map2.get(emptyObj)); 23 | 24 | // Setting values 25 | nameMap.set(4, 'Jack'); 26 | nameMap.set(5, 'Jill'); 27 | 28 | // Checking values 29 | console.log(nameMap.has(1)); 30 | console.log(nameMap.has(6)); 31 | 32 | // Deleting values 33 | nameMap.delete(1); 34 | console.log(nameMap.has(1)); 35 | 36 | // Get Size 37 | console.log(nameMap.size); 38 | 39 | // Iterating (for...of) 40 | for (let [key, value] of nameMap) { 41 | console.log(key, value); 42 | } 43 | 44 | // Using forEach 45 | nameMap.forEach((value, key) => { 46 | console.log(key, value); 47 | }); 48 | 49 | // Looping keys and values 50 | console.log(nameMap.keys()); 51 | console.log(nameMap.values()); 52 | 53 | // Clearing 54 | nameMap.clear(); 55 | console.log(nameMap.size); 56 | 57 | // console.log(nameMap); 58 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/03-maps/maps.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/06-hash-tables-maps-sets/03-maps/maps.js -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/04-word-frequency-counter/word-frequency-counter-run.js: -------------------------------------------------------------------------------- 1 | const wordFrequencyCounter = require('./word-frequency-counter'); 2 | 3 | const result = wordFrequencyCounter( 4 | 'The quick brown fox jumps over the lazy dog.' 5 | ); 6 | 7 | console.log(result); 8 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/04-word-frequency-counter/word-frequency-counter-solution.js: -------------------------------------------------------------------------------- 1 | function wordFrequencyCounter(str) { 2 | // Convert the string to lowercase and split it into an array of words 3 | const words = str.toLowerCase().split(/\W+/); 4 | 5 | // Create an empty map to store word frequencies 6 | const wordFrequency = new Map(); 7 | 8 | // Loop through each word in the array 9 | for (const word of words) { 10 | // Ignore empty strings (caused by multiple spaces or punctuation marks) 11 | if (word === '') continue; 12 | 13 | // If the word is already in the map, increment its frequency 14 | if (wordFrequency.has(word)) { 15 | wordFrequency.set(word, wordFrequency.get(word) + 1); 16 | } else { 17 | // If the word is not in the map, add it with a frequency of 1 18 | wordFrequency.set(word, 1); 19 | } 20 | } 21 | 22 | return wordFrequency; 23 | } 24 | 25 | module.exports = wordFrequencyCounter; 26 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/04-word-frequency-counter/word-frequency-counter-test.js: -------------------------------------------------------------------------------- 1 | const wordFrequencyCounter = require('./word-frequency-counter'); 2 | 3 | describe('wordFrequencyCounter', () => { 4 | it('should count word frequencies correctly', () => { 5 | const input = "The quick brown fox jumps over the lazy dog. The dog barks, and the fox runs away."; 6 | const expectedOutput = new Map([ 7 | ['the', 4], 8 | ['quick', 1], 9 | ['brown', 1], 10 | ['fox', 2], 11 | ['jumps', 1], 12 | ['over', 1], 13 | ['lazy', 1], 14 | ['dog', 2], 15 | ['barks', 1], 16 | ['and', 1], 17 | ['runs', 1], 18 | ['away', 1], 19 | ]); 20 | 21 | const result = wordFrequencyCounter(input); 22 | expect(result).toEqual(expectedOutput); 23 | }); 24 | 25 | it('should handle empty input', () => { 26 | const input = ''; 27 | const expectedOutput = new Map(); 28 | 29 | const result = wordFrequencyCounter(input); 30 | expect(result).toEqual(expectedOutput); 31 | }); 32 | 33 | it('should handle input with single word', () => { 34 | const input = 'hello'; 35 | const expectedOutput = new Map([ 36 | ['hello', 1], 37 | ]); 38 | 39 | const result = wordFrequencyCounter(input); 40 | expect(result).toEqual(expectedOutput); 41 | }); 42 | 43 | // Add more test cases as needed 44 | }); 45 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/04-word-frequency-counter/word-frequency-counter.js: -------------------------------------------------------------------------------- 1 | function wordFrequencyCounter() {} 2 | 3 | module.exports = wordFrequencyCounter; 4 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/05-phone-number-directory/phone-number-directory-run.js: -------------------------------------------------------------------------------- 1 | const phoneNumberDirectory = require('./phone-number-directory'); 2 | 3 | const phoneNumbers = [ 4 | 'John:123-456-7890', 5 | 'Jane:987-654-3210', 6 | 'Joe:555-555-5555', 7 | ]; 8 | 9 | const result = phoneNumberDirectory(phoneNumbers); 10 | 11 | console.log(result.get('John')); 12 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/05-phone-number-directory/phone-number-directory-solution.js: -------------------------------------------------------------------------------- 1 | function phoneNumberDirectory(phoneNumbers) { 2 | // Create a new Map object 3 | const directory = new Map(); 4 | 5 | // Loop through each entry in the phoneNumbers array 6 | for (const entry of phoneNumbers) { 7 | // Split the entry into a name and phone number 8 | const [name, phoneNumber] = entry.split(':'); 9 | // Add the name and phone number to the directory 10 | directory.set(name, phoneNumber); 11 | } 12 | 13 | // Return the directory 14 | return directory; 15 | } 16 | 17 | module.exports = phoneNumberDirectory; 18 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/05-phone-number-directory/phone-number-directory-test.js: -------------------------------------------------------------------------------- 1 | const phoneNumberDirectory = require('./phone-number-directory'); 2 | 3 | test('Building a phone number directory from an array of phone numbers', () => { 4 | const phoneNumbers = [ 5 | 'John:123-456-7890', 6 | 'Jane:987-654-3210', 7 | 'Joe:555-555-5555', 8 | ]; 9 | 10 | const result = phoneNumberDirectory(phoneNumbers); 11 | 12 | expect(result.get('John')).toBe('123-456-7890'); 13 | expect(result.get('Jane')).toBe('987-654-3210'); 14 | expect(result.get('Joe')).toBe('555-555-5555'); 15 | }); 16 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/05-phone-number-directory/phone-number-directory.js: -------------------------------------------------------------------------------- 1 | function phoneNumberDirectory() {} 2 | 3 | module.exports = phoneNumberDirectory; 4 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/06-anagram-grouping/anagram-grouping-run.js: -------------------------------------------------------------------------------- 1 | const anagramGrouping = require('./anagram-grouping'); 2 | 3 | const result = anagramGrouping(['cat', 'act', 'dog', 'god', 'tac']); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/06-anagram-grouping/anagram-grouping-solution.js: -------------------------------------------------------------------------------- 1 | function anagramGrouping(words) { 2 | const anagramGroups = new Map(); 3 | 4 | for (const word of words) { 5 | // Sort the characters of the word alphabetically. 6 | const sortedChars = word.split('').sort().join(''); 7 | 8 | // If the sorted characters are already in the map, add the word to the array. 9 | if (anagramGroups.has(sortedChars)) { 10 | // The array is already in the map, so we can push to it. 11 | anagramGroups.get(sortedChars).push(word); 12 | } else { 13 | // The array is not in the map, so we need to create it. 14 | anagramGroups.set(sortedChars, [word]); 15 | } 16 | } 17 | 18 | // Return the values of the map as an array. 19 | return Array.from(anagramGroups.values()); 20 | } 21 | 22 | module.exports = anagramGrouping; 23 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/06-anagram-grouping/anagram-grouping-test.js: -------------------------------------------------------------------------------- 1 | const anagramGrouping = require('./anagram-grouping'); 2 | 3 | test('Grouping anagrams', () => { 4 | const result1 = anagramGrouping(['cat', 'act', 'dog', 'god', 'tac']); 5 | const result2 = anagramGrouping([ 6 | 'listen', 7 | 'silent', 8 | 'enlist', 9 | 'hello', 10 | 'world', 11 | ]); 12 | 13 | expect(result1).toEqual([ 14 | ['cat', 'act', 'tac'], 15 | ['dog', 'god'], 16 | ]); 17 | expect(result2).toEqual([ 18 | ['listen', 'silent', 'enlist'], 19 | ['hello'], 20 | ['world'], 21 | ]); 22 | }); 23 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/06-anagram-grouping/anagram-grouping.js: -------------------------------------------------------------------------------- 1 | function anagramGrouping() {} 2 | 3 | module.exports = anagramGrouping; 4 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/07-sets/sets-done.js: -------------------------------------------------------------------------------- 1 | // Create a set (try adding duplicate Values) 2 | const nameSet = new Set(['John', 'Jane', 'Joe', 'John', 'Joe']); 3 | 4 | // Add values to set 5 | nameSet.add('Jack'); 6 | nameSet.add('Jill'); 7 | 8 | console.log(nameSet); 9 | 10 | // Check for values 11 | console.log(nameSet.has('Jill')); 12 | 13 | // Delete from set 14 | nameSet.delete('Jill'); 15 | 16 | console.log(nameSet); 17 | 18 | // Get size of set 19 | console.log(nameSet.size); 20 | 21 | // Get all values from set 22 | console.log(nameSet.values()); 23 | 24 | // Iterate through set 25 | for (const name of nameSet) { 26 | console.log(name); 27 | } 28 | 29 | // Convert set to array 30 | const nameArray = [...nameSet]; 31 | console.log(nameArray); 32 | 33 | // Clear set 34 | nameSet.clear(); 35 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/07-sets/sets.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/06-hash-tables-maps-sets/07-sets/sets.js -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/08-symmetric-difference/symmetric-difference-solution.js: -------------------------------------------------------------------------------- 1 | function symmetricDifference(arr1, arr2) { 2 | // Create a set from arr1 and arr2 3 | const set1 = new Set(arr1); 4 | const set2 = new Set(arr2); 5 | // Create a result array 6 | const result = []; 7 | 8 | // Iterate through arr1 and check if the current number is not in set2 9 | for (const num of arr1) { 10 | if (!set2.has(num)) { 11 | // If it is not in set2, push it to the result array 12 | result.push(num); 13 | } 14 | } 15 | 16 | // Iterate through arr2 and check if the current number is not in set1 17 | for (const num of arr2) { 18 | // If it is not in set1, push it to the result array 19 | if (!set1.has(num)) { 20 | result.push(num); 21 | } 22 | } 23 | 24 | // Return the result array 25 | return result; 26 | } 27 | 28 | module.exports = symmetricDifference; 29 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/08-symmetric-difference/symmetric-difference-test.js: -------------------------------------------------------------------------------- 1 | const symmetricDifference = require('./symmetric-difference'); 2 | 3 | test('Symmetric Difference of Two Arrays', () => { 4 | expect(symmetricDifference([1, 2, 3], [3, 4, 5])).toEqual([1, 2, 4, 5]); 5 | expect(symmetricDifference([1, 2, 2, 3, 4], [2, 3, 3, 4, 5])).toEqual([1, 5]); 6 | expect(symmetricDifference([1, 2, 3, 4, 5], [5, 4, 3, 2, 1])).toEqual([]); 7 | expect(symmetricDifference([1, 2, 3], [4, 5, 6])).toEqual([1, 2, 3, 4, 5, 6]); 8 | }); 9 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/08-symmetric-difference/symmetric-difference.js: -------------------------------------------------------------------------------- 1 | function symmetricDifference() {} 2 | 3 | module.exports = symmetricDifference; 4 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/08-symmetric-difference/symmetric-diiference-run.js: -------------------------------------------------------------------------------- 1 | const symmetricDifference = require('./symmetric-difference'); 2 | 3 | const result = symmetricDifference([1, 2, 3], [2, 3, 4]); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/09-two-sum/two-sum-run.js: -------------------------------------------------------------------------------- 1 | const twoSum = require('./two-sum'); 2 | 3 | const result = twoSum([2, 7, 11, 15], 17); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/09-two-sum/two-sum-solution.js: -------------------------------------------------------------------------------- 1 | function twoSum(nums, target) { 2 | // Create a Set to store numbers that have been seen 3 | const numSet = new Set(); 4 | 5 | // Iterate through the input array 6 | for (let i = 0; i < nums.length; i++) { 7 | // Calculate the complement needed to reach the target sum 8 | // nums[i] represents the current number being iterated in the array. 9 | // target is the desired sum we're trying to achieve with two numbers. 10 | // target - nums[i] calculates the difference between the target sum and the current number. This value is the complement. 11 | const complement = target - nums[i]; 12 | 13 | // If the complement is found in the numSet, return the indices of the two numbers 14 | if (numSet.has(complement)) { 15 | return [nums.indexOf(complement), i]; 16 | } 17 | 18 | // Add the current number to the numSet 19 | numSet.add(nums[i]); 20 | } 21 | 22 | // If no solution is found, return an empty array 23 | return []; 24 | } 25 | 26 | module.exports = twoSum; 27 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/09-two-sum/two-sum-test.js: -------------------------------------------------------------------------------- 1 | const twoSum = require('./two-sum'); 2 | 3 | describe('Two Sum', () => { 4 | test('Test 1', () => { 5 | const nums = [2, 7, 11, 15]; 6 | const target = 9; 7 | const result = twoSum(nums, target); 8 | expect(result).toEqual(expect.arrayContaining([0, 1])); 9 | }); 10 | 11 | test('Test 2', () => { 12 | const nums = [3, 2, 4]; 13 | const target = 6; 14 | const result = twoSum(nums, target); 15 | expect(result).toEqual(expect.arrayContaining([1, 2])); 16 | }); 17 | 18 | test('Test 3', () => { 19 | const nums = [3, 3]; 20 | const target = 6; 21 | const result = twoSum(nums, target); 22 | expect(result).toEqual(expect.arrayContaining([0, 1])); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/09-two-sum/two-sum.js: -------------------------------------------------------------------------------- 1 | function twoSum() {} 2 | 3 | module.exports = twoSum; 4 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/10-longest-consecutive/logest-consecutive-test.js: -------------------------------------------------------------------------------- 1 | const longestConsecutiveSequence = require('./longest-consecutive'); 2 | 3 | test('Longest Consecutive Sequence', () => { 4 | expect(longestConsecutiveSequence([100, 4, 200, 1, 3, 2])).toBe(4); 5 | expect(longestConsecutiveSequence([0, 3, 7, 2, 5, 8, 4, 6, 9, 1])).toBe(10); 6 | }); 7 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/10-longest-consecutive/longest-consecutive-run.js: -------------------------------------------------------------------------------- 1 | const longestConsecutiveSequence = require('./longest-consecutive'); 2 | 3 | const result = longestConsecutiveSequence([100, 4, 200, 1, 3, 2]); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/10-longest-consecutive/longest-consecutive-solution.js: -------------------------------------------------------------------------------- 1 | function longestConsecutiveSequence(nums) { 2 | // Create new set 3 | const numSet = new Set(nums); 4 | // Create longest sequence variable 5 | let longestSequence = 0; 6 | 7 | // Loop through set 8 | for (const num of numSet) { 9 | // If set does not have num - 1. Identify the starting element of a potential consecutive sequence. 10 | if (!numSet.has(num - 1)) { 11 | // Create current num and current sequence variables 12 | let currentNum = num; 13 | let currentSequence = 1; 14 | 15 | // While set has current num + 1. Is the next consecutive number in the set? 16 | while (numSet.has(currentNum + 1)) { 17 | // Increment current num and current sequence 18 | currentNum++; 19 | currentSequence++; 20 | } 21 | 22 | // Set longest sequence to max of longest sequence and current sequence 23 | longestSequence = Math.max(longestSequence, currentSequence); 24 | } 25 | } 26 | 27 | // Return longest sequence 28 | return longestSequence; 29 | } 30 | 31 | module.exports = longestConsecutiveSequence; 32 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/10-longest-consecutive/longest-consecutive.js: -------------------------------------------------------------------------------- 1 | function longestConsecutiveSequence() {} 2 | 3 | module.exports = longestConsecutiveSequence; 4 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/11-custom-hash-table/custom-hash-table-run.js: -------------------------------------------------------------------------------- 1 | const HashTable = require('./custom-hash-table'); 2 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/11-custom-hash-table/custom-hash-table-test.js: -------------------------------------------------------------------------------- 1 | const HashTable = require('./custom-hash-table'); 2 | 3 | describe('HashTable', () => { 4 | let hashTable; 5 | 6 | beforeEach(() => { 7 | hashTable = new HashTable(); 8 | }); 9 | 10 | test('Set and get a key-value pair', () => { 11 | hashTable.set('firstName', 'John'); 12 | expect(hashTable.get('firstName')).toBe('John'); 13 | }); 14 | 15 | test('Set and get multiple key-value pairs', () => { 16 | hashTable.set('firstName', 'John'); 17 | hashTable.set('lastName', 'Smith'); 18 | hashTable.set('age', 30); 19 | 20 | expect(hashTable.get('firstName')).toBe('John'); 21 | expect(hashTable.get('lastName')).toBe('Smith'); 22 | expect(hashTable.get('age')).toBe(30); 23 | }); 24 | 25 | test('Get a value for a non-existent key', () => { 26 | expect(hashTable.get('city')).toBeUndefined(); 27 | }); 28 | 29 | test('Remove a key-value pair', () => { 30 | hashTable.set('firstName', 'John'); 31 | hashTable.remove('firstName'); 32 | 33 | expect(hashTable.get('firstName')).toBeUndefined(); 34 | }); 35 | 36 | test('Remove a non-existent key-value pair', () => { 37 | hashTable.set('firstName', 'John'); 38 | hashTable.remove('lastName'); 39 | 40 | expect(hashTable.get('firstName')).toBe('John'); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/11-custom-hash-table/custom-hash-table.js: -------------------------------------------------------------------------------- 1 | class HashTable {} 2 | 3 | module.exports = HashTable; 4 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/12-word-instance-counter/word-instance-counter-run.js: -------------------------------------------------------------------------------- 1 | const wordInstanceCounter = require('./word-instance-counter'); 2 | 3 | const result = wordInstanceCounter( 4 | 'The quick brown fox jumps over the lazy dog.', 5 | 'brown' 6 | ); 7 | 8 | console.log(result); 9 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/12-word-instance-counter/word-instance-counter-solution.js: -------------------------------------------------------------------------------- 1 | const HashTable = require('./HashTable'); 2 | 3 | function wordInstanceCounter(str, word) { 4 | // Convert the input string to lowercase and split it into an array of words 5 | const words = str.toLowerCase().split(/\W+/); 6 | 7 | // Create a new instance of the HashTable class to store word frequencies 8 | const wordFrequency = new HashTable(); 9 | 10 | // Convert the target word to lowercase for case-insensitive comparison 11 | const targetWord = word.toLowerCase(); 12 | 13 | // Initialize a count variable to store the number of instances of the target word 14 | let count = 0; 15 | 16 | // Loop through each word in the array of words 17 | for (const currentWord of words) { 18 | // Ignore empty strings (caused by multiple spaces or punctuation marks) 19 | if (currentWord === '') continue; 20 | 21 | // Check if the current word already exists in the HashTable 22 | if (wordFrequency.has(currentWord)) { 23 | // If the word exists, increment its frequency by 1 24 | wordFrequency.set(currentWord, wordFrequency.get(currentWord) + 1); 25 | } else { 26 | // If the word doesn't exist, add it to the HashTable with a frequency of 1 27 | wordFrequency.set(currentWord, 1); 28 | } 29 | 30 | // Check if the current word is the target word 31 | if (currentWord === targetWord) { 32 | // Get the frequency of the target word from the HashTable 33 | count = wordFrequency.get(currentWord); 34 | } 35 | } 36 | 37 | // Return the count of instances of the target word 38 | return count; 39 | } 40 | 41 | module.exports = wordInstanceCounter; 42 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/12-word-instance-counter/word-instance-counter-test.js: -------------------------------------------------------------------------------- 1 | const wordInstanceCounter = require('./word-instance-counter') 2 | 3 | test('Counting instances of a word in a string', () => { 4 | expect( 5 | wordInstanceCounter('The quick brown fox jumps over the lazy dog.', 'the') 6 | ).toBe(2); 7 | expect( 8 | wordInstanceCounter( 9 | 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 10 | 'ipsum' 11 | ) 12 | ).toBe(1); 13 | expect(wordInstanceCounter('Hello, world!', 'hello')).toBe(1); 14 | expect(wordInstanceCounter('Hello, Hello, Hello!', 'hello')).toBe(3); 15 | }); 16 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/12-word-instance-counter/word-instance-counter.js: -------------------------------------------------------------------------------- 1 | const HashTable = require('./HashTable'); 2 | 3 | function wordInstanceCounter() {} 4 | 5 | module.exports = wordInstanceCounter; 6 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/13-add-get-values-method/get-values-run.js: -------------------------------------------------------------------------------- 1 | const HashTable = require('./HashTable'); 2 | 3 | const myHashTable = new HashTable(); 4 | 5 | myHashTable.set('a', 1); 6 | myHashTable.set('b', 2); 7 | myHashTable.set('c', 3); 8 | myHashTable.set('d', 4); 9 | 10 | console.log(myHashTable.getValues()); 11 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/13-add-get-values-method/get-values-solution.js: -------------------------------------------------------------------------------- 1 | class HashTable { 2 | // Rest of the class 3 | 4 | // Get an array of all values in the hash table 5 | getValues() { 6 | // Create an empty array to store the values 7 | const values = []; 8 | 9 | // Loop through each bucket in the storage 10 | for (let i = 0; i < this.storage.length; i++) { 11 | // Check if the bucket is not empty 12 | if (this.storage[i]) { 13 | // Iterate through each key-value pair in the bucket 14 | for (const [key, value] of this.storage[i]) { 15 | // Push the value to the values array 16 | values.push(value); 17 | } 18 | } 19 | } 20 | 21 | // Return the array of values 22 | return values; 23 | } 24 | } 25 | 26 | module.exports = HashTable; 27 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/13-add-get-values-method/get-values-test.js: -------------------------------------------------------------------------------- 1 | const HashTable = require('./HashTable'); 2 | 3 | describe('HashTable', () => { 4 | let hashTable; 5 | 6 | beforeEach(() => { 7 | hashTable = new HashTable(); 8 | }); 9 | 10 | test('Get values from hash table', () => { 11 | hashTable.set('name', 'Alice'); 12 | hashTable.set('age', 30); 13 | hashTable.set('city', 'New York'); 14 | 15 | const values = hashTable.getValues(); 16 | expect(values).toEqual(expect.arrayContaining(['Alice', 30, 'New York'])); 17 | expect(values).toHaveLength(3); 18 | }); 19 | 20 | test('Get values from an empty hash table', () => { 21 | const values = hashTable.getValues(); 22 | expect(values).toEqual([]); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/14-custom-anagram-grouping/custom-anagram-grouping-run.js: -------------------------------------------------------------------------------- 1 | const anagramGrouping = require('./custom-anagram-grouping'); 2 | 3 | const words = ['cat', 'act', 'silent', 'listen', 'tac', 'hello', 'foo', 'bar']; 4 | 5 | const result = anagramGrouping(words); 6 | 7 | console.log(result); 8 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/14-custom-anagram-grouping/custom-anagram-grouping-solution.js: -------------------------------------------------------------------------------- 1 | const HashTable = require('./HashTable'); 2 | 3 | function anagramGrouping(words) { 4 | // Create a new HashTable instance 5 | const anagramGroups = new HashTable(); 6 | 7 | // Loop through each word in the words array 8 | for (const word of words) { 9 | // Sort the word's characters alphabetically 10 | const sortedChars = word.split('').sort().join(''); 11 | // If the sorted characters are already in the HashTable, push the word to the array 12 | if (anagramGroups.get(sortedChars)) { 13 | anagramGroups.get(sortedChars).push(word); 14 | } else { 15 | // Otherwise, set the sorted characters as the key and the word as the value 16 | anagramGroups.set(sortedChars, [word]); 17 | } 18 | } 19 | 20 | // Return the values of the HashTable 21 | return anagramGroups.getValues(); 22 | } 23 | 24 | module.exports = anagramGrouping; 25 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/14-custom-anagram-grouping/custom-anagram-grouping-test.js: -------------------------------------------------------------------------------- 1 | const anagramGrouping = require('./custom-anagram-grouping'); 2 | 3 | describe('Anagram Grouping', () => { 4 | test('Grouping anagrams', () => { 5 | const words = [ 6 | 'listen', 7 | 'silent', 8 | 'hello', 9 | 'world', 10 | 'act', 11 | 'cat', 12 | 'dog', 13 | 'god', 14 | ]; 15 | 16 | const result = anagramGrouping(words); 17 | 18 | expect(result).toEqual( 19 | expect.arrayContaining([ 20 | expect.arrayContaining(['listen', 'silent']), 21 | expect.arrayContaining(['act', 'cat']), 22 | expect.arrayContaining(['dog', 'god']), 23 | expect.arrayContaining(['hello']), 24 | expect.arrayContaining(['world']), 25 | ]) 26 | ); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /06-hash-tables-maps-sets/14-custom-anagram-grouping/custom-anagram-grouping.js: -------------------------------------------------------------------------------- 1 | const HashTable = require('./HashTable'); 2 | 3 | function anagramGrouping() {} 4 | 5 | module.exports = anagramGrouping; 6 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/02-stack-implementation/stack-run.js: -------------------------------------------------------------------------------- 1 | const Stack = require('./stack'); 2 | 3 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/02-stack-implementation/stack-solution.js: -------------------------------------------------------------------------------- 1 | class Stack { 2 | constructor() { 3 | // The maximum number of elements the stack can hold. 4 | this.maxSize = 100; 5 | // The stack itself. 6 | this.stack = []; 7 | // The index of the top element in the stack. 8 | this.top = -1; 9 | } 10 | 11 | // Add an element to the top of the stack. 12 | push(value) { 13 | // If the stack is full, return false. 14 | if (this.isFull()) { 15 | return false; 16 | } 17 | // Increment the top index. 18 | this.top++; 19 | // Add the value to the top of the stack. 20 | this.stack[this.top] = value; 21 | return true; 22 | } 23 | 24 | // Remove the top element from the stack. 25 | pop() { 26 | if (this.isEmpty()) { 27 | return null; 28 | } 29 | this.top--; 30 | 31 | return this.stack.pop(); 32 | } 33 | 34 | // Get the value of the top element in the stack. 35 | peek() { 36 | // If the stack is empty, return null. 37 | if (this.isEmpty()) { 38 | return null; 39 | } 40 | // Return the value of the top element. 41 | return this.stack[this.top]; 42 | } 43 | 44 | // Check if the stack is empty. 45 | isEmpty() { 46 | // If the top index is -1, the stack is empty. 47 | return this.top === -1; 48 | } 49 | 50 | // Check if the stack is full. 51 | isFull() { 52 | // If the top index is equal to the maximum size of the stack, the stack is full. 53 | return this.top === this.maxSize - 1; 54 | } 55 | } 56 | 57 | module.exports = Stack; 58 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/02-stack-implementation/stack-test.js: -------------------------------------------------------------------------------- 1 | const Stack = require('./stack'); // Assuming the Stack class is in a separate file called Stack.js 2 | 3 | describe('Stack', () => { 4 | let stack; 5 | 6 | beforeEach(() => { 7 | stack = new Stack(); 8 | }); 9 | 10 | afterEach(() => { 11 | stack = null; 12 | }); 13 | 14 | test('push should add an element to the stack', () => { 15 | stack.push(1); 16 | expect(stack.peek()).toBe(1); 17 | }); 18 | 19 | test('pop should remove and return the top element from the stack', () => { 20 | stack.push(1); 21 | stack.push(2); 22 | const poppedElement = stack.pop(); 23 | expect(poppedElement).toBe(2); 24 | expect(stack.peek()).toBe(1); 25 | }); 26 | 27 | test('peek should return the top element without removing it', () => { 28 | stack.push(1); 29 | stack.push(2); 30 | expect(stack.peek()).toBe(2); 31 | expect(stack.pop()).toBe(2); 32 | expect(stack.peek()).toBe(1); 33 | }); 34 | 35 | test('isEmpty should return true if the stack is empty', () => { 36 | expect(stack.isEmpty()).toBe(true); 37 | stack.push(1); 38 | expect(stack.isEmpty()).toBe(false); 39 | stack.pop(); 40 | expect(stack.isEmpty()).toBe(true); 41 | }); 42 | 43 | test('isFull should return true if the stack is full', () => { 44 | expect(stack.isFull()).toBe(false); 45 | for (let i = 0; i < stack.maxSize; i++) { 46 | stack.push(i); 47 | } 48 | expect(stack.isFull()).toBe(true); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/02-stack-implementation/stack.js: -------------------------------------------------------------------------------- 1 | class Stack {} 2 | 3 | module.exports = Stack; 4 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/03-reverse-string-stack/reverse-string-stack-run.js: -------------------------------------------------------------------------------- 1 | const reverseStringStack = require('./reverse-string-stack'); 2 | 3 | const result = reverseStringStack('Hello World!'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/03-reverse-string-stack/reverse-string-stack-solution.js: -------------------------------------------------------------------------------- 1 | const Stack = require('./stack'); 2 | 3 | function reverseStringStack(str) { 4 | // Create a new stack 5 | const stack = new Stack(); 6 | 7 | // Push each character onto the stack 8 | for (let i = 0; i < str.length; i++) { 9 | stack.push(str[i]); 10 | } 11 | 12 | // Create a variable to store the reversed string 13 | let reversedString = ''; 14 | 15 | // Pop the characters from the stack to construct the reversed string 16 | while (!stack.isEmpty()) { 17 | reversedString += stack.pop(); 18 | } 19 | 20 | // Return the reversed string 21 | return reversedString; 22 | } 23 | 24 | module.exports = reverseStringStack; 25 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/03-reverse-string-stack/reverse-string-stack-test.js: -------------------------------------------------------------------------------- 1 | const reverseStringStack = require('./reverse-string-stack'); 2 | 3 | test('Reversing a string', () => { 4 | expect(reverseStringStack('Hello')).toBe('olleH'); 5 | expect(reverseStringStack('JavaScript')).toBe('tpircSavaJ'); 6 | expect(reverseStringStack('12345')).toBe('54321'); 7 | }); 8 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/03-reverse-string-stack/reverse-string-stack.js: -------------------------------------------------------------------------------- 1 | const Stack = require('./stack'); 2 | 3 | function reverseStringStack() {} 4 | 5 | module.exports = reverseStringStack; 6 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/03-reverse-string-stack/stack.js: -------------------------------------------------------------------------------- 1 | class Stack { 2 | constructor() { 3 | this.maxSize = 100; 4 | this.stack = []; 5 | this.top = -1; 6 | } 7 | 8 | push(value) { 9 | if (this.isFull()) { 10 | return false; 11 | } 12 | this.top++; 13 | this.stack[this.top] = value; 14 | return true; 15 | } 16 | 17 | pop() { 18 | if (this.isEmpty()) { 19 | return null; 20 | } 21 | this.top--; 22 | 23 | return this.stack.pop(); 24 | } 25 | 26 | peek() { 27 | if (this.isEmpty()) { 28 | return null; 29 | } 30 | return this.stack[this.top]; 31 | } 32 | 33 | isEmpty() { 34 | return this.top === -1; 35 | } 36 | 37 | isFull() { 38 | return this.top === this.maxSize - 1; 39 | } 40 | } 41 | 42 | module.exports = Stack; 43 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/04-balanced-parenthesis/balanced-parenthesis-run.js: -------------------------------------------------------------------------------- 1 | const balancedParenthesis = require('./balanced-parenthesis'); 2 | 3 | const result1 = balancedParenthesis('()()()'); 4 | const result2 = balancedParenthesis('()('); 5 | 6 | console.log(result1, result2); 7 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/04-balanced-parenthesis/balanced-parenthesis-solution.js: -------------------------------------------------------------------------------- 1 | const Stack = require('./stack'); 2 | 3 | function balancedParenthesis(str) { 4 | // Create a new stack 5 | const stack = new Stack(); 6 | 7 | // Loop through each character in str 8 | for (let i = 0; i < str.length; i++) { 9 | // If the character is '(', push it onto the stack 10 | if (str[i] === '(') { 11 | stack.push(str[i]); 12 | // If the character is ')', pop the stack 13 | } else if (str[i] === ')') { 14 | // If the stack is empty, return false 15 | if (stack.isEmpty()) { 16 | return false; 17 | } 18 | // If the stack is not empty, pop the stack 19 | stack.pop(); 20 | } 21 | } 22 | 23 | // If the stack is empty, return true 24 | return stack.isEmpty(); 25 | } 26 | 27 | module.exports = balancedParenthesis; 28 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/04-balanced-parenthesis/balanced-parenthesis-test.js: -------------------------------------------------------------------------------- 1 | const Stack = require('./stack'); 2 | const balancedParenthesis = require('./balanced-parenthesis'); 3 | 4 | describe('balancedParenthesis', () => { 5 | test('should return true for balanced parentheses', () => { 6 | expect(balancedParenthesis('()')).toBe(true); 7 | expect(balancedParenthesis('(())')).toBe(true); 8 | expect(balancedParenthesis('(()())')).toBe(true); 9 | expect(balancedParenthesis('((()))')).toBe(true); 10 | expect(balancedParenthesis('()()()')).toBe(true); 11 | expect(balancedParenthesis('()((()))()')).toBe(true); 12 | expect(balancedParenthesis('((()()(())))')).toBe(true); 13 | }); 14 | 15 | test('should return false for unbalanced parentheses', () => { 16 | expect(balancedParenthesis(')(')).toBe(false); 17 | expect(balancedParenthesis('((')).toBe(false); 18 | expect(balancedParenthesis('))')).toBe(false); 19 | expect(balancedParenthesis('())')).toBe(false); 20 | expect(balancedParenthesis('(()(()')).toBe(false); 21 | expect(balancedParenthesis('(()())(')).toBe(false); 22 | expect(balancedParenthesis('((()()(()))')).toBe(false); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/04-balanced-parenthesis/balanced-parenthesis.js: -------------------------------------------------------------------------------- 1 | const Stack = require('./stack'); 2 | 3 | function balancedParenthesis() {} 4 | 5 | module.exports = balancedParenthesis; 6 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/04-balanced-parenthesis/stack.js: -------------------------------------------------------------------------------- 1 | class Stack { 2 | constructor() { 3 | this.maxSize = 100; 4 | this.stack = []; 5 | this.top = -1; 6 | } 7 | 8 | push(value) { 9 | if (this.isFull()) { 10 | return false; 11 | } 12 | this.top++; 13 | this.stack[this.top] = value; 14 | return true; 15 | } 16 | 17 | pop() { 18 | if (this.isEmpty()) { 19 | return null; 20 | } 21 | this.top--; 22 | 23 | return this.stack.pop(); 24 | } 25 | 26 | peek() { 27 | if (this.isEmpty()) { 28 | return null; 29 | } 30 | return this.stack[this.top]; 31 | } 32 | 33 | isEmpty() { 34 | return this.top === -1; 35 | } 36 | 37 | isFull() { 38 | return this.top === this.maxSize - 1; 39 | } 40 | } 41 | 42 | module.exports = Stack; 43 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/06-queue-implementation/queue-run.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./queue'); 2 | 3 | const queue = new Queue(); 4 | console.log(queue.isEmpty()); 5 | console.log(queue.isFull()); 6 | console.log(queue.enqueue(1)); 7 | console.log(queue.enqueue(2)); 8 | console.log(queue.enqueue(3)); 9 | console.log(queue.peek()); 10 | console.log(queue.dequeue()); 11 | console.log(queue.peek()); 12 | console.log(queue.getLength()); 13 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/06-queue-implementation/queue.js: -------------------------------------------------------------------------------- 1 | class Queue {} 2 | 3 | module.exports = Queue; 4 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/07-reverse-string-queue/queue.js: -------------------------------------------------------------------------------- 1 | class Queue { 2 | constructor() { 3 | this.queue = []; 4 | this.head = 0; 5 | this.tail = 0; 6 | this.maxSize = 100; 7 | } 8 | 9 | enqueue(element) { 10 | if (this.isFull()) { 11 | return false; 12 | } 13 | this.queue[this.tail] = element; 14 | this.tail++; 15 | return true; 16 | } 17 | 18 | dequeue() { 19 | const item = this.queue[this.head]; 20 | this.head++; 21 | return item; 22 | } 23 | 24 | peek() { 25 | return this.queue[this.head]; 26 | } 27 | 28 | getLength() { 29 | return this.tail - this.head; 30 | } 31 | 32 | isEmpty() { 33 | return this.getLength() === 0; 34 | } 35 | 36 | isFull() { 37 | return this.getLength() === this.maxSize; 38 | } 39 | } 40 | 41 | module.exports = Queue; 42 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/07-reverse-string-queue/reverse-string-queue-run.js: -------------------------------------------------------------------------------- 1 | const reverseStringQueue = require('./reverse-string-queue'); 2 | 3 | const result = reverseStringQueue('Hello World!'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/07-reverse-string-queue/reverse-string-queue-solution.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./queue'); 2 | 3 | const reverseStringWithQueue = () => { 4 | // Create a new queue. 5 | const queue = new Queue(); 6 | 7 | // Enqueue each character in str. 8 | for (let i = str.length - 1; i >= 0; i--) { 9 | queue.enqueue(str[i]); 10 | } 11 | 12 | // Create a variable to store the reversed string. 13 | let reversedString = ''; 14 | 15 | // Dequeue the characters from the queue to construct the reversed string. 16 | while (!queue.isEmpty()) { 17 | reversedString += queue.dequeue(); 18 | } 19 | 20 | // Return the reversed string. 21 | return reversedString; 22 | }; 23 | 24 | module.exports = reverseStringWithQueue; 25 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/07-reverse-string-queue/reverse-string-queue-test.js: -------------------------------------------------------------------------------- 1 | const reverseStringQueue = require('./reverse-string-queue'); 2 | 3 | test('Reversing a string', () => { 4 | expect(reverseStringQueue('Hello')).toBe('olleH'); 5 | expect(reverseStringQueue('JavaScript')).toBe('tpircSavaJ'); 6 | expect(reverseStringQueue('12345')).toBe('54321'); 7 | }); 8 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/07-reverse-string-queue/reverse-string-queue.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./queue'); 2 | 3 | const reverseStringWithQueue = (str) => {}; 4 | 5 | module.exports = reverseStringWithQueue; 6 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/08-palindrome-queue-stack.js/palindrome-queue-stack-run.js: -------------------------------------------------------------------------------- 1 | const isPalindromeQueueStack = require('./palindrome-queue-stack'); 2 | 3 | const result1 = isPalindromeQueueStack('A man, a plan, a canal: Panama'); 4 | const result2 = isPalindromeQueueStack('Hello'); 5 | 6 | console.log(result1, result2); 7 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/08-palindrome-queue-stack.js/palindrome-queue-stack-solution.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./queue'); 2 | const Stack = require('./stack'); 3 | 4 | function isPalindromeQueueStack(str) { 5 | // Remove all non-alphanumeric characters from str and convert to lowercase. 6 | const formattedStr = str.replace(/[^a-zA-Z0-9]/g, '').toLowerCase(); 7 | 8 | // Create a new queue and a new stack. 9 | const charQueue = new Queue(); 10 | const charStack = new Stack(); 11 | 12 | // Enqueue each character in str to the queue and push each character in str to the stack. 13 | for (let i = 0; i < formattedStr.length; i++) { 14 | const char = formattedStr.charAt(i); 15 | charQueue.enqueue(char); 16 | charStack.push(char); 17 | } 18 | 19 | // Dequeue each character from the queue and pop each character from the stack. 20 | while (!charQueue.isEmpty()) { 21 | // If the dequeued character does not equal the popped character, return false. 22 | if (charQueue.dequeue() !== charStack.pop()) { 23 | return false; 24 | } 25 | } 26 | 27 | // Return true if the loop completes without returning false. 28 | return true; 29 | } 30 | 31 | module.exports = isPalindromeQueueStack; 32 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/08-palindrome-queue-stack.js/palindrome-queue-stack-test.js: -------------------------------------------------------------------------------- 1 | const isPalindromeQueueStack = require('./palindrome-queue-stack'); 2 | 3 | test('Checking for palindrome strings', () => { 4 | expect(isPalindromeQueueStack('racecar')).toBe(true); 5 | expect(isPalindromeQueueStack('Hello')).toBe(false); 6 | expect(isPalindromeQueueStack('A man, a plan, a canal, Panama')).toBe(true); 7 | expect(isPalindromeQueueStack('12321')).toBe(true); 8 | }); 9 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/08-palindrome-queue-stack.js/palindrome-queue-stack.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./queue'); 2 | const Stack = require('./stack'); 3 | 4 | function isPalindromeQueueStack() {} 5 | 6 | module.exports = isPalindromeQueueStack; 7 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/08-palindrome-queue-stack.js/queue.js: -------------------------------------------------------------------------------- 1 | class Queue { 2 | constructor() { 3 | this.queue = []; 4 | this.head = 0; 5 | this.tail = 0; 6 | this.maxSize = 100; 7 | } 8 | 9 | enqueue(element) { 10 | if (this.isFull()) { 11 | return false; 12 | } 13 | this.queue[this.tail] = element; 14 | this.tail++; 15 | return true; 16 | } 17 | 18 | dequeue() { 19 | const item = this.queue[this.head]; 20 | this.head++; 21 | return item; 22 | } 23 | 24 | peek() { 25 | return this.queue[this.head]; 26 | } 27 | 28 | getLength() { 29 | return this.tail - this.head; 30 | } 31 | 32 | isEmpty() { 33 | return this.getLength() === 0; 34 | } 35 | 36 | isFull() { 37 | return this.getLength() === this.maxSize; 38 | } 39 | } 40 | 41 | module.exports = Queue; 42 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/08-palindrome-queue-stack.js/stack.js: -------------------------------------------------------------------------------- 1 | class Stack { 2 | constructor() { 3 | this.maxSize = 100; 4 | this.stack = []; 5 | this.top = -1; 6 | } 7 | 8 | push(value) { 9 | if (this.isFull()) { 10 | return false; 11 | } 12 | this.top++; 13 | this.stack[this.top] = value; 14 | return true; 15 | } 16 | 17 | pop() { 18 | if (this.isEmpty()) { 19 | return null; 20 | } 21 | this.top--; 22 | 23 | return this.stack.pop(); 24 | } 25 | 26 | peek() { 27 | if (this.isEmpty()) { 28 | return null; 29 | } 30 | return this.stack[this.top]; 31 | } 32 | 33 | isEmpty() { 34 | return this.top === -1; 35 | } 36 | 37 | isFull() { 38 | return this.top === this.maxSize - 1; 39 | } 40 | } 41 | 42 | module.exports = Stack; 43 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/10-linked-list-implementation/linked-list-run.js: -------------------------------------------------------------------------------- 1 | const { LinkedList } = require('./linked-list'); 2 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/10-linked-list-implementation/linked-list.js: -------------------------------------------------------------------------------- 1 | class Node {} 2 | 3 | class LinkedList {} 4 | 5 | module.exports = { Node, LinkedList }; 6 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/11-reverse-string-linked-list/reverse-string-linked-list-run.js: -------------------------------------------------------------------------------- 1 | const reverseStringLinkedList = require('./reverse-string-linked-list'); 2 | 3 | const result = reverseStringLinkedList('Hello World!'); 4 | 5 | console.log(result); 6 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/11-reverse-string-linked-list/reverse-string-linked-list-solution.js: -------------------------------------------------------------------------------- 1 | const { LinkedList } = require('./linked-list'); 2 | 3 | function reverseStringLinkedList(str) { 4 | // Create a new linked list 5 | const list = new LinkedList(); 6 | 7 | // Add each character to the linked list 8 | for (let i = str.length - 1; i >= 0; i--) { 9 | list.add(str[i]); 10 | } 11 | 12 | // Create a variable to store the reversed string 13 | let reversedString = ''; 14 | // Start at the head of the linked list 15 | let current = list.head; 16 | 17 | // Loop through each node in the linked list 18 | while (current !== null) { 19 | // Add the data of the current node to the reversed string 20 | reversedString += current.data; 21 | // Move to the next node 22 | current = current.next; 23 | } 24 | 25 | // Return the reversed string 26 | return reversedString; 27 | } 28 | 29 | module.exports = reverseStringLinkedList; 30 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/11-reverse-string-linked-list/reverse-string-linked-list-test.js: -------------------------------------------------------------------------------- 1 | const reverseStringLinkedList = require('./reverse-string-linked-list'); 2 | 3 | test('Reversing a string', () => { 4 | expect(reverseStringLinkedList('Hello')).toBe('olleH'); 5 | expect(reverseStringLinkedList('JavaScript')).toBe('tpircSavaJ'); 6 | expect(reverseStringLinkedList('12345')).toBe('54321'); 7 | }); 8 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/11-reverse-string-linked-list/reverse-string-linked-list.js: -------------------------------------------------------------------------------- 1 | const { LinkedList } = require('./linked-list'); 2 | 3 | function reverseStringLinkedList() {} 4 | 5 | module.exports = reverseStringLinkedList; 6 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/13-find-middle/find-middle-run.js: -------------------------------------------------------------------------------- 1 | const findMiddle = require('./find-middle'); 2 | const { LinkedList } = require('./linked-list'); 3 | 4 | const list = new LinkedList(); 5 | list.add(1); 6 | list.add(2); 7 | list.add(3); 8 | list.add(4); 9 | list.add(5); 10 | list.add(6); 11 | list.add(7); 12 | 13 | console.log(findMiddle(list)); 14 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/13-find-middle/find-middle-solution.js: -------------------------------------------------------------------------------- 1 | function findMiddle(list) { 2 | // Both fast and slow start at the head 3 | let slow = list.head; 4 | let fast = list.head; 5 | // prev starts at null 6 | let prev = null; 7 | 8 | // Loop through the list 9 | while (fast !== null && fast.next !== null) { 10 | // Move fast forward by 2 nodes 11 | fast = fast.next.next; 12 | // Move slow forward by 1 node 13 | prev = slow; 14 | slow = slow.next; 15 | } 16 | 17 | if (fast === null) { 18 | // Even number of nodes 19 | return prev.next; 20 | } else { 21 | // Odd number of nodes 22 | return slow; 23 | } 24 | } 25 | 26 | module.exports = findMiddle; 27 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/13-find-middle/find-middle-test.js: -------------------------------------------------------------------------------- 1 | const { LinkedList } = require('./linked-list'); 2 | const findMiddle = require('./find-middle'); 3 | 4 | describe('findMiddle', () => { 5 | test('should return the middle node for a linked list with an odd number of nodes', () => { 6 | const list = new LinkedList(); 7 | list.add(1); 8 | list.add(2); 9 | list.add(3); 10 | list.add(4); 11 | list.add(5); 12 | 13 | const middleNode = findMiddle(list); 14 | expect(middleNode.data).toBe(3); 15 | }); 16 | 17 | test('should return the second middle node for a linked list with an even number of nodes', () => { 18 | const list = new LinkedList(); 19 | list.add(1); 20 | list.add(2); 21 | list.add(3); 22 | list.add(4); 23 | list.add(5); 24 | list.add(6); 25 | 26 | const middleNode = findMiddle(list); 27 | expect(middleNode.data).toBe(4); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/13-find-middle/find-middle.js: -------------------------------------------------------------------------------- 1 | function findMiddle() {} 2 | 3 | module.exports = findMiddle; 4 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/15-doubly-linked-list-implementation/doubly-linked-list-run.js: -------------------------------------------------------------------------------- 1 | const DoublyLinkedList = require('./doubly-linked-list'); 2 | 3 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/15-doubly-linked-list-implementation/doubly-linked-list.js: -------------------------------------------------------------------------------- 1 | function Node() {} 2 | 3 | function DoublyLinkedList() {} 4 | 5 | module.exports = DoublyLinkedList; 6 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/16-find-pair-sum/find-pair-sum-run.js: -------------------------------------------------------------------------------- 1 | const findPairSum = require('./find-pair-sum'); 2 | 3 | const nums = [2, 6, 12, 11, 6, 10]; 4 | const targetSum = 22; 5 | 6 | const result = findPairSum(nums, targetSum); -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/16-find-pair-sum/find-pair-sum-solution.js: -------------------------------------------------------------------------------- 1 | const DoublyLinkedList = require('./DoublyLinkedList'); 2 | 3 | function findPairSum(nums, targetSum) { 4 | // Init a doubly linked list to keep track of seen numbers 5 | const seen = new DoublyLinkedList(); 6 | 7 | // Loop through nums 8 | for (const num of nums) { 9 | // Calculate the difference between the target sum and the current number 10 | const difference = targetSum - num; 11 | // If the difference is in the seen list, return the pair 12 | if (seen.contains(difference)) { 13 | return [difference, num]; 14 | } 15 | // Otherwise, add the current number to the seen list 16 | seen.append(num); 17 | } 18 | 19 | // If no pair is found, return null 20 | return null; 21 | } 22 | 23 | module.exports = findPairSum; 24 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/16-find-pair-sum/find-pair-sum-test.js: -------------------------------------------------------------------------------- 1 | const findPairSum = require('./find-pair-sum'); 2 | 3 | describe('findPairSum', () => { 4 | it('should find a pair with the given target sum', () => { 5 | const nums = [2, 6, 3, 8, 10, 5]; 6 | const targetSum = 12; 7 | const pair = findPairSum(nums, targetSum); 8 | expect(pair).toEqual([2, 10]); 9 | }); 10 | 11 | it('should return null if no such pair exists', () => { 12 | const nums = [1, 2, 3, 4, 5]; 13 | const targetSum = 10; 14 | const pair = findPairSum(nums, targetSum); 15 | expect(pair).toBeNull(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /07-stacks-queues-linked-lists/16-find-pair-sum/find-pair-sum.js: -------------------------------------------------------------------------------- 1 | const DoublyLinkedList = require('./DoublyLinkedList'); 2 | 3 | function findPairSum() {} 4 | 5 | module.exports = findPairSum; 6 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/02-tree-node-class/tree-node-class-run.js: -------------------------------------------------------------------------------- 1 | const TreeNode = require('./tree-node-class'); 2 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/02-tree-node-class/tree-node-class-solution.js: -------------------------------------------------------------------------------- 1 | class TreeNode { 2 | constructor(value) { 3 | // The value of the node. 4 | this.value = value; 5 | // The left child of the node. 6 | this.left = null; 7 | // The right child of the node. 8 | this.right = null; 9 | } 10 | } 11 | 12 | // Add a bunch of nodes to the tree. 13 | const a = new TreeNode('a'); 14 | const b = new TreeNode('b'); 15 | const c = new TreeNode('c'); 16 | const d = new TreeNode('d'); 17 | const e = new TreeNode('e'); 18 | const f = new TreeNode('f'); 19 | 20 | // Set the left of the root to b and the right of the root to c. 21 | a.left = b; 22 | a.right = c; 23 | // Set the left of b to d and the right of b to e. 24 | b.left = d; 25 | b.right = e; 26 | // Set the right of c to f. 27 | c.right = f; 28 | 29 | module.exports = TreeNode; 30 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/02-tree-node-class/tree-node-class-test.js: -------------------------------------------------------------------------------- 1 | const TreeNode = require('./tree-node-class'); 2 | 3 | describe('Manual Binary Tree', () => { 4 | let a, b, c, d, e, f; 5 | 6 | beforeEach(() => { 7 | a = new TreeNode('a'); 8 | b = new TreeNode('b'); 9 | c = new TreeNode('c'); 10 | d = new TreeNode('d'); 11 | e = new TreeNode('e'); 12 | f = new TreeNode('f'); 13 | 14 | a.left = b; 15 | a.right = c; 16 | b.left = d; 17 | b.right = e; 18 | c.right = f; 19 | }); 20 | 21 | test('Nodes are correctly connected', () => { 22 | expect(a.left).toBe(b); 23 | expect(a.right).toBe(c); 24 | expect(b.left).toBe(d); 25 | expect(b.right).toBe(e); 26 | expect(c.right).toBe(f); 27 | }); 28 | 29 | test('Node values are correct', () => { 30 | expect(a.value).toBe('a'); 31 | expect(b.value).toBe('b'); 32 | expect(c.value).toBe('c'); 33 | expect(d.value).toBe('d'); 34 | expect(e.value).toBe('e'); 35 | expect(f.value).toBe('f'); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/02-tree-node-class/tree-node-class.js: -------------------------------------------------------------------------------- 1 | class TreeNode {} 2 | 3 | module.exports = TreeNode; 4 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/03-depth-first-traversal/depth-first-traversal-run.js: -------------------------------------------------------------------------------- 1 | const { Node, depthFirstTraversal } = require('./depth-first-traversal'); 2 | 3 | // Create a binary tree: a 4 | // / \ 5 | // b c 6 | // / \ / 7 | // d e f 8 | 9 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/03-depth-first-traversal/depth-first-traversal-test.js: -------------------------------------------------------------------------------- 1 | const { Node, depthFirstTraversal } = require('./depth-first-traversal'); 2 | 3 | describe('Depth First Traversal', () => { 4 | test('Should perform depth-first traversal on the binary tree', () => { 5 | // Create a binary tree: a 6 | // / \ 7 | // b c 8 | // / \ / 9 | // d e f 10 | 11 | const root = new Node('a'); 12 | const nodeB = new Node('b'); 13 | const nodeC = new Node('c'); 14 | const nodeD = new Node('d'); 15 | const nodeE = new Node('e'); 16 | const nodeF = new Node('f'); 17 | 18 | root.left = nodeB; 19 | root.right = nodeC; 20 | nodeB.left = nodeD; 21 | nodeB.right = nodeE; 22 | nodeC.left = nodeF; 23 | 24 | expect(depthFirstTraversal(root)).toEqual(['a', 'b', 'd', 'e', 'c', 'f']); 25 | }); 26 | 27 | test('Should return an empty array for an empty tree', () => { 28 | expect(depthFirstTraversal(null)).toEqual([]); 29 | }); 30 | 31 | test('Should handle a tree with only the root node', () => { 32 | const root = new Node('root'); 33 | expect(depthFirstTraversal(root)).toEqual(['root']); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/03-depth-first-traversal/depth-first-traversal.js: -------------------------------------------------------------------------------- 1 | const Stack = require('./stack'); 2 | 3 | class Node {} 4 | 5 | function depthFirstTraversal() {} 6 | 7 | module.exports = { 8 | Node, 9 | depthFirstTraversal, 10 | }; 11 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/03-depth-first-traversal/stack.js: -------------------------------------------------------------------------------- 1 | class Stack { 2 | constructor() { 3 | this.maxSize = 100; 4 | this.stack = []; 5 | this.top = -1; 6 | } 7 | 8 | push(value) { 9 | if (this.isFull()) { 10 | return false; 11 | } 12 | this.top++; 13 | this.stack[this.top] = value; 14 | return true; 15 | } 16 | 17 | pop() { 18 | if (this.isEmpty()) { 19 | return null; 20 | } 21 | this.top--; 22 | 23 | return this.stack.pop(); 24 | } 25 | 26 | peek() { 27 | if (this.isEmpty()) { 28 | return null; 29 | } 30 | return this.stack[this.top]; 31 | } 32 | 33 | isEmpty() { 34 | return this.top === -1; 35 | } 36 | 37 | isFull() { 38 | return this.top === this.maxSize - 1; 39 | } 40 | } 41 | 42 | module.exports = Stack; 43 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/04-depth-first-traversal-recursive/depth-first-traversal-recursive-run.js: -------------------------------------------------------------------------------- 1 | const { Node, depthFirstTraversal } = require('./depth-first-traversal'); 2 | 3 | // Create a binary tree: a 4 | // / \ 5 | // b c 6 | // / \ / 7 | // d e f 8 | 9 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/04-depth-first-traversal-recursive/depth-first-traversal-recursive-solution.js: -------------------------------------------------------------------------------- 1 | // Node class 2 | class Node { 3 | constructor(data) { 4 | this.data = data; 5 | this.left = null; 6 | this.right = null; 7 | } 8 | } 9 | 10 | function recDepthFirstTraversal(root) { 11 | // If the root is null, return an empty array. 12 | const result = []; 13 | 14 | // Create a recursive helper function. 15 | function traverse(node) { 16 | // If the node is not null: 17 | if (node !== null) { 18 | // Add the node's data to the result. 19 | result.push(node.data); 20 | // Traverse the left subtree. 21 | traverse(node.left); 22 | // Traverse the right subtree. 23 | traverse(node.right); 24 | } 25 | } 26 | 27 | // Invoke the recursive helper function on the root. 28 | traverse(root); 29 | // Return the result. 30 | return result; 31 | } 32 | 33 | module.exports = { 34 | Node, 35 | recDepthFirstTraversal, 36 | }; 37 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/04-depth-first-traversal-recursive/depth-first-traversal-recursive-test.js: -------------------------------------------------------------------------------- 1 | const { 2 | Node, 3 | recDepthFirstTraversal, 4 | } = require('./depth-first-traversal-recursive'); 5 | 6 | // Test tree: a -> b -> d 7 | // \-> e 8 | // -> c -> f 9 | const root = new Node('a'); 10 | root.left = new Node('b'); 11 | root.right = new Node('c'); 12 | root.left.left = new Node('d'); 13 | root.left.right = new Node('e'); 14 | root.right.left = new Node('f'); 15 | 16 | test('Depth First Traversal', () => { 17 | expect(recDepthFirstTraversal(root)).toEqual(['a', 'b', 'd', 'e', 'c', 'f']); 18 | }); 19 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/04-depth-first-traversal-recursive/depth-first-traversal-recursive.js: -------------------------------------------------------------------------------- 1 | class Node {} 2 | 3 | function recDepthFirstTraversal() {} 4 | 5 | module.exports = { 6 | Node, 7 | recDepthFirstTraversal, 8 | }; 9 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/05-breadth-first-traversal/breadth-first-traversal-run.js: -------------------------------------------------------------------------------- 1 | const { Node, breadthFirstTraversal } = require('./breadth-first-traversal'); 2 | 3 | // Create a binary tree: a 4 | // / \ 5 | // b c 6 | // / \ / 7 | // d e f 8 | 9 | const root = new Node('a'); 10 | const nodeB = new Node('b'); 11 | const nodeC = new Node('c'); 12 | const nodeD = new Node('d'); 13 | const nodeE = new Node('e'); 14 | const nodeF = new Node('f'); 15 | 16 | root.left = nodeB; 17 | root.right = nodeC; 18 | nodeB.left = nodeD; 19 | nodeB.right = nodeE; 20 | nodeC.left = nodeF; 21 | 22 | const result = breadthFirstTraversal(root); 23 | 24 | console.log(result); 25 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/05-breadth-first-traversal/breadth-first-traversal-test.js: -------------------------------------------------------------------------------- 1 | const { Node, breadthFirstTraversal } = require('./breadth-first-traversal'); 2 | 3 | describe('Breadth-First Traversal', () => { 4 | test('Should perform breadth-first traversal on the binary tree', () => { 5 | // Create a binary tree: a 6 | // / \ 7 | // b c 8 | // / \ / 9 | // d e f 10 | 11 | const root = new Node('a'); 12 | const nodeB = new Node('b'); 13 | const nodeC = new Node('c'); 14 | const nodeD = new Node('d'); 15 | const nodeE = new Node('e'); 16 | const nodeF = new Node('f'); 17 | 18 | root.left = nodeB; 19 | root.right = nodeC; 20 | nodeB.left = nodeD; 21 | nodeB.right = nodeE; 22 | nodeC.left = nodeF; 23 | 24 | expect(breadthFirstTraversal(root)).toEqual(['a', 'b', 'c', 'd', 'e', 'f']); 25 | }); 26 | 27 | test('Should return an empty array for an empty tree', () => { 28 | expect(breadthFirstTraversal(null)).toEqual([]); 29 | }); 30 | 31 | test('Should handle a tree with only the root node', () => { 32 | const root = new Node('root'); 33 | expect(breadthFirstTraversal(root)).toEqual(['root']); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/05-breadth-first-traversal/breadth-first-traversal.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./queue'); 2 | 3 | class Node {} 4 | 5 | function breadthFirstTraversal() {} 6 | 7 | module.exports = { 8 | Node, 9 | breadthFirstTraversal, 10 | }; 11 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/05-breadth-first-traversal/queue.js: -------------------------------------------------------------------------------- 1 | class Queue { 2 | constructor() { 3 | this.queue = []; 4 | this.head = 0; 5 | this.tail = 0; 6 | this.maxSize = 100; 7 | } 8 | 9 | enqueue(element) { 10 | if (this.isFull()) { 11 | return false; 12 | } 13 | this.queue[this.tail] = element; 14 | this.tail++; 15 | return true; 16 | } 17 | 18 | dequeue() { 19 | const item = this.queue[this.head]; 20 | this.head++; 21 | return item; 22 | } 23 | 24 | peek() { 25 | return this.queue[this.head]; 26 | } 27 | 28 | getLength() { 29 | return this.tail - this.head; 30 | } 31 | 32 | isEmpty() { 33 | return this.getLength() === 0; 34 | } 35 | 36 | isFull() { 37 | return this.getLength() === this.maxSize; 38 | } 39 | } 40 | 41 | // const queue = new Queue(); 42 | // console.log(queue.isEmpty()); // true 43 | // console.log(queue.isFull()); // false 44 | // console.log(queue.enqueue(1)); // true 45 | // console.log(queue.enqueue(2)); // true 46 | // console.log(queue.enqueue(3)); // true 47 | // console.log(queue.peek()); // 1 48 | // console.log(queue.dequeue()); // 1 49 | // console.log(queue.peek()); // 2 50 | // console.log(queue.getLength()); // 2 51 | 52 | module.exports = Queue; 53 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/06-maximum-depth/maximum-depth-run.js: -------------------------------------------------------------------------------- 1 | const { Node, maxDepth } = require('./maximum-depth'); 2 | 3 | // Create the binary tree: 3 4 | // / \ 5 | // 9 20 6 | // / \ 7 | // 15 7 8 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/06-maximum-depth/maximum-depth-solution.js: -------------------------------------------------------------------------------- 1 | // Node class 2 | class Node { 3 | constructor(val) { 4 | this.val = val; 5 | this.left = null; 6 | this.right = null; 7 | } 8 | } 9 | 10 | function maxDepth(root) { 11 | // If the root is null, return 0. 12 | if (!root) { 13 | return 0; 14 | } 15 | 16 | // Recursively call maxDepth on the left and right subtrees. 17 | const leftDepth = maxDepth(root.left); 18 | const rightDepth = maxDepth(root.right); 19 | 20 | // Return the max of the left and right depths, plus 1. We add 1 to account for the root. 21 | return Math.max(leftDepth, rightDepth) + 1; 22 | } 23 | 24 | module.exports = { 25 | maxDepth, 26 | Node, 27 | }; 28 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/06-maximum-depth/maximum-depth-test.js: -------------------------------------------------------------------------------- 1 | const { Node, maxDepth } = require('./maximum-depth'); 2 | 3 | describe('Binary Tree Maximum Depth', () => { 4 | test('Should calculate the maximum depth of a binary tree', () => { 5 | // Create the binary tree: 3 6 | // / \ 7 | // 9 20 8 | // / \ 9 | // 15 7 10 | 11 | const root = new Node(3); 12 | const node9 = new Node(9); 13 | const node20 = new Node(20); 14 | const node15 = new Node(15); 15 | const node7 = new Node(7); 16 | 17 | root.left = node9; 18 | root.right = node20; 19 | node20.left = node15; 20 | node20.right = node7; 21 | 22 | expect(maxDepth(root)).toBe(3); 23 | }); 24 | 25 | test('Should handle a tree with a single root node', () => { 26 | const root = new Node(1); 27 | expect(maxDepth(root)).toBe(1); 28 | }); 29 | 30 | test('Should calculate the maximum depth of a binary tree with only left children', () => { 31 | // Create the binary tree: 1 32 | // / 33 | // 2 34 | // / 35 | // 3 36 | // / 37 | // 4 38 | 39 | const root = new Node(1); 40 | const node2 = new Node(2); 41 | const node3 = new Node(3); 42 | const node4 = new Node(4); 43 | 44 | root.left = node2; 45 | node2.left = node3; 46 | node3.left = node4; 47 | 48 | expect(maxDepth(root)).toBe(4); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/06-maximum-depth/maximum-depth.js: -------------------------------------------------------------------------------- 1 | class Node {} 2 | 3 | function maxDepth() {} 4 | 5 | module.exports = { 6 | maxDepth, 7 | Node, 8 | }; 9 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/08-binary-search-tree-implementation/binary-search-tree-run.js: -------------------------------------------------------------------------------- 1 | const { Node, BinarySearchTree } = require('./binary-search-tree'); 2 | 3 | // Create a binary search tree: 4 | // 10 5 | // / \ 6 | // 5 15 7 | // / 8 | // 2 9 | 10 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/08-binary-search-tree-implementation/binary-search-tree.js: -------------------------------------------------------------------------------- 1 | class Node {} 2 | 3 | class BinarySearchTree {} 4 | 5 | module.exports = { Node, BinarySearchTree }; 6 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/09-validate-bst/validate-bst-run.js: -------------------------------------------------------------------------------- 1 | const { Node, isValidBST } = require('./validate-bst'); 2 | 3 | // Create the binary tree: 4 | // 8 5 | // / \ 6 | // 4 10 7 | // / \ 8 | // 2 6 9 | 10 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/09-validate-bst/validate-bst-solution.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(value) { 3 | this.value = value; 4 | this.left = null; 5 | this.right = null; 6 | } 7 | } 8 | 9 | function isValidBST(root) { 10 | // Helper function to check if all values in a subtree are within the specified range 11 | function isValidSubtree(node, min, max) { 12 | if (!node) { 13 | return true; 14 | } 15 | 16 | if ( 17 | (min !== null && node.value <= min) || 18 | (max !== null && node.value >= max) 19 | ) { 20 | return false; 21 | } 22 | 23 | // For the left subtree, values must be less than the current node's value (max = node.value) 24 | // For the right subtree, values must be greater than the current node's value (min = node.value) 25 | return ( 26 | isValidSubtree(node.left, min, node.value) && 27 | isValidSubtree(node.right, node.value, max) 28 | ); 29 | } 30 | 31 | // Call the helper function on the root with initial range of null 32 | return isValidSubtree(root, null, null); 33 | } 34 | 35 | module.exports = { Node, isValidBST }; 36 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/09-validate-bst/validate-bst-test.js: -------------------------------------------------------------------------------- 1 | const { Node, isValidBST } = require('./validate-bst'); 2 | 3 | describe('isValidBST', () => { 4 | it('should return true for a valid binary search tree', () => { 5 | const root = new Node(8); 6 | const node4 = new Node(4); 7 | const node10 = new Node(10); 8 | const node2 = new Node(2); 9 | const node6 = new Node(6); 10 | 11 | root.left = node4; 12 | root.right = node10; 13 | node4.left = node2; 14 | node4.right = node6; 15 | 16 | const result = isValidBST(root); 17 | expect(result).toBe(true); 18 | }); 19 | 20 | it('should return false for an invalid binary search tree', () => { 21 | const root = new Node(8); 22 | const node4 = new Node(4); 23 | const node10 = new Node(10); 24 | const node2 = new Node(2); 25 | const node12 = new Node(12); 26 | 27 | root.left = node4; 28 | root.right = node10; 29 | node4.left = node2; 30 | node4.right = node12; 31 | 32 | const result = isValidBST(root); 33 | expect(result).toBe(false); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/09-validate-bst/validate-bst.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(value) { 3 | this.value = value; 4 | this.left = null; 5 | this.right = null; 6 | } 7 | } 8 | 9 | function isValidBST() {} 10 | 11 | module.exports = { Node, isValidBST }; 12 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/12-graph-implementation/graph-run.js: -------------------------------------------------------------------------------- 1 | const Graph = require('./graph'); 2 | 3 | // Create a graph: 4 | // Tokyo 5 | // / \ 6 | // Dallas - Aspen 7 | 8 | const g = new Graph(); 9 | g.addVertex('Tokyo'); 10 | g.addVertex('Dallas'); 11 | g.addVertex('Aspen'); 12 | g.addEdge('Tokyo', 'Dallas'); 13 | g.addEdge('Dallas', 'Aspen'); 14 | g.addEdge('Aspen', 'Tokyo'); 15 | 16 | console.log(g); 17 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/12-graph-implementation/graph.js: -------------------------------------------------------------------------------- 1 | class Graph {} 2 | 3 | // Example Adjacency List 4 | // { 5 | // 'A': ['B', 'C'], 6 | // 'B': ['A', 'D'], 7 | // 'C': ['A', 'D'], 8 | // 'D': ['B', 'C'] 9 | // }; 10 | 11 | module.exports = Graph; 12 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/14-graph-depth-first-traversal/graph-depth-first-run.js: -------------------------------------------------------------------------------- 1 | const Graph = require('./graph'); 2 | const depthFirstTraversal = require('./graph-depth-first'); 3 | 4 | // Example Graph 5 | // A --- B 6 | // | | 7 | // | | 8 | // C --- D 9 | // | | 10 | // | | 11 | // E --- F 12 | 13 | const graph = new Graph(); 14 | 15 | // Add vertices 16 | graph.addVertex('A'); 17 | graph.addVertex('B'); 18 | graph.addVertex('C'); 19 | graph.addVertex('D'); 20 | graph.addVertex('E'); 21 | graph.addVertex('F'); 22 | 23 | // Add edges 24 | graph.addEdge('A', 'B'); 25 | graph.addEdge('A', 'C'); 26 | graph.addEdge('B', 'D'); 27 | graph.addEdge('C', 'D'); 28 | graph.addEdge('C', 'E'); 29 | graph.addEdge('D', 'F'); 30 | graph.addEdge('E', 'F'); 31 | 32 | graph.printAdjacencyList(); 33 | 34 | console.log(depthFirstTraversal(graph, 'A')); 35 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/14-graph-depth-first-traversal/graph-depth-first-solution.js: -------------------------------------------------------------------------------- 1 | const Stack = require('./stack'); 2 | 3 | function depthFirstTraversal(graph, startingVertex) { 4 | // If the starting vertex is not in the graph, return an empty array. 5 | if (!graph.adjacencyList[startingVertex]) { 6 | return []; 7 | } 8 | 9 | // Create an empty object to store visited vertices. 10 | const visited = {}; 11 | // Create a new Stack instance. 12 | const stack = new Stack(); 13 | // Create an empty array to store the result. 14 | const result = []; 15 | 16 | // Push the starting vertex onto the stack. 17 | stack.push(startingVertex); 18 | 19 | // Mark the starting vertex as visited. 20 | visited[startingVertex] = true; 21 | 22 | // While the stack is not empty: 23 | while (!stack.isEmpty()) { 24 | // Pop a vertex from the stack. 25 | const currentVertex = stack.pop(); 26 | // Add the vertex to the result. 27 | result.push(currentVertex); 28 | 29 | // For each neighbor of the vertex: 30 | graph.adjacencyList[currentVertex].forEach((neighbor) => { 31 | // If the neighbor has not been visited: 32 | if (!visited[neighbor]) { 33 | // Mark it as visited. 34 | visited[neighbor] = true; 35 | // Push it onto the stack. 36 | stack.push(neighbor); 37 | } 38 | }); 39 | } 40 | 41 | // Return the result. 42 | return result; 43 | } 44 | 45 | module.exports = depthFirstTraversal; 46 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/14-graph-depth-first-traversal/graph-depth-first-test.js: -------------------------------------------------------------------------------- 1 | const Graph = require('./graph'); 2 | const depthFirstTraversal = require('./graph-depth-first'); 3 | 4 | describe('Graph Depth-First Traversal', () => { 5 | test('should perform depth-first traversal correctly', () => { 6 | const g = new Graph(); 7 | g.addVertex('A'); 8 | g.addVertex('B'); 9 | g.addVertex('C'); 10 | g.addVertex('D'); 11 | g.addVertex('E'); 12 | g.addVertex('F'); 13 | g.addVertex('G'); 14 | 15 | g.addEdge('A', 'B'); 16 | g.addEdge('A', 'C'); 17 | g.addEdge('B', 'D'); 18 | g.addEdge('C', 'E'); 19 | g.addEdge('D', 'E'); 20 | g.addEdge('D', 'F'); 21 | g.addEdge('E', 'G'); 22 | g.addEdge('F', 'G'); 23 | 24 | const result = depthFirstTraversal(g, 'A').sort(); 25 | const expected = ['A', 'B', 'C', 'D', 'E', 'F', 'G'].sort(); 26 | expect(result).toEqual(expected); 27 | }); 28 | 29 | test('should handle loops correctly', () => { 30 | const g = new Graph(); 31 | g.addVertex('X'); 32 | g.addVertex('Y'); 33 | g.addVertex('Z'); 34 | 35 | g.addEdge('X', 'Y'); 36 | g.addEdge('Y', 'Z'); 37 | g.addEdge('Z', 'X'); 38 | 39 | const result = depthFirstTraversal(g, 'X').sort(); 40 | const expected = ['X', 'Y', 'Z'].sort(); 41 | expect(result).toEqual(expected); 42 | }); 43 | 44 | test('should return an empty array for an empty graph', () => { 45 | const g = new Graph(); 46 | 47 | expect(depthFirstTraversal(g, 'A')).toEqual([]); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/14-graph-depth-first-traversal/graph-depth-first.js: -------------------------------------------------------------------------------- 1 | const Stack = require('./stack'); 2 | 3 | function depthFirstTraversal() {} 4 | 5 | module.exports = depthFirstTraversal; 6 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/14-graph-depth-first-traversal/graph.js: -------------------------------------------------------------------------------- 1 | class Graph { 2 | constructor() { 3 | this.adjacencyList = {}; 4 | } 5 | 6 | addVertex(vertex) { 7 | this.adjacencyList[vertex] = []; 8 | } 9 | 10 | addEdge(vertex1, vertex2) { 11 | this.adjacencyList[vertex1].push(vertex2); 12 | this.adjacencyList[vertex2].push(vertex1); 13 | } 14 | 15 | removeEdge(vertex1, vertex2) { 16 | this.adjacencyList[vertex1] = this.adjacencyList[vertex1].filter( 17 | (v) => v !== vertex2 18 | ); 19 | 20 | this.adjacencyList[vertex2] = this.adjacencyList[vertex2].filter( 21 | (v) => v !== vertex1 22 | ); 23 | } 24 | 25 | removeVertex(vertex) { 26 | while (this.adjacencyList[vertex].length) { 27 | const adjacentVertex = this.adjacencyList[vertex].pop(); 28 | this.removeEdge(vertex, adjacentVertex); 29 | } 30 | delete this.adjacencyList[vertex]; 31 | } 32 | 33 | printAdjacencyList() { 34 | for (const vertex in this.adjacencyList) { 35 | console.log(`${vertex} -> ${this.adjacencyList[vertex].join(', ')}`); 36 | } 37 | } 38 | } 39 | 40 | 41 | module.exports = Graph; 42 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/14-graph-depth-first-traversal/stack.js: -------------------------------------------------------------------------------- 1 | class Stack { 2 | constructor() { 3 | this.maxSize = 100; 4 | this.stack = []; 5 | this.top = -1; 6 | } 7 | 8 | push(value) { 9 | if (this.isFull()) { 10 | return false; 11 | } 12 | this.top++; 13 | this.stack[this.top] = value; 14 | return true; 15 | } 16 | 17 | pop() { 18 | if (this.isEmpty()) { 19 | return null; 20 | } 21 | this.top--; 22 | 23 | return this.stack.pop(); 24 | } 25 | 26 | peek() { 27 | if (this.isEmpty()) { 28 | return null; 29 | } 30 | return this.stack[this.top]; 31 | } 32 | 33 | isEmpty() { 34 | return this.top === -1; 35 | } 36 | 37 | isFull() { 38 | return this.top === this.maxSize - 1; 39 | } 40 | } 41 | 42 | module.exports = Stack; 43 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/15-graph-breadth-first-traversal/graph-breadth-first-run.js: -------------------------------------------------------------------------------- 1 | const Graph = require('./graph'); 2 | const breadthFirstTraversal = require('./graph-breadth-first'); 3 | 4 | const g = new Graph(); 5 | g.addVertex('Tokyo'); 6 | g.addVertex('Dallas'); 7 | g.addVertex('Aspen'); 8 | g.addEdge('Tokyo', 'Dallas'); 9 | g.addEdge('Dallas', 'Aspen'); 10 | g.addEdge('Tokyo', 'Aspen'); 11 | // g.removeEdge('Dallas', 'Aspen'); 12 | // g.removeVertex('Aspen'); 13 | 14 | console.log(breadthFirstTraversal(g, 'Tokyo')); 15 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/15-graph-breadth-first-traversal/graph-breadth-first-solution.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./queue'); 2 | 3 | function breadthFirstTraversal(graph, startingVertex) { 4 | // If the starting vertex is not in the graph, return an empty array. 5 | const visited = new Set(); 6 | // Create an empty array to store the result. 7 | const result = []; 8 | // Create an empty queue and add the starting vertex to it. 9 | const queue = new Queue(); 10 | 11 | // Add the starting vertex to the queue. 12 | queue.enqueue(startingVertex); 13 | // Mark it as visited. 14 | visited.add(startingVertex); 15 | 16 | // While the queue is not empty: 17 | while (!queue.isEmpty()) { 18 | // Remove a vertex from the queue. 19 | const currentVertex = queue.dequeue(); 20 | // Add the vertex to the result. 21 | result.push(currentVertex); 22 | 23 | // For each neighbor of the vertex: 24 | for (const neighbor of graph.adjacencyList[currentVertex]) { 25 | // If the neighbor has not been visited: 26 | if (!visited.has(neighbor)) { 27 | // Add it to the queue. 28 | queue.enqueue(neighbor); 29 | // Mark it as visited. 30 | visited.add(neighbor); 31 | } 32 | } 33 | } 34 | 35 | // Return the result. 36 | return result; 37 | } 38 | 39 | module.exports = breadthFirstTraversal; 40 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/15-graph-breadth-first-traversal/graph-breadth-first-test.js: -------------------------------------------------------------------------------- 1 | const Graph = require('./graph'); 2 | const Queue = require('./queue'); 3 | const breadthFirstTraversal = require('./graph-breadth-first'); 4 | 5 | describe('Breadth First Traversal', () => { 6 | it('should traverse a graph in breadth-first order', () => { 7 | const graph = new Graph(); 8 | 9 | graph.addVertex('A'); 10 | graph.addVertex('B'); 11 | graph.addVertex('C'); 12 | graph.addVertex('D'); 13 | graph.addVertex('E'); 14 | graph.addVertex('F'); 15 | graph.addVertex('G'); 16 | 17 | graph.addEdge('A', 'B'); 18 | graph.addEdge('A', 'C'); 19 | graph.addEdge('B', 'D'); 20 | graph.addEdge('B', 'E'); 21 | graph.addEdge('C', 'F'); 22 | graph.addEdge('C', 'G'); 23 | 24 | const result = breadthFirstTraversal(graph, 'A'); 25 | expect(result).toEqual(['A', 'B', 'C', 'D', 'E', 'F', 'G']); 26 | }); 27 | 28 | it('should handle disconnected components in the graph', () => { 29 | const graph = new Graph(); 30 | 31 | graph.addVertex('A'); 32 | graph.addVertex('B'); 33 | graph.addVertex('C'); 34 | graph.addVertex('D'); 35 | 36 | graph.addEdge('A', 'B'); 37 | graph.addEdge('C', 'D'); 38 | 39 | const result = breadthFirstTraversal(graph, 'A'); 40 | expect(result).toEqual(['A', 'B']); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/15-graph-breadth-first-traversal/graph-breadth-first.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./queue'); 2 | 3 | function breadthFirstTraversal() {} 4 | 5 | module.exports = breadthFirstTraversal; 6 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/15-graph-breadth-first-traversal/graph.js: -------------------------------------------------------------------------------- 1 | class Graph { 2 | constructor() { 3 | this.adjacencyList = {}; 4 | } 5 | 6 | addVertex(vertex) { 7 | this.adjacencyList[vertex] = []; 8 | } 9 | 10 | addEdge(vertex1, vertex2) { 11 | this.adjacencyList[vertex1].push(vertex2); 12 | this.adjacencyList[vertex2].push(vertex1); 13 | } 14 | 15 | removeEdge(vertex1, vertex2) { 16 | this.adjacencyList[vertex1] = this.adjacencyList[vertex1].filter( 17 | (v) => v !== vertex2 18 | ); 19 | 20 | this.adjacencyList[vertex2] = this.adjacencyList[vertex2].filter( 21 | (v) => v !== vertex1 22 | ); 23 | } 24 | 25 | removeVertex(vertex) { 26 | while (this.adjacencyList[vertex].length) { 27 | const adjacentVertex = this.adjacencyList[vertex].pop(); 28 | this.removeEdge(vertex, adjacentVertex); 29 | } 30 | delete this.adjacencyList[vertex]; 31 | } 32 | 33 | printAdjacencyList() { 34 | for (const vertex in this.adjacencyList) { 35 | console.log(`${vertex} -> ${this.adjacencyList[vertex].join(', ')}`); 36 | } 37 | } 38 | } 39 | 40 | 41 | module.exports = Graph; 42 | -------------------------------------------------------------------------------- /08-binary-trees-graphs/15-graph-breadth-first-traversal/queue.js: -------------------------------------------------------------------------------- 1 | class Queue { 2 | constructor() { 3 | this.queue = []; 4 | this.head = 0; 5 | this.tail = 0; 6 | this.maxSize = 100; 7 | } 8 | 9 | enqueue(element) { 10 | if (this.isFull()) { 11 | return false; 12 | } 13 | this.queue[this.tail] = element; 14 | this.tail++; 15 | return true; 16 | } 17 | 18 | dequeue() { 19 | const item = this.queue[this.head]; 20 | this.head++; 21 | return item; 22 | } 23 | 24 | peek() { 25 | return this.queue[this.head]; 26 | } 27 | 28 | getLength() { 29 | return this.tail - this.head; 30 | } 31 | 32 | isEmpty() { 33 | return this.getLength() === 0; 34 | } 35 | 36 | isFull() { 37 | return this.getLength() === this.maxSize; 38 | } 39 | } 40 | 41 | module.exports = Queue; 42 | -------------------------------------------------------------------------------- /09-sorting-algorithms/03-bubble-sort-implementation/bubble-sort-run.js: -------------------------------------------------------------------------------- 1 | const bubbleSort = require('./bubble-sort'); 2 | 3 | const array = [5, 4, 2, 1]; 4 | 5 | const result = bubbleSort(array); 6 | 7 | console.log(result); 8 | -------------------------------------------------------------------------------- /09-sorting-algorithms/03-bubble-sort-implementation/bubble-sort-solution.js: -------------------------------------------------------------------------------- 1 | // Solution 1 2 | function bubbleSort(arr) { 3 | // Outer loop 4 | for (let i = 0; i < arr.length; i++) { 5 | // Inner loop 6 | for (let j = 0; j < arr.length - i - 1; j++) { 7 | console.log(arr[j], arr[j + 1]); // Display every comparison 8 | // Check if the current element is greater than the next element 9 | if (arr[j] > arr[j + 1]) { 10 | // Swap the elements 11 | // Assign the current element to a temporary variable 12 | const temp = arr[j]; 13 | // Assign the next element to the current element (swap) 14 | arr[j] = arr[j + 1]; 15 | // Assign the temporary variable to the next element 16 | arr[j + 1] = temp; 17 | } 18 | } 19 | } 20 | return arr; 21 | } 22 | 23 | // Solution 2 24 | function bubbleSort(arr) { 25 | // Create a variable to track if any swaps have been made 26 | let swapped = false; 27 | 28 | // Loop until no swaps have been made 29 | while (!swapped) { 30 | // Set swapped to true 31 | swapped = true; 32 | 33 | // Loop through the array 34 | for (let i = 0; i < arr.length; i++) { 35 | // Check if the current element is greater than the next element 36 | if (arr[i] > arr[i + 1]) { 37 | // Swap the elements just like we did in solution 1 38 | const temp = arr[i]; 39 | arr[i] = arr[i + 1]; 40 | arr[i + 1] = temp; 41 | // Set swapped to false 42 | swapped = false; 43 | } 44 | } 45 | } 46 | 47 | return arr; 48 | } 49 | 50 | module.exports = bubbleSort; 51 | -------------------------------------------------------------------------------- /09-sorting-algorithms/03-bubble-sort-implementation/bubble-sort-test.js: -------------------------------------------------------------------------------- 1 | const bubbleSort = require('./bubble-sort'); // Replace with the correct path 2 | 3 | test('Sort an array in ascending order', () => { 4 | const unsortedArray = [5, 2, 8, 1, 3]; 5 | const sortedArray = [1, 2, 3, 5, 8]; 6 | expect(bubbleSort(unsortedArray)).toEqual(sortedArray); 7 | }); 8 | 9 | test('Sort an array with repeated values', () => { 10 | const unsortedArray = [4, 1, 3, 4, 2, 2]; 11 | const sortedArray = [1, 2, 2, 3, 4, 4]; 12 | expect(bubbleSort(unsortedArray)).toEqual(sortedArray); 13 | }); 14 | 15 | test('Sort an already sorted array', () => { 16 | const sortedArray = [1, 2, 3, 4, 5]; 17 | expect(bubbleSort(sortedArray)).toEqual(sortedArray); 18 | }); 19 | 20 | test('Sort an array with one element', () => { 21 | const singleElementArray = [42]; 22 | expect(bubbleSort(singleElementArray)).toEqual(singleElementArray); 23 | }); 24 | 25 | test('Sort an empty array', () => { 26 | const emptyArray = []; 27 | expect(bubbleSort(emptyArray)).toEqual(emptyArray); 28 | }); 29 | -------------------------------------------------------------------------------- /09-sorting-algorithms/03-bubble-sort-implementation/bubble-sort.js: -------------------------------------------------------------------------------- 1 | function bubbleSort() {} 2 | 3 | module.exports = bubbleSort; 4 | -------------------------------------------------------------------------------- /09-sorting-algorithms/05-insertion-sort-implementation/insertion-sort-run.js: -------------------------------------------------------------------------------- 1 | const insertionSort = require('./insertion-sort'); 2 | 3 | const array = [4, 3, 2, 10, 12, 1, 5, 6]; 4 | 5 | const result = insertionSort(array); 6 | 7 | console.log(result); 8 | -------------------------------------------------------------------------------- /09-sorting-algorithms/05-insertion-sort-implementation/insertion-sort-solution.js: -------------------------------------------------------------------------------- 1 | function insertionSort(arr) { 2 | // Loop through the array starting from the second element. 3 | // We start from the second element because we assume the first element is already sorted. 4 | for (let i = 1; i < arr.length; i++) { 5 | // Store the current element in a variable 6 | const currentElement = arr[i]; 7 | // This is the index of the last element in the current "sorted" portion 8 | let j = i - 1; 9 | 10 | // Loop through the sorted part of the array (the left side) and find the correct index of the current element 11 | // As the algorithm moves through the sorted portion to find the correct position for the current element, 12 | // it compares the currentElement with each element in the sorted portion. If the currentElement is smaller 13 | // than the element being compared, the algorithm shifts that element one position to the right to make space 14 | // for the currentElement. 15 | while (j >= 0 && arr[j] > currentElement) { 16 | // Shift the elements to the right 17 | arr[j + 1] = arr[j]; 18 | // Decrement the index 19 | j--; 20 | } 21 | 22 | // Insert the current element 23 | arr[j + 1] = currentElement; 24 | } 25 | 26 | // Return the sorted arra 27 | return arr; 28 | } 29 | 30 | module.exports = insertionSort; 31 | -------------------------------------------------------------------------------- /09-sorting-algorithms/05-insertion-sort-implementation/insertion-sort-test.js: -------------------------------------------------------------------------------- 1 | const insertionSort = require('./insertion-sort'); 2 | 3 | test('Sort an array in ascending order', () => { 4 | const unsortedArray = [5, 2, 8, 1, 3]; 5 | const sortedArray = [1, 2, 3, 5, 8]; 6 | expect(insertionSort(unsortedArray)).toEqual(sortedArray); 7 | }); 8 | 9 | test('Sort an array with repeated values', () => { 10 | const unsortedArray = [4, 1, 3, 4, 2, 2]; 11 | const sortedArray = [1, 2, 2, 3, 4, 4]; 12 | expect(insertionSort(unsortedArray)).toEqual(sortedArray); 13 | }); 14 | 15 | test('Sort an already sorted array', () => { 16 | const sortedArray = [1, 2, 3, 4, 5]; 17 | expect(insertionSort(sortedArray)).toEqual(sortedArray); 18 | }); 19 | 20 | test('Sort an array with one element', () => { 21 | const singleElementArray = [42]; 22 | expect(insertionSort(singleElementArray)).toEqual(singleElementArray); 23 | }); 24 | 25 | test('Sort an empty array', () => { 26 | const emptyArray = []; 27 | expect(insertionSort(emptyArray)).toEqual(emptyArray); 28 | }); 29 | -------------------------------------------------------------------------------- /09-sorting-algorithms/05-insertion-sort-implementation/insertion-sort.js: -------------------------------------------------------------------------------- 1 | function insertionSort() {} 2 | 3 | module.exports = insertionSort; 4 | -------------------------------------------------------------------------------- /09-sorting-algorithms/07-selection-sort-implentation/selection-sort-run.js: -------------------------------------------------------------------------------- 1 | const selectionSort = require('./selection-sort'); 2 | 3 | const array = [4, 3, 2, 10, 12, 1, 5, 6]; 4 | 5 | const result = selectionSort(array); 6 | 7 | console.log(result); 8 | -------------------------------------------------------------------------------- /09-sorting-algorithms/07-selection-sort-implentation/selection-sort-solution.js: -------------------------------------------------------------------------------- 1 | function selectionSort(arr) { 2 | // Loop through the array 3 | for (let i = 0; i < arr.length - 1; i++) { 4 | // Set the minIndex to the current index 5 | let minIndex = i; 6 | 7 | // Loop through the array starting at the next index 8 | for (let j = i + 1; j < arr.length; j++) { 9 | // If the current element is less than the element at the minIndex, set the minIndex to the current index 10 | if (arr[j] < arr[minIndex]) { 11 | minIndex = j; 12 | } 13 | } 14 | 15 | // If the minIndex is not the current index, swap the elements 16 | if (minIndex !== i) { 17 | [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; 18 | } 19 | } 20 | 21 | // Return the sorted array 22 | return arr; 23 | } 24 | 25 | module.exports = selectionSort; 26 | -------------------------------------------------------------------------------- /09-sorting-algorithms/07-selection-sort-implentation/selection-sort-test.js: -------------------------------------------------------------------------------- 1 | const selectionSort = require('./selection-sort'); 2 | 3 | test('Sort an array in ascending order', () => { 4 | const unsortedArray = [5, 2, 8, 1, 3]; 5 | const sortedArray = [1, 2, 3, 5, 8]; 6 | expect(selectionSort(unsortedArray)).toEqual(sortedArray); 7 | }); 8 | 9 | test('Sort an array with repeated values', () => { 10 | const unsortedArray = [4, 1, 3, 4, 2, 2]; 11 | const sortedArray = [1, 2, 2, 3, 4, 4]; 12 | expect(selectionSort(unsortedArray)).toEqual(sortedArray); 13 | }); 14 | 15 | test('Sort an already sorted array', () => { 16 | const sortedArray = [1, 2, 3, 4, 5]; 17 | expect(selectionSort(sortedArray)).toEqual(sortedArray); 18 | }); 19 | 20 | test('Sort an array with one element', () => { 21 | const singleElementArray = [42]; 22 | expect(selectionSort(singleElementArray)).toEqual(singleElementArray); 23 | }); 24 | 25 | test('Sort an empty array', () => { 26 | const emptyArray = []; 27 | expect(selectionSort(emptyArray)).toEqual(emptyArray); 28 | }); 29 | -------------------------------------------------------------------------------- /09-sorting-algorithms/07-selection-sort-implentation/selection-sort.js: -------------------------------------------------------------------------------- 1 | function selectionSort() {} 2 | 3 | module.exports = selectionSort; 4 | -------------------------------------------------------------------------------- /09-sorting-algorithms/08-merge-sort-algorithm/readme.md: -------------------------------------------------------------------------------- 1 | # Merge Sort Algorithm 2 | 3 | The merge sort algorithm is a very efficient divide and conquer algorithm. It works by continuously splitting the array in half until it can no longer be divided. Then, it merges each subarray while sorting them in the process. This process continues until the whole array is sorted. 4 | 5 | This is the most efficient solution that we've looked at so far. It has a time complexity of O(n log n), which signifies that its performance grows in a linearithmic fashion with the input size. This is different from O(log n), where the growth is purely logarithmic. So it isn't as fast as O(log n) but it's faster than O(n), especially for large data sets. It's definitely faster than the other algorithms we've looked at, which had complexities of O(n^2). 6 | 7 | Let's look at an example: 8 | 9 | 10 | 11 | ```js 12 | [5, 3, 7, 1]; 13 | ``` 14 | 15 | The first step is to split the array in half. We get two subarrays: 16 | 17 | ```js 18 | [5, 3][(7, 1)]; 19 | ``` 20 | 21 | We split each subarray in half again: 22 | 23 | ```js 24 | [5][3][7][1]; 25 | ``` 26 | 27 | Now that we can not go any further, we start merging each subarray while sorting them in the process: 28 | 29 | ```js 30 | [3, 5][(1, 7)]; 31 | ``` 32 | 33 | We merge the two subarrays again: 34 | 35 | ```js 36 | [1, 3, 5, 7]; 37 | ``` 38 | 39 | And we are done! 40 | 41 | In the next lesson, we will implement a merge sort algorithm in JavaScript. 42 | -------------------------------------------------------------------------------- /09-sorting-algorithms/09-merge-sort-implementation/merge-sort-run.js: -------------------------------------------------------------------------------- 1 | const mergeSort = require('./merge-sort'); 2 | 3 | const array = [4, 3, 2, 10, 12, 1, 5, 6]; 4 | 5 | const result = mergeSort(array); 6 | 7 | console.log(result); 8 | -------------------------------------------------------------------------------- /09-sorting-algorithms/09-merge-sort-implementation/merge-sort-solution.js: -------------------------------------------------------------------------------- 1 | function mergeSort(arr) { 2 | // If the array has 1 or 0 elements, then it is already sorted. 3 | if (arr.length <= 1) { 4 | return arr; 5 | } 6 | 7 | // Otherwise, divide the array into two halves and sort each half. 8 | const mid = Math.floor(arr.length / 2); 9 | const left = mergeSort(arr.slice(0, mid)); // From 0 to mid, not including mid. 10 | const right = mergeSort(arr.slice(mid)); // From mid to the end. 11 | 12 | // Merge the sorted halves. 13 | return merge(left, right); 14 | } 15 | 16 | function merge(left, right) { 17 | // Initialize an empty array to store the merged array. 18 | const merged = []; 19 | // Initialize two pointers to keep track of the current index of each half. 20 | let leftIndex = 0; 21 | let rightIndex = 0; 22 | 23 | // While both pointers are still within their respective halves, compare the elements at 24 | // the current indices and push the smaller one to the merged array. 25 | while (leftIndex < left.length && rightIndex < right.length) { 26 | // If the element in the left half is smaller, push it to the merged array and increment the left pointer. 27 | if (left[leftIndex] < right[rightIndex]) { 28 | merged.push(left[leftIndex]); 29 | leftIndex++; 30 | } else { 31 | // Otherwise, push the element in the right half to the merged array and increment the right pointer. 32 | merged.push(right[rightIndex]); 33 | rightIndex++; 34 | } 35 | } 36 | 37 | // If there are any remaining elements in the left half, push them to the merged array. 38 | return merged.concat(left.slice(leftIndex)).concat(right.slice(rightIndex)); 39 | } 40 | 41 | module.exports = mergeSort; 42 | -------------------------------------------------------------------------------- /09-sorting-algorithms/09-merge-sort-implementation/merge-sort-test.js: -------------------------------------------------------------------------------- 1 | const mergeSort = require('./merge-sort'); 2 | 3 | test('Sort an array in ascending order', () => { 4 | const unsortedArray = [5, 2, 8, 1, 3]; 5 | const sortedArray = [1, 2, 3, 5, 8]; 6 | expect(mergeSort(unsortedArray)).toEqual(sortedArray); 7 | }); 8 | 9 | test('Sort an array with repeated values', () => { 10 | const unsortedArray = [4, 1, 3, 4, 2, 2]; 11 | const sortedArray = [1, 2, 2, 3, 4, 4]; 12 | expect(mergeSort(unsortedArray)).toEqual(sortedArray); 13 | }); 14 | 15 | test('Sort an already sorted array', () => { 16 | const sortedArray = [1, 2, 3, 4, 5]; 17 | expect(mergeSort(sortedArray)).toEqual(sortedArray); 18 | }); 19 | 20 | test('Sort an array with one element', () => { 21 | const singleElementArray = [42]; 22 | expect(mergeSort(singleElementArray)).toEqual(singleElementArray); 23 | }); 24 | 25 | test('Sort an empty array', () => { 26 | const emptyArray = []; 27 | expect(mergeSort(emptyArray)).toEqual(emptyArray); 28 | }); 29 | -------------------------------------------------------------------------------- /09-sorting-algorithms/09-merge-sort-implementation/merge-sort.js: -------------------------------------------------------------------------------- 1 | function mergeSort() {} 2 | 3 | module.exports = mergeSort; 4 | -------------------------------------------------------------------------------- /09-sorting-algorithms/11-quick-sort-implementation/quick-sort-run.js: -------------------------------------------------------------------------------- 1 | const quickSort = require('./quick-sort'); 2 | 3 | const array = [20, 13, 3, 2, 10, 12, 1, 5, 6]; 4 | 5 | const result = quickSort(array); 6 | 7 | console.log(result); 8 | -------------------------------------------------------------------------------- /09-sorting-algorithms/11-quick-sort-implementation/quick-sort-solution.js: -------------------------------------------------------------------------------- 1 | function quickSort(arr) { 2 | // Base case: If the array has 1 or fewer elements, it's already sorted 3 | if (arr.length <= 1) { 4 | return arr; 5 | } 6 | 7 | // Choose the pivot as the last element of the array 8 | const pivot = arr[arr.length - 1]; 9 | 10 | // Create empty arrays to hold elements less than and greater than the pivot 11 | const left = []; 12 | const right = []; 13 | 14 | // Iterate through the array (except for the pivot) 15 | for (let i = 0; i < arr.length - 1; i++) { 16 | // Compare each element with the pivot 17 | if (arr[i] < pivot) { 18 | // If it's less than the pivot, push it to the left array 19 | left.push(arr[i]); 20 | } else { 21 | // Otherwise, push it to the right array 22 | right.push(arr[i]); 23 | } 24 | } 25 | 26 | // Recursively apply quickSort to the left and right arrays, and combine them with the pivot 27 | return [...quickSort(left), pivot, ...quickSort(right)]; 28 | } 29 | -------------------------------------------------------------------------------- /09-sorting-algorithms/11-quick-sort-implementation/quick-sort-test.js: -------------------------------------------------------------------------------- 1 | const quickSort = require('./quick-sort'); 2 | 3 | test('Sort an array in ascending order', () => { 4 | const unsortedArray = [5, 2, 8, 1, 3]; 5 | const sortedArray = [1, 2, 3, 5, 8]; 6 | expect(quickSort(unsortedArray)).toEqual(sortedArray); 7 | }); 8 | 9 | test('Sort an array with repeated values', () => { 10 | const unsortedArray = [4, 1, 3, 4, 2, 2]; 11 | const sortedArray = [1, 2, 2, 3, 4, 4]; 12 | expect(quickSort(unsortedArray)).toEqual(sortedArray); 13 | }); 14 | 15 | test('Sort an already sorted array', () => { 16 | const sortedArray = [1, 2, 3, 4, 5]; 17 | expect(quickSort(sortedArray)).toEqual(sortedArray); 18 | }); 19 | 20 | test('Sort an array with one element', () => { 21 | const singleElementArray = [42]; 22 | expect(quickSort(singleElementArray)).toEqual(singleElementArray); 23 | }); 24 | 25 | test('Sort an empty array', () => { 26 | const emptyArray = []; 27 | expect(quickSort(emptyArray)).toEqual(emptyArray); 28 | }); 29 | -------------------------------------------------------------------------------- /09-sorting-algorithms/11-quick-sort-implementation/quick-sort.js: -------------------------------------------------------------------------------- 1 | function quickSort() { 2 | 3 | } 4 | 5 | module.exports = quickSort; 6 | -------------------------------------------------------------------------------- /assets/images/adjacency-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/adjacency-list.png -------------------------------------------------------------------------------- /assets/images/adjacency-matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/adjacency-matrix.png -------------------------------------------------------------------------------- /assets/images/binary-search-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/binary-search-tree.png -------------------------------------------------------------------------------- /assets/images/binary-search-tree1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/binary-search-tree1.png -------------------------------------------------------------------------------- /assets/images/binarytree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/binarytree.png -------------------------------------------------------------------------------- /assets/images/breadth-first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/breadth-first.png -------------------------------------------------------------------------------- /assets/images/bubble-sort-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/bubble-sort-console.png -------------------------------------------------------------------------------- /assets/images/bubble-sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/bubble-sort.png -------------------------------------------------------------------------------- /assets/images/depth-first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/depth-first.png -------------------------------------------------------------------------------- /assets/images/doubly-linked-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/doubly-linked-list.png -------------------------------------------------------------------------------- /assets/images/event-loop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/event-loop.png -------------------------------------------------------------------------------- /assets/images/fastslow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/fastslow.png -------------------------------------------------------------------------------- /assets/images/firstnonrepeat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/firstnonrepeat.png -------------------------------------------------------------------------------- /assets/images/graph-breadth-first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/graph-breadth-first.png -------------------------------------------------------------------------------- /assets/images/graph-cycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/graph-cycle.png -------------------------------------------------------------------------------- /assets/images/graph-depth-first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/graph-depth-first.png -------------------------------------------------------------------------------- /assets/images/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/graph.png -------------------------------------------------------------------------------- /assets/images/graph1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/graph1.png -------------------------------------------------------------------------------- /assets/images/hash-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/hash-table.png -------------------------------------------------------------------------------- /assets/images/insertion-sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/insertion-sort.png -------------------------------------------------------------------------------- /assets/images/linked-list1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/linked-list1.png -------------------------------------------------------------------------------- /assets/images/merge-sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/merge-sort.png -------------------------------------------------------------------------------- /assets/images/notbinarytree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/notbinarytree.png -------------------------------------------------------------------------------- /assets/images/queue1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/queue1.png -------------------------------------------------------------------------------- /assets/images/quicksort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/quicksort.png -------------------------------------------------------------------------------- /assets/images/recursion-stack-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/recursion-stack-1.png -------------------------------------------------------------------------------- /assets/images/recursion-stack-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/recursion-stack-2.png -------------------------------------------------------------------------------- /assets/images/selection-sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/selection-sort.png -------------------------------------------------------------------------------- /assets/images/sliding-window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/sliding-window.png -------------------------------------------------------------------------------- /assets/images/stack1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/stack1.png -------------------------------------------------------------------------------- /assets/images/time-complexity.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/time-complexity.webp -------------------------------------------------------------------------------- /assets/images/tree1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/tree1.png -------------------------------------------------------------------------------- /assets/images/tree2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/tree2.png -------------------------------------------------------------------------------- /assets/images/tree3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/tree3.png -------------------------------------------------------------------------------- /assets/images/tree4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/tree4.png -------------------------------------------------------------------------------- /assets/images/tree5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/tree5.png -------------------------------------------------------------------------------- /assets/images/treeheightdepth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/traversy-js-challenges/bc25271618519aaa0f49e12bde268ccfa23d4e91/assets/images/treeheightdepth.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "100-js-challenges", 3 | "version": "1.0.0", 4 | "description": "100 JavaScript challeneges for you to solve", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest" 8 | }, 9 | "author": "Brad Traversy", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "jest": "^29.6.1" 13 | } 14 | } 15 | --------------------------------------------------------------------------------