From f0df2ee0496d6ec381e2c5b18b402f095b1d406e Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sun, 18 Feb 2024 11:17:13 -0500 Subject: [PATCH 01/46] directory cleanup --- .../completed_exercises/anagrams/index.js | 51 +++ .../completed_exercises/anagrams/test.js | 27 ++ .../completed_exercises/bst/index.js | 49 +++ .../completed_exercises/bst/test.js | 41 ++ .../completed_exercises/capitalize/index.js | 34 ++ .../completed_exercises/capitalize/test.js | 17 + .../completed_exercises/chunk/index.js | 39 ++ .../completed_exercises/chunk/test.js | 33 ++ .../completed_exercises/circular/index.js | 31 ++ .../circular/linkedlist.js | 178 +++++++++ .../completed_exercises/circular/test.js | 50 +++ .../completed_exercises/events/example.html | 19 + .../completed_exercises/events/index.js | 37 ++ .../completed_exercises/events/test.js | 77 ++++ .../completed_exercises/fib/index.js | 48 +++ .../completed_exercises/fib/test.js | 25 ++ .../completed_exercises/fizzbuzz/index.js | 31 ++ .../completed_exercises/fizzbuzz/test.js | 39 ++ .../completed_exercises/fromlast/index.js | 31 ++ .../fromlast/linkedlist.js | 156 ++++++++ .../completed_exercises/fromlast/test.js | 20 + .../completed_exercises/levelwidth/index.js | 33 ++ .../completed_exercises/levelwidth/node.js | 10 + .../completed_exercises/levelwidth/test.js | 27 ++ .../linkedlist/directions.html | 378 ++++++++++++++++++ .../completed_exercises/linkedlist/index.js | 160 ++++++++ .../completed_exercises/linkedlist/test.js | 321 +++++++++++++++ .../completed_exercises/matrix/index.js | 63 +++ .../completed_exercises/matrix/test.js | 29 ++ .../completed_exercises/maxchar/index.js | 31 ++ .../completed_exercises/maxchar/test.js | 14 + .../completed_exercises/midpoint/index.js | 27 ++ .../midpoint/linkedlist.js | 178 +++++++++ .../completed_exercises/midpoint/test.js | 46 +++ .../completed_exercises/package.json | 11 + .../completed_exercises/palindrome/index.js | 25 ++ .../completed_exercises/palindrome/test.js | 33 ++ .../completed_exercises/pyramid/index.js | 55 +++ .../completed_exercises/pyramid/test.js | 37 ++ .../completed_exercises/qfroms/index.js | 56 +++ .../completed_exercises/qfroms/stack.js | 19 + .../completed_exercises/qfroms/test.js | 41 ++ .../completed_exercises/queue/index.js | 25 ++ .../completed_exercises/queue/test.js | 31 ++ .../completed_exercises/reverseint/index.js | 21 + .../completed_exercises/reverseint/test.js | 23 ++ .../reversestring/index.js | 30 ++ .../completed_exercises/reversestring/test.js | 13 + .../completed_exercises/sorting/index.js | 66 +++ .../completed_exercises/sorting/test.js | 38 ++ .../completed_exercises/stack/index.js | 31 ++ .../completed_exercises/stack/test.js | 36 ++ .../completed_exercises/steps/index.js | 50 +++ .../completed_exercises/steps/test.js | 34 ++ .../completed_exercises/tree/index.js | 56 +++ .../completed_exercises/tree/test.js | 67 ++++ .../completed_exercises/validate/index.js | 28 ++ .../completed_exercises/validate/node.js | 21 + .../completed_exercises/validate/test.js | 23 ++ .../completed_exercises/vowels/index.js | 28 ++ .../completed_exercises/vowels/test.js | 17 + .../completed_exercises/weave/index.js | 43 ++ .../completed_exercises/weave/queue.js | 25 ++ .../completed_exercises/weave/test.js | 45 +++ .../diagrams/01/.gitkeep | 0 .../diagrams/01/diagrams.xml | 1 + .../diagrams/02/.gitkeep | 0 .../diagrams/02/diagrams.xml | 1 + .../diagrams/03/.gitkeep | 0 .../diagrams/03/diagrams.xml | 1 + .../diagrams/04/.gitkeep | 0 .../diagrams/04/diagrams.xml | 1 + .../diagrams/05/.gitkeep | 0 .../diagrams/05/diagrams.xml | 1 + .../diagrams/06/.gitkeep | 0 .../diagrams/06/diagrams.xml | 1 + .../diagrams/07/.gitkeep | 0 .../diagrams/07/diagrams.xml | 1 + .../diagrams/08/.gitkeep | 0 .../diagrams/08/diagrams.xml | 1 + .../diagrams/09/.gitkeep | 0 .../diagrams/09/diagrams.xml | 1 + .../diagrams/10/.gitkeep | 0 .../diagrams/10/diagrams.xml | 1 + .../exercises/anagrams/index.js | 13 + .../exercises/anagrams/test.js | 27 ++ .../exercises/bst/index.js | 16 + .../exercises/bst/test.js | 41 ++ .../exercises/capitalize/index.js | 12 + .../exercises/capitalize/test.js | 17 + .../exercises/chunk/index.js | 13 + .../exercises/chunk/test.js | 33 ++ .../exercises/circular/index.js | 17 + .../exercises/circular/linkedlist.js | 178 +++++++++ .../exercises/circular/test.js | 50 +++ .../exercises/events/example.html | 10 + .../exercises/events/index.js | 19 + .../exercises/events/test.js | 77 ++++ .../exercises/fib/index.js | 13 + .../exercises/fib/test.js | 25 ++ .../exercises/fizzbuzz/index.js | 17 + .../exercises/fizzbuzz/test.js | 39 ++ .../exercises/fromlast/index.js | 16 + .../exercises/fromlast/linkedlist.js | 156 ++++++++ .../exercises/fromlast/test.js | 20 + .../exercises/levelwidth/index.js | 16 + .../exercises/levelwidth/node.js | 10 + .../exercises/levelwidth/test.js | 27 ++ .../exercises/linkedlist/directions.html | 377 +++++++++++++++++ .../exercises/linkedlist/index.js | 9 + .../exercises/linkedlist/test.js | 321 +++++++++++++++ .../exercises/matrix/index.js | 20 + .../exercises/matrix/test.js | 29 ++ .../exercises/maxchar/index.js | 10 + .../exercises/maxchar/test.js | 14 + .../exercises/midpoint/index.js | 17 + .../exercises/midpoint/linkedlist.js | 178 +++++++++ .../exercises/midpoint/test.js | 46 +++ .../exercises/package.json | 14 + .../exercises/palindrome/index.js | 12 + .../exercises/palindrome/test.js | 33 ++ .../exercises/pyramid/index.js | 19 + .../exercises/pyramid/test.js | 37 ++ .../exercises/qfroms/index.js | 19 + .../exercises/qfroms/stack.js | 19 + .../exercises/qfroms/test.js | 41 ++ .../exercises/queue/index.js | 13 + .../exercises/queue/test.js | 31 ++ .../exercises/reverseint/index.js | 13 + .../exercises/reverseint/test.js | 23 ++ .../exercises/reversestring/index.js | 11 + .../exercises/reversestring/test.js | 13 + .../exercises/sorting/index.js | 20 + .../exercises/sorting/test.js | 38 ++ .../exercises/stack/index.js | 15 + .../exercises/stack/test.js | 36 ++ .../exercises/steps/index.js | 22 + .../exercises/steps/test.js | 34 ++ .../exercises/tree/index.js | 17 + .../exercises/tree/test.js | 67 ++++ .../exercises/validate/index.js | 10 + .../exercises/validate/node.js | 21 + .../exercises/validate/test.js | 23 ++ .../exercises/vowels/index.js | 12 + .../exercises/vowels/test.js | 21 + .../exercises/weave/index.js | 29 ++ .../exercises/weave/queue.js | 21 + .../exercises/weave/test.js | 45 +++ 148 files changed, 6000 insertions(+) create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/anagrams/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/anagrams/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/bst/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/bst/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/capitalize/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/capitalize/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/chunk/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/chunk/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/circular/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/circular/linkedlist.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/circular/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/events/example.html create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/events/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/events/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fib/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fib/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fizzbuzz/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fizzbuzz/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fromlast/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fromlast/linkedlist.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fromlast/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/levelwidth/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/levelwidth/node.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/levelwidth/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/linkedlist/directions.html create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/linkedlist/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/linkedlist/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/matrix/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/matrix/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/maxchar/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/maxchar/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/midpoint/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/midpoint/linkedlist.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/midpoint/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/package.json create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/palindrome/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/palindrome/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/pyramid/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/pyramid/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/qfroms/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/qfroms/stack.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/qfroms/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/queue/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/queue/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reverseint/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reverseint/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reversestring/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reversestring/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/sorting/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/sorting/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/stack/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/stack/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/steps/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/steps/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/tree/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/tree/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/validate/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/validate/node.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/validate/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/vowels/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/vowels/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/weave/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/weave/queue.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/weave/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/01/.gitkeep create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/01/diagrams.xml create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/02/.gitkeep create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/02/diagrams.xml create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/03/.gitkeep create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/03/diagrams.xml create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/04/.gitkeep create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/04/diagrams.xml create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/05/.gitkeep create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/05/diagrams.xml create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/06/.gitkeep create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/06/diagrams.xml create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/07/.gitkeep create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/07/diagrams.xml create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/08/.gitkeep create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/08/diagrams.xml create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/09/.gitkeep create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/09/diagrams.xml create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/10/.gitkeep create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/diagrams/10/diagrams.xml create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/bst/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/bst/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/linkedlist.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/example.html create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/fib/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/fib/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/fizzbuzz/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/fizzbuzz/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/linkedlist.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/node.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/directions.html create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/matrix/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/matrix/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/maxchar/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/maxchar/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/linkedlist.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/package.json create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/palindrome/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/palindrome/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/stack.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/queue/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/queue/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/stack/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/stack/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/node.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/vowels/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/vowels/test.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/index.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/queue.js create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/test.js diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/anagrams/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/anagrams/index.js new file mode 100644 index 0000000..1a1b598 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/anagrams/index.js @@ -0,0 +1,51 @@ +// --- Directions +// Check to see if two provided strings are anagrams of eachother. +// One string is an anagram of another if it uses the same characters +// in the same quantity. Only consider characters, not spaces +// or punctuation. Consider capital letters to be the same as lower case +// --- Examples +// anagrams('rail safety', 'fairy tales') --> True +// anagrams('RAIL! SAFETY!', 'fairy tales') --> True +// anagrams('Hi there', 'Bye there') --> False + +function anagrams(stringA, stringB) { + return cleanString(stringA) === cleanString(stringB); +} + +function cleanString(str) { + return str + .replace(/[^\w]/g, '') + .toLowerCase() + .split('') + .sort() + .join(''); +} + +module.exports = anagrams; + +// function anagrams(stringA, stringB) { +// const aCharMap = buildCharMap(stringA); +// const bCharMap = buildCharMap(stringB); +// +// if (Object.keys(aCharMap).length !== Object.keys(bCharMap).length) { +// return false; +// } +// +// for (let char in aCharMap) { +// if (aCharMap[char] !== bCharMap[char]) { +// return false; +// } +// } +// +// return true; +// } +// +// function buildCharMap(str) { +// const charMap = {}; +// +// for (let char of str.replace(/[^\w]/g, '').toLowerCase()) { +// charMap[char] = charMap[char] + 1 || 1; +// } +// +// return charMap; +// } diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/anagrams/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/anagrams/test.js new file mode 100644 index 0000000..60f117b --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/anagrams/test.js @@ -0,0 +1,27 @@ +const anagrams = require('./index.js'); + +test('anagrams function exists', () => { + expect(typeof anagrams).toEqual('function'); +}); + +test('"hello" is an anagram of "llohe"', () => { + expect(anagrams('hello', 'llohe')).toBeTruthy(); +}); + +test('"Whoa! Hi!" is an anagram of "Hi! Whoa!"', () => { + expect(anagrams('Whoa! Hi!', 'Hi! Whoa!')).toBeTruthy(); +}); + +test('"One One" is not an anagram of "Two two two"', () => { + expect(anagrams('One One', 'Two two two')).toBeFalsy(); +}); + +test('"One one" is not an anagram of "One one c"', () => { + expect(anagrams('One one', 'One one c')).toBeFalsy(); +}); + +test('"A tree, a life, a bench" is not an anagram of "A tree, a fence, a yard"', () => { + expect( + anagrams('A tree, a life, a bench', 'A tree, a fence, a yard') + ).toBeFalsy(); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/bst/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/bst/index.js new file mode 100644 index 0000000..673fd7d --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/bst/index.js @@ -0,0 +1,49 @@ +// --- Directions +// 1) Implement the Node class to create +// a binary search tree. The constructor +// should initialize values 'data', 'left', +// and 'right'. +// 2) Implement the 'insert' method for the +// Node class. Insert should accept an argument +// 'data', then create an insert a new node +// at the appropriate location in the tree. +// 3) Implement the 'contains' method for the Node +// class. Contains should accept a 'data' argument +// and return the Node in the tree with the same value. +// If the value isn't in the tree return null. + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + + insert(data) { + if (data < this.data && this.left) { + this.left.insert(data); + } else if (data < this.data) { + this.left = new Node(data); + } else if (data > this.data && this.right) { + this.right.insert(data); + } else if (data > this.data) { + this.right = new Node(data); + } + } + + contains(data) { + if (this.data === data) { + return this; + } + + if (this.data < data && this.right) { + return this.right.contains(data); + } else if (this.data > data && this.left) { + return this.left.contains(data); + } + + return null; + } +} + +module.exports = Node; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/bst/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/bst/test.js new file mode 100644 index 0000000..331ae22 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/bst/test.js @@ -0,0 +1,41 @@ +const Node = require('./index'); + +test('Node is a constructor', () => { + expect(typeof Node.prototype.constructor).toEqual('function'); +}); + +test('Node can insert correctly', () => { + const node = new Node(10); + node.insert(5); + node.insert(15); + node.insert(17); + + expect(node.left.data).toEqual(5); + expect(node.right.data).toEqual(15); + expect(node.right.right.data).toEqual(17); +}); + +test('Contains returns node with the same data', () => { + const node = new Node(10); + node.insert(5); + node.insert(15); + node.insert(20); + node.insert(0); + node.insert(-5); + node.insert(3); + + const three = node.left.left.right; + expect(node.contains(3)).toEqual(three); +}); + +test('Contains returns null if value not found', () => { + const node = new Node(10); + node.insert(5); + node.insert(15); + node.insert(20); + node.insert(0); + node.insert(-5); + node.insert(3); + + expect(node.contains(9999)).toEqual(null); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/capitalize/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/capitalize/index.js new file mode 100644 index 0000000..353993f --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/capitalize/index.js @@ -0,0 +1,34 @@ +// --- Directions +// Write a function that accepts a string. The function should +// capitalize the first letter of each word in the string then +// return the capitalized string. +// --- Examples +// capitalize('a short sentence') --> 'A Short Sentence' +// capitalize('a lazy fox') --> 'A Lazy Fox' +// capitalize('look, it is working!') --> 'Look, It Is Working!' + +function capitalize(str) { + let result = str[0].toUpperCase(); + + for (let i = 1; i < str.length; i++) { + if (str[i - 1] === ' ') { + result += str[i].toUpperCase(); + } else { + result += str[i]; + } + } + + return result; +} + +module.exports = capitalize; + +// function capitalize(str) { +// const words = []; +// +// for (let word of str.split(' ')) { +// words.push(word[0].toUpperCase() + word.slice(1)); +// } +// +// return words.join(' '); +// } diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/capitalize/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/capitalize/test.js new file mode 100644 index 0000000..21a2423 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/capitalize/test.js @@ -0,0 +1,17 @@ +const capitalize = require('./index'); + +test('Capitalize is a function', () => { + expect(typeof capitalize).toEqual('function'); +}); + +test('capitalizes the first letter of every word in a sentence', () => { + expect(capitalize('hi there, how is it going?')).toEqual( + 'Hi There, How Is It Going?' + ); +}); + +test('capitalizes the first letter', () => { + expect(capitalize('i love breakfast at bill miller bbq')).toEqual( + 'I Love Breakfast At Bill Miller Bbq' + ); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/chunk/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/chunk/index.js new file mode 100644 index 0000000..02c9bbb --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/chunk/index.js @@ -0,0 +1,39 @@ +// --- Directions +// Given an array and chunk size, divide the array into many subarrays +// where each subarray is of length size +// --- Examples +// chunk([1, 2, 3, 4], 2) --> [[ 1, 2], [3, 4]] +// chunk([1, 2, 3, 4, 5], 2) --> [[ 1, 2], [3, 4], [5]] +// chunk([1, 2, 3, 4, 5, 6, 7, 8], 3) --> [[ 1, 2, 3], [4, 5, 6], [7, 8]] +// chunk([1, 2, 3, 4, 5], 4) --> [[ 1, 2, 3, 4], [5]] +// chunk([1, 2, 3, 4, 5], 10) --> [[ 1, 2, 3, 4, 5]] + +function chunk(array, size) { + const chunked = []; + let index = 0; + + while (index < array.length) { + chunked.push(array.slice(index, index + size)); + index += size; + } + + return chunked; +} + +module.exports = chunk; + +// function chunk(array, size) { +// const chunked = []; +// +// for (let element of array) { +// const last = chunked[chunked.length - 1]; +// +// if (!last || last.length === size) { +// chunked.push([element]); +// } else { +// last.push(element); +// } +// } +// +// return chunked; +// } diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/chunk/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/chunk/test.js new file mode 100644 index 0000000..ef3d645 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/chunk/test.js @@ -0,0 +1,33 @@ +const chunk = require('./index'); + +test('function chunk exists', () => { + expect(typeof chunk).toEqual('function'); +}); + +test('chunk divides an array of 10 elements with chunk size 2', () => { + const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + const chunked = chunk(arr, 2); + + expect(chunked).toEqual([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]); +}); + +test('chunk divides an array of 3 elements with chunk size 1', () => { + const arr = [1, 2, 3]; + const chunked = chunk(arr, 1); + + expect(chunked).toEqual([[1], [2], [3]]); +}); + +test('chunk divides an array of 5 elements with chunk size 3', () => { + const arr = [1, 2, 3, 4, 5]; + const chunked = chunk(arr, 3); + + expect(chunked).toEqual([[1, 2, 3], [4, 5]]); +}); + +test('chunk divides an array of 13 elements with chunk size 5', () => { + const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; + const chunked = chunk(arr, 5); + + expect(chunked).toEqual([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13]]); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/circular/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/circular/index.js new file mode 100644 index 0000000..508b09f --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/circular/index.js @@ -0,0 +1,31 @@ +// --- Directions +// Given a linked list, return true if the list +// is circular, false if it is not. +// --- Examples +// const l = new List(); +// const a = new Node('a'); +// const b = new Node('b'); +// const c = new Node('c'); +// l.head = a; +// a.next = b; +// b.next = c; +// c.next = b; +// circular(l) // true + +function circular(list) { + let slow = list.getFirst(); + let fast = list.getFirst(); + + while (fast.next && fast.next.next) { + slow = slow.next; + fast = fast.next.next; + + if (slow === fast) { + return true; + } + } + + return false; +} + +module.exports = circular; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/circular/linkedlist.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/circular/linkedlist.js new file mode 100644 index 0000000..b7da56b --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/circular/linkedlist.js @@ -0,0 +1,178 @@ +class Node { + constructor(data, next = null) { + this.data = data; + this.next = next; + } +} + +class LinkedList { + constructor(values = []) { + this.head = null; + + for (let value of values) { + this.insertLast(value); + } + } + + clear() { + this.head = null; + } + + size() { + let counter = 0; + let node = this.head; + + while (node) { + counter++; + node = node.next; + } + + return counter; + } + + getAt(index) { + if (!this.head) { + return null; + } + + let counter = 0; + let node = this.head; + while (node) { + if (counter === index) { + return node; + } + node = node.next; + counter++; + } + return null; + } + + insertAt(data, index) { + if (!this.head) { + this.head = new Node(data); + return; + } + + if (index === 0) { + this.head = new Node(data, this.head); + return; + } + + let counter = 1; + let previous = this.head; + let node = this.head.next; + while (node) { + if (counter === index) { + previous.next = new Node(data, node); + return; + } + previous = node; + node = node.next; + counter++; + } + + previous.next = new Node(data, node); + } + + removeFirst() { + if (!this.head) { + return; + } + + this.head = this.head.next; + } + + removeLast() { + if (!this.head) { + return; + } + + if (!this.head.next) { + this.head = null; + return; + } + + let previous = this.head; + let node = this.head.next; + while (node.next) { + previous = node; + node = node.next; + } + previous.next = null; + } + + removeAt(index) { + if (!this.head) { + return; + } + + let counter = 0; + let node = this.head; + while (node) { + if (counter === index - 1) { + if (node.next) { + return (node.next = node.next.next); + } else { + return (node.next = null); + } + } + node = node.next; + counter++; + } + } + + getFirst() { + return this.head; + } + + insertFirst(data) { + this.head = new Node(data, this.getFirst()); + } + + getLast() { + if (!this.head) { + return null; + } + + let node = this.head; + while (node.next) { + node = node.next; + } + + return node; + } + + insertLast(data) { + const last = this.getLast(); + + if (last) { + last.next = new Node(data); + return last.next; + } else { + this.head = new Node(data); + return this.head; + } + } + + forEach(fn) { + if (!this.head) { + return null; + } + + let node = this.head; + while (node) { + fn(node); + node = node.next; + } + } + + *[Symbol.iterator]() { + let node = this.head; + while (node) { + yield node; + node = node.next; + } + } +} + +module.exports = { Node, LinkedList }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/circular/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/circular/test.js new file mode 100644 index 0000000..99c21fe --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/circular/test.js @@ -0,0 +1,50 @@ +const circular = require('./index'); +const L = require('./linkedlist'); +const List = L.LinkedList; +const Node = L.Node; + +test('circular function is defined', () => { + expect(typeof circular).toEqual('function'); +}); + +test('circular detects circular linked lists', () => { + const l = new List(); + const a = new Node('a'); + const b = new Node('b'); + const c = new Node('c'); + + l.head = a; + a.next = b; + b.next = c; + c.next = b; + + expect(circular(l)).toEqual(true); +}); + +test('circular detects circular linked lists linked at the head', () => { + const l = new List(); + const a = new Node('a'); + const b = new Node('b'); + const c = new Node('c'); + + l.head = a; + a.next = b; + b.next = c; + c.next = a; + + expect(circular(l)).toEqual(true); +}); + +test('circular detects non-circular linked lists', () => { + const l = new List(); + const a = new Node('a'); + const b = new Node('b'); + const c = new Node('c'); + + l.head = a; + a.next = b; + b.next = c; + c.next = null; + + expect(circular(l)).toEqual(false); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/events/example.html b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/events/example.html new file mode 100644 index 0000000..c1a8303 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/events/example.html @@ -0,0 +1,19 @@ + + + + +

Click the button

+ + + diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/events/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/events/index.js new file mode 100644 index 0000000..ee5a600 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/events/index.js @@ -0,0 +1,37 @@ +// --- Directions +// Create an 'eventing' library out of the +// Events class. The Events class should +// have methods 'on', 'trigger', and 'off'. + +class Events { + constructor() { + this.events = {}; + } + + // Register an event handler + on(eventName, callback) { + if (this.events[eventName]) { + this.events[eventName].push(callback); + } else { + this.events[eventName] = [callback]; + } + } + + // Trigger all callbacks associated + // with a given eventName + trigger(eventName) { + if (this.events[eventName]) { + for (let cb of this.events[eventName]) { + cb(); + } + } + } + + // Remove all event handlers associated + // with the given eventName + off(eventName) { + delete this.events[eventName]; + } +} + +module.exports = Events; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/events/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/events/test.js new file mode 100644 index 0000000..e015819 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/events/test.js @@ -0,0 +1,77 @@ +const Events = require('./index'); + +test('Events can be registered then triggered', () => { + const events = new Events(); + + const cb1 = jest.fn(); + + events.on('click', cb1); + events.trigger('click'); + + expect(cb1.mock.calls.length).toBe(1); +}); + +test('Multiple events can be registered then triggered', () => { + const events = new Events(); + + const cb1 = jest.fn(); + const cb2 = jest.fn(); + + events.on('click', cb1); + events.on('click', cb2); + events.trigger('click'); + + expect(cb1.mock.calls.length).toBe(1); + expect(cb2.mock.calls.length).toBe(1); +}); + +test('Events can be triggered multiple times', () => { + const events = new Events(); + + const cb1 = jest.fn(); + const cb2 = jest.fn(); + + events.on('click', cb1); + events.trigger('click'); + events.on('click', cb2); + events.trigger('click'); + events.trigger('click'); + + expect(cb1.mock.calls.length).toBe(3); + expect(cb2.mock.calls.length).toBe(2); +}); + +test('Events can have different names', () => { + const events = new Events(); + + const cb1 = jest.fn(); + const cb2 = jest.fn(); + + events.on('click', cb1); + events.trigger('click'); + events.on('hover', cb2); + events.trigger('click'); + events.trigger('hover'); + + expect(cb1.mock.calls.length).toBe(2); + expect(cb2.mock.calls.length).toBe(1); +}); + +test('Events can be toggled off', () => { + const events = new Events(); + + const cb1 = jest.fn(); + const cb2 = jest.fn(); + + events.on('hover', cb2); + + events.on('click', cb1); + events.trigger('click'); + events.off('click'); + events.trigger('click'); + + events.trigger('hover'); + + expect(cb1.mock.calls.length).toBe(1); + expect(cb2.mock.calls.length).toBe(1); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fib/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fib/index.js new file mode 100644 index 0000000..51e2ae1 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fib/index.js @@ -0,0 +1,48 @@ +// --- Directions +// Print out the n-th entry in the fibonacci series. +// The fibonacci series is an ordering of numbers where +// each number is the sum of the preceeding two. +// For example, the sequence +// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] +// forms the first ten entries of the fibonacci series. +// Example: +// fib(4) === 3 + +function memoize(fn) { + const cache = {}; + return function(...args) { + if (cache[args]) { + return cache[args]; + } + + const result = fn.apply(this, args); + cache[args] = result; + + return result; + }; +} + +function slowFib(n) { + if (n < 2) { + return n; + } + + return fib(n - 1) + fib(n - 2); +} + +const fib = memoize(slowFib); + +module.exports = fib; + +// function fib(n) { +// const result = [0, 1]; +// +// for (let i = 2; i <= n; i++) { +// const a = result[i - 1]; +// const b = result[i - 2]; +// +// result.push(a + b); +// } +// +// return result[n]; +// } diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fib/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fib/test.js new file mode 100644 index 0000000..02a385d --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fib/test.js @@ -0,0 +1,25 @@ +const fib = require('./index'); + +test('Fib function is defined', () => { + expect(typeof fib).toEqual('function'); +}); + +test('calculates correct fib value for 1', () => { + expect(fib(1)).toEqual(1); +}); + +test('calculates correct fib value for 2', () => { + expect(fib(2)).toEqual(1); +}); + +test('calculates correct fib value for 3', () => { + expect(fib(3)).toEqual(2); +}); + +test('calculates correct fib value for 4', () => { + expect(fib(4)).toEqual(3); +}); + +test('calculates correct fib value for 15', () => { + expect(fib(39)).toEqual(63245986); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fizzbuzz/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fizzbuzz/index.js new file mode 100644 index 0000000..8fe64c4 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fizzbuzz/index.js @@ -0,0 +1,31 @@ +// --- Directions +// Write a program that console logs the numbers +// from 1 to n. But for multiples of three print +// “fizz” instead of the number and for the multiples +// of five print “buzz”. For numbers which are multiples +// of both three and five print “fizzbuzz”. +// --- Example +// fizzBuzz(5); +// 1 +// 2 +// fizz +// 4 +// buzz + +function fizzBuzz(n) { + for (let i = 1; i <= n; i++) { + // Is the number a multiple of 3 and 5? + if (i % 3 === 0 && i % 5 === 0) { + console.log('fizzbuzz'); + } else if (i % 3 === 0) { + // Is the number a multiple of 3? + console.log('fizz'); + } else if (i % 5 === 0) { + console.log('buzz'); + } else { + console.log(i); + } + } +} + +module.exports = fizzBuzz; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fizzbuzz/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fizzbuzz/test.js new file mode 100644 index 0000000..fa5108e --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fizzbuzz/test.js @@ -0,0 +1,39 @@ +const fizzBuzz = require('./index'); + +test('fizzBuzz function is defined', () => { + expect(fizzBuzz).toBeDefined(); +}); + +test('Calling fizzbuzz with `5` prints out 5 statements', () => { + fizzBuzz(5); + + expect(console.log.mock.calls.length).toEqual(5); +}); + +test('Calling fizzbuzz with 15 prints out the correct values', () => { + fizzBuzz(15); + + expect(console.log.mock.calls[0][0]).toEqual(1); + expect(console.log.mock.calls[1][0]).toEqual(2); + expect(console.log.mock.calls[2][0]).toEqual('fizz'); + expect(console.log.mock.calls[3][0]).toEqual(4); + expect(console.log.mock.calls[4][0]).toEqual('buzz'); + expect(console.log.mock.calls[5][0]).toEqual('fizz'); + expect(console.log.mock.calls[6][0]).toEqual(7); + expect(console.log.mock.calls[7][0]).toEqual(8); + expect(console.log.mock.calls[8][0]).toEqual('fizz'); + expect(console.log.mock.calls[9][0]).toEqual('buzz'); + expect(console.log.mock.calls[10][0]).toEqual(11); + expect(console.log.mock.calls[11][0]).toEqual('fizz'); + expect(console.log.mock.calls[12][0]).toEqual(13); + expect(console.log.mock.calls[13][0]).toEqual(14); + expect(console.log.mock.calls[14][0]).toEqual('fizzbuzz'); +}); + +beforeEach(() => { + jest.spyOn(console, 'log').mockImplementation(() => {}); +}); + +afterEach(() => { + console.log.mockRestore(); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fromlast/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fromlast/index.js new file mode 100644 index 0000000..935ca22 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fromlast/index.js @@ -0,0 +1,31 @@ +// --- Directions +// Given a linked list and integer n, return the element n +// spaces from the last node in the list. Do not call the +// 'size' method of the linked list. Assume that n will always +// be less than the length of the list. +// --- Examples +// const list = new List(); +// list.insertLast('a'); +// list.insertLast('b'); +// list.insertLast('c'); +// list.insertLast('d'); +// fromLast(list, 2).data // 'b' + +function fromLast(list, n) { + let slow = list.getFirst(); + let fast = list.getFirst(); + + while (n > 0) { + fast = fast.next; + n--; + } + + while (fast.next) { + slow = slow.next; + fast = fast.next; + } + + return slow; +} + +module.exports = fromLast; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fromlast/linkedlist.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fromlast/linkedlist.js new file mode 100644 index 0000000..2029b3b --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fromlast/linkedlist.js @@ -0,0 +1,156 @@ +class Node { + constructor(data, next = null) { + this.data = data; + this.next = next; + } +} + +class LinkedList { + constructor() { + this.head = null; + } + + insertFirst(data) { + this.head = new Node(data, this.head); + } + + size() { + let counter = 0; + let node = this.head; + + while (node) { + counter++; + node = node.next; + } + + return counter; + } + + getFirst() { + return this.head; + } + + getLast() { + if (!this.head) { + return null; + } + + let node = this.head; + while (node) { + if (!node.next) { + return node; + } + node = node.next; + } + } + + clear() { + this.head = null; + } + + removeFirst() { + if (!this.head) { + return; + } + + this.head = this.head.next; + } + + removeLast() { + if (!this.head) { + return; + } + + if (!this.head.next) { + this.head = null; + return; + } + + let previous = this.head; + let node = this.head.next; + while (node.next) { + previous = node; + node = node.next; + } + previous.next = null; + } + + insertLast(data) { + const last = this.getLast(); + + if (last) { + // There are some existing nodes in our chain + last.next = new Node(data); + } else { + // The chain is empty! + this.head = new Node(data); + } + } + + getAt(index) { + let counter = 0; + let node = this.head; + while (node) { + if (counter === index) { + return node; + } + + counter++; + node = node.next; + } + return null; + } + + removeAt(index) { + if (!this.head) { + return; + } + + if (index === 0) { + this.head = this.head.next; + return; + } + + const previous = this.getAt(index - 1); + if (!previous || !previous.next) { + return; + } + previous.next = previous.next.next; + } + + insertAt(data, index) { + if (!this.head) { + this.head = new Node(data); + return; + } + + if (index === 0) { + this.head = new Node(data, this.head); + return; + } + + const previous = this.getAt(index - 1) || this.getLast(); + const node = new Node(data, previous.next); + previous.next = node; + } + + forEach(fn) { + let node = this.head; + let counter = 0; + while (node) { + fn(node, counter); + node = node.next; + counter++; + } + } + + *[Symbol.iterator]() { + let node = this.head; + while (node) { + yield node; + node = node.next; + } + } +} + +module.exports = { Node, LinkedList }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fromlast/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fromlast/test.js new file mode 100644 index 0000000..e4684d5 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/fromlast/test.js @@ -0,0 +1,20 @@ +const fromLast = require('./index'); +const L = require('./linkedlist'); +const List = L.LinkedList; +const Node = L.Node; + +test('fromLast is a function', () => { + expect(typeof fromLast).toEqual('function'); +}); + +test('fromLast returns the node n elements from the end', () => { + const l = new List(); + + l.insertLast('a'); + l.insertLast('b'); + l.insertLast('c'); + l.insertLast('d'); + l.insertLast('e'); + + expect(fromLast(l, 3).data).toEqual('b'); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/levelwidth/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/levelwidth/index.js new file mode 100644 index 0000000..349c0c4 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/levelwidth/index.js @@ -0,0 +1,33 @@ +// --- Directions +// Given the root node of a tree, return +// an array where each element is the width +// of the tree at each level. +// --- Example +// Given: +// 0 +// / | \ +// 1 2 3 +// | | +// 4 5 +// Answer: [1, 3, 2] + +function levelWidth(root) { + const arr = [root, 's']; + const counters = [0]; + + while (arr.length > 1) { + const node = arr.shift(); + + if (node === 's') { + counters.push(0); + arr.push('s'); + } else { + arr.push(...node.children); + counters[counters.length - 1]++; + } + } + + return counters; +} + +module.exports = levelWidth; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/levelwidth/node.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/levelwidth/node.js new file mode 100644 index 0000000..5238e8f --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/levelwidth/node.js @@ -0,0 +1,10 @@ +module.exports = class Node { + constructor(data) { + this.data = data; + this.children = []; + } + + add(data) { + this.children.push(new Node(data)); + } +}; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/levelwidth/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/levelwidth/test.js new file mode 100644 index 0000000..35d20c2 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/levelwidth/test.js @@ -0,0 +1,27 @@ +const Node = require('./node'); +const levelWidth = require('./index'); + +test('levelWidth is a function', () => { + expect(typeof levelWidth).toEqual('function'); +}); + +test('levelWidth returns number of nodes at widest point', () => { + const root = new Node(0); + root.add(1); + root.add(2); + root.add(3); + root.children[0].add(4); + root.children[2].add(5); + + expect(levelWidth(root)).toEqual([1, 3, 2]); +}); + +test('levelWidth returns number of nodes at widest point', () => { + const root = new Node(0); + root.add(1); + root.children[0].add(2); + root.children[0].add(3); + root.children[0].children[0].add(4); + + expect(levelWidth(root)).toEqual([1, 1, 2, 1]); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/linkedlist/directions.html b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/linkedlist/directions.html new file mode 100644 index 0000000..3bae946 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/linkedlist/directions.html @@ -0,0 +1,378 @@ + + + + + +

Node Class API

+ + + + + + + + + + + + + + + + + + + +
FunctionArgumentsReturnsDirectionsExample
constructor(Data, Node)Node + Creates a class instance to represent a node. The node should + have two properties, 'data' and 'next'. Accept both + of these as arguments to the 'Node' constructor, then + assign them to the instance as properties 'data' and 'next'. + If 'next' is not provided to the constructor, then default its + value to be 'null'. + +
+            const n = new Node('Hi');
+            n.data // 'Hi'
+            n.next // null
+            const n2 = new Node('There', n);
+            n.next // returns n
+          
+
+ +

LinkedList Class API

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FunctionArgumentsReturnsDirectionsExample
constructor-(LinkedList) + Create a class to represent a linked list. When created, + a linked list should have *no* head node associated with it. + The LinkedList instance will have one property, 'head', which + is a reference to the first node of the linked list. By default + 'head' should be 'null'. + +
+            const list = new LinkedList();
+            list.head // null
+          
+
insertFirst(data)- + Creates a new Node from argument 'data' and assigns the resulting + node to the 'head' property. Make sure to handle the case in which + the linked list already has a node assigned to the 'head' property. + +
+            const list = new LinkedList();
+            list.insertFirst('Hi There'); // List has one node
+          
+
size-(integer) + Returns the number of nodes in the linked list. + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.insertFirst('c');
+            list.size(); // returns 3
+          
+
getFirst-(Node) + Returns the first node of the linked list. + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.getFirst(); // returns Node instance with data 'a'
+          
+
+ getLast + + - + + (Node) + + Returns the last node of the linked list + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.getLast(); // returns node with data 'a'
+          
+
+ clear + + - + + - + + Empties the linked list of any nodes. + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.clear();
+            list.size(); // returns 0
+          
+
+ removeFirst + + - + + - + + Removes only the first node of the linked list. The list's head should + now be the second element. + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.removeFirst();
+            list.getFirst(); // returns node with data 'a'
+          
+
+ removeLast + + - + + - + + Removes the last node of the chain + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.removeLast();
+            list.size(); // returns 1
+            list.getLast(); // returns node with data of 'b'
+          
+
+ insertLast + + (Data) + + - + + Inserts a new node with provided data at the end of the chain + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.insertLast('c');
+            list.getLast(); // returns node with data 'C'
+          
+
+ getAt + + (integer) + + (Node) + + Returns the node at the provided index + +
+            const list = new List();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.insertFirst('c');
+            list.getAt(1); // returns node with data 'b'
+          
+
+ removeAt + + (integer) + + - + + Removes node at the provided index + +
+            const list = new List();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.insertFirst('c');
+            list.removeAt(1);
+            list.getAt(1); // returns node with data 'a'
+          
+
+ insertAt + + (Data, integer) + + - + + Create an insert a new node at provided index. + If index is out of bounds, add the node to the end + of the list. + +
+            const list = new List();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.insertFirst('c');
+            list.insertAt('Hi', 1)
+            list.getAt(1); // returns node with data 'Hi'
+          
+
+ forEach + + (function) + + - + + Calls the provided function with every node of the chain and the index + of the node. + +
+            const list = new List();
+
+            list.insertLast(1);
+            list.insertLast(2);
+            list.insertLast(3);
+            list.insertLast(4);
+
+            list.forEach((node, index) => {
+              node.data += 10;
+            });
+            list.getAt(0); // Returns node with data '11'
+          
+
+ for...of Loop + + - + + - + + Linked list should be compatible as the subject of a 'for...of' loop + +
+            const list = new List();
+
+            list.insertLast(1);
+            list.insertLast(2);
+            list.insertLast(3);
+            list.insertLast(4);
+
+            for (let node of list) {
+              node.data += 10;
+            }
+
+            node.getAt(1); // returns node with data 11
+          
+
+ diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/linkedlist/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/linkedlist/index.js new file mode 100644 index 0000000..5bd5efb --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/linkedlist/index.js @@ -0,0 +1,160 @@ +// --- Directions +// Implement classes Node and Linked Lists +// See 'directions' document + +class Node { + constructor(data, next = null) { + this.data = data; + this.next = next; + } +} + +class LinkedList { + constructor() { + this.head = null; + } + + insertFirst(data) { + this.head = new Node(data, this.head); + } + + size() { + let counter = 0; + let node = this.head; + + while (node) { + counter++; + node = node.next; + } + + return counter; + } + + getFirst() { + return this.head; + } + + getLast() { + if (!this.head) { + return null; + } + + let node = this.head; + while (node) { + if (!node.next) { + return node; + } + node = node.next; + } + } + + clear() { + this.head = null; + } + + removeFirst() { + if (!this.head) { + return; + } + + this.head = this.head.next; + } + + removeLast() { + if (!this.head) { + return; + } + + if (!this.head.next) { + this.head = null; + return; + } + + let previous = this.head; + let node = this.head.next; + while (node.next) { + previous = node; + node = node.next; + } + previous.next = null; + } + + insertLast(data) { + const last = this.getLast(); + + if (last) { + // There are some existing nodes in our chain + last.next = new Node(data); + } else { + // The chain is empty! + this.head = new Node(data); + } + } + + getAt(index) { + let counter = 0; + let node = this.head; + while (node) { + if (counter === index) { + return node; + } + + counter++; + node = node.next; + } + return null; + } + + removeAt(index) { + if (!this.head) { + return; + } + + if (index === 0) { + this.head = this.head.next; + return; + } + + const previous = this.getAt(index - 1); + if (!previous || !previous.next) { + return; + } + previous.next = previous.next.next; + } + + insertAt(data, index) { + if (!this.head) { + this.head = new Node(data); + return; + } + + if (index === 0) { + this.head = new Node(data, this.head); + return; + } + + const previous = this.getAt(index - 1) || this.getLast(); + const node = new Node(data, previous.next); + previous.next = node; + } + + forEach(fn) { + let node = this.head; + let counter = 0; + while (node) { + fn(node, counter); + node = node.next; + counter++; + } + } + + *[Symbol.iterator]() { + let node = this.head; + while (node) { + yield node; + node = node.next; + } + } +} + +module.exports = { Node, LinkedList }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/linkedlist/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/linkedlist/test.js new file mode 100644 index 0000000..f4de046 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/linkedlist/test.js @@ -0,0 +1,321 @@ +const L = require('./index'); +const List = L.LinkedList; +const Node = L.Node; + +test('List is a class', () => { + expect(typeof List.prototype.constructor).toEqual('function'); +}); + +test('Node is a class', () => { + expect(typeof Node.prototype.constructor).toEqual('function'); +}); + +describe('A Node', () => { + test('has properties "data" and "next"', () => { + const node = new Node('a', 'b'); + expect(node.data).toEqual('a'); + expect(node.next).toEqual('b'); + }); +}); + +describe('Insert First', () => { + test('appends a node to the start of the list', () => { + const l = new List(); + l.insertFirst(1); + expect(l.head.data).toEqual(1); + l.insertFirst(2); + expect(l.head.data).toEqual(2); + }); +}); + +describe('Size', () => { + test('returns the number of items in the linked list', () => { + const l = new List(); + expect(l.size()).toEqual(0); + l.insertFirst(1); + l.insertFirst(1); + l.insertFirst(1); + l.insertFirst(1); + expect(l.size()).toEqual(4); + }); +}); + +describe('GetFirst', () => { + test('returns the first element', () => { + const l = new List(); + l.insertFirst(1); + expect(l.getFirst().data).toEqual(1); + l.insertFirst(2); + expect(l.getFirst().data).toEqual(2); + }); +}); + +describe('GetLast', () => { + test('returns the last element', () => { + const l = new List(); + l.insertFirst(2); + expect(l.getLast()).toEqual({ data: 2, next: null }); + l.insertFirst(1); + expect(l.getLast()).toEqual({ data: 2, next: null }); + }); +}); + +describe('Clear', () => { + test('empties out the list', () => { + const l = new List(); + expect(l.size()).toEqual(0); + l.insertFirst(1); + l.insertFirst(1); + l.insertFirst(1); + l.insertFirst(1); + expect(l.size()).toEqual(4); + l.clear(); + expect(l.size()).toEqual(0); + }); +}); + +describe('RemoveFirst', () => { + test('removes the first node when the list has a size of one', () => { + const l = new List(); + l.insertFirst('a'); + l.removeFirst(); + expect(l.size()).toEqual(0); + expect(l.getFirst()).toEqual(null); + }); + + test('removes the first node when the list has a size of three', () => { + const l = new List(); + l.insertFirst('c'); + l.insertFirst('b'); + l.insertFirst('a'); + l.removeFirst(); + expect(l.size()).toEqual(2); + expect(l.getFirst().data).toEqual('b'); + l.removeFirst(); + expect(l.size()).toEqual(1); + expect(l.getFirst().data).toEqual('c'); + }); +}); + +describe('RemoveLast', () => { + test('RemoveLast removes the last node when list is empty', () => { + const l = new List(); + expect(() => { + l.removeLast(); + }).not.toThrow(); + }); + + test('RemoveLast removes the last node when list is length 1', () => { + const l = new List(); + l.insertFirst('a'); + l.removeLast(); + expect(l.head).toEqual(null); + }); + + test('RemoveLast removes the last node when list is length 2', () => { + const l = new List(); + l.insertFirst('b'); + l.insertFirst('a'); + + l.removeLast(); + + expect(l.size()).toEqual(1); + expect(l.head.data).toEqual('a'); + }); + + test('RemoveLast removes the last node when list is length 3', () => { + const l = new List(); + l.insertFirst('c'); + l.insertFirst('b'); + l.insertFirst('a'); + l.removeLast(); + + expect(l.size()).toEqual(2); + expect(l.getLast().data).toEqual('b'); + }); +}); + +describe('InsertLast', () => { + test('adds to the end of the list', () => { + const l = new List(); + l.insertFirst('a'); + + l.insertLast('b'); + + expect(l.size()).toEqual(2); + expect(l.getLast().data).toEqual('b'); + }); +}); + +describe('GetAt', () => { + test('returns the node at given index', () => { + const l = new List(); + expect(l.getAt(10)).toEqual(null); + + l.insertLast(1); + l.insertLast(2); + l.insertLast(3); + l.insertLast(4); + + expect(l.getAt(0).data).toEqual(1); + expect(l.getAt(1).data).toEqual(2); + expect(l.getAt(2).data).toEqual(3); + expect(l.getAt(3).data).toEqual(4); + }); +}); + +describe('RemoveAt', () => { + test('removeAt doesnt crash on an empty list', () => { + const l = new List(); + expect(() => { + l.removeAt(0); + l.removeAt(1); + l.removeAt(2); + }).not.toThrow(); + }); + + test('removeAt doesnt crash on an index out of bounds', () => { + const l = new List(); + expect(() => { + const l = new List(); + l.insertFirst('a'); + l.removeAt(1); + }).not.toThrow(); + }); + + test('removeAt deletes the first node', () => { + const l = new List(); + l.insertLast(1); + l.insertLast(2); + l.insertLast(3); + l.insertLast(4); + expect(l.getAt(0).data).toEqual(1); + l.removeAt(0); + expect(l.getAt(0).data).toEqual(2); + }); + + test('removeAt deletes the node at the given index', () => { + const l = new List(); + l.insertLast(1); + l.insertLast(2); + l.insertLast(3); + l.insertLast(4); + expect(l.getAt(1).data).toEqual(2); + l.removeAt(1); + expect(l.getAt(1).data).toEqual(3); + }); + + test('removeAt works on the last node', () => { + const l = new List(); + l.insertLast(1); + l.insertLast(2); + l.insertLast(3); + l.insertLast(4); + expect(l.getAt(3).data).toEqual(4); + l.removeAt(3); + expect(l.getAt(3)).toEqual(null); + }); +}); + +describe('InsertAt', () => { + test('inserts a new node with data at the 0 index when the list is empty', () => { + const l = new List(); + l.insertAt('hi', 0); + expect(l.getFirst().data).toEqual('hi'); + }); + + test('inserts a new node with data at the 0 index when the list has elements', () => { + const l = new List(); + l.insertLast('a'); + l.insertLast('b'); + l.insertLast('c'); + l.insertAt('hi', 0); + expect(l.getAt(0).data).toEqual('hi'); + expect(l.getAt(1).data).toEqual('a'); + expect(l.getAt(2).data).toEqual('b'); + expect(l.getAt(3).data).toEqual('c'); + }); + + test('inserts a new node with data at a middle index', () => { + const l = new List(); + l.insertLast('a'); + l.insertLast('b'); + l.insertLast('c'); + l.insertLast('d'); + l.insertAt('hi', 2); + expect(l.getAt(0).data).toEqual('a'); + expect(l.getAt(1).data).toEqual('b'); + expect(l.getAt(2).data).toEqual('hi'); + expect(l.getAt(3).data).toEqual('c'); + expect(l.getAt(4).data).toEqual('d'); + }); + + test('inserts a new node with data at a last index', () => { + const l = new List(); + l.insertLast('a'); + l.insertLast('b'); + l.insertAt('hi', 2); + expect(l.getAt(0).data).toEqual('a'); + expect(l.getAt(1).data).toEqual('b'); + expect(l.getAt(2).data).toEqual('hi'); + }); + + test('insert a new node when index is out of bounds', () => { + const l = new List(); + l.insertLast('a'); + l.insertLast('b'); + l.insertAt('hi', 30); + + expect(l.getAt(0).data).toEqual('a'); + expect(l.getAt(1).data).toEqual('b'); + expect(l.getAt(2).data).toEqual('hi'); + }); +}); + +describe('ForEach', () => { + test('applies a transform to each node', () => { + const l = new List(); + + l.insertLast(1); + l.insertLast(2); + l.insertLast(3); + l.insertLast(4); + + l.forEach(node => { + node.data += 10; + }); + + expect(l.getAt(0).data).toEqual(11); + expect(l.getAt(1).data).toEqual(12); + expect(l.getAt(2).data).toEqual(13); + expect(l.getAt(3).data).toEqual(14); + }); +}); + +describe('for...of loops', () => { + test('works with the linked list', () => { + const l = new List(); + + l.insertLast(1); + l.insertLast(2); + l.insertLast(3); + l.insertLast(4); + + for (let node of l) { + node.data += 10; + } + + expect(l.getAt(0).data).toEqual(11); + expect(l.getAt(1).data).toEqual(12); + expect(l.getAt(2).data).toEqual(13); + expect(l.getAt(3).data).toEqual(14); + }); + + test('for...of works on an empty list', () => { + const l = new List(); + expect(() => { + for (let node of l) { + } + }).not.toThrow(); + }); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/matrix/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/matrix/index.js new file mode 100644 index 0000000..f1d0651 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/matrix/index.js @@ -0,0 +1,63 @@ +// --- Directions +// Write a function that accepts an integer N +// and returns a NxN spiral matrix. +// --- Examples +// matrix(2) +// [[undefined, undefined], +// [undefined, undefined]] +// matrix(3) +// [[1, 2, 3], +// [8, 9, 4], +// [7, 6, 5]] +// matrix(4) +// [[1, 2, 3, 4], +// [12, 13, 14, 5], +// [11, 16, 15, 6], +// [10, 9, 8, 7]] + +function matrix(n) { + const results = []; + + for (let i = 0; i < n; i++) { + results.push([]); + } + + let counter = 1; + let startColumn = 0; + let endColumn = n - 1; + let startRow = 0; + let endRow = n - 1; + while (startColumn <= endColumn && startRow <= endRow) { + // Top row + for (let i = startColumn; i <= endColumn; i++) { + results[startRow][i] = counter; + counter++; + } + startRow++; + + // Right column + for (let i = startRow; i <= endRow; i++) { + results[i][endColumn] = counter; + counter++; + } + endColumn--; + + // Bottom row + for (let i = endColumn; i >= startColumn; i--) { + results[endRow][i] = counter; + counter++; + } + endRow--; + + // start column + for (let i = endRow; i >= startRow; i--) { + results[i][startColumn] = counter; + counter++; + } + startColumn++; + } + + return results; +} + +module.exports = matrix; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/matrix/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/matrix/test.js new file mode 100644 index 0000000..4476dda --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/matrix/test.js @@ -0,0 +1,29 @@ +const matrix = require('./index'); + +test('matrix is a function', () => { + expect(typeof matrix).toEqual('function'); +}); + +test('matrix produces a 2x2 array', () => { + const m = matrix(2); + expect(m.length).toEqual(2); + expect(m[0]).toEqual([1, 2]); + expect(m[1]).toEqual([4, 3]); +}); + +test('matrix produces a 3x3 array', () => { + const m = matrix(3); + expect(m.length).toEqual(3); + expect(m[0]).toEqual([1, 2, 3]); + expect(m[1]).toEqual([8, 9, 4]); + expect(m[2]).toEqual([7, 6, 5]); +}); + +test('matrix produces a 4x4 array', () => { + const m = matrix(4); + expect(m.length).toEqual(4); + expect(m[0]).toEqual([1, 2, 3, 4]); + expect(m[1]).toEqual([12, 13, 14, 5]); + expect(m[2]).toEqual([11, 16, 15, 6]); + expect(m[3]).toEqual([10, 9, 8, 7]); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/maxchar/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/maxchar/index.js new file mode 100644 index 0000000..4ddbeac --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/maxchar/index.js @@ -0,0 +1,31 @@ +// --- Directions +// Given a string, return the character that is most +// commonly used in the string. +// --- Examples +// maxChar("abcccccccd") === "c" +// maxChar("apple 1231111") === "1" + +function maxChar(str) { + const charMap = {}; + let max = 0; + let maxChar = ''; + + for (let char of str) { + if (charMap[char]) { + charMap[char]++; + } else { + charMap[char] = 1; + } + } + + for (let char in charMap) { + if (charMap[char] > max) { + max = charMap[char]; + maxChar = char; + } + } + + return maxChar; +} + +module.exports = maxChar; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/maxchar/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/maxchar/test.js new file mode 100644 index 0000000..14918ee --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/maxchar/test.js @@ -0,0 +1,14 @@ +const maxChar = require('./index'); + +test('maxChar function exists', () => { + expect(typeof maxChar).toEqual('function'); +}); + +test('Finds the most frequently used char', () => { + expect(maxChar('a')).toEqual('a'); + expect(maxChar('abcdefghijklmnaaaaa')).toEqual('a'); +}); + +test('Works with numbers in the string', () => { + expect(maxChar('ab1c1d1e1f1g1')).toEqual('1'); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/midpoint/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/midpoint/index.js new file mode 100644 index 0000000..10503dc --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/midpoint/index.js @@ -0,0 +1,27 @@ +// --- Directions +// Return the 'middle' node of a linked list. +// If the list has an even number of elements, return +// the node at the end of the first half of the list. +// *Do not* use a counter variable, *do not* retrieve +// the size of the list, and only iterate +// through the list one time. +// --- Example +// const l = new LinkedList(); +// l.insertLast('a') +// l.insertLast('b') +// l.insertLast('c') +// midpoint(l); // returns { data: 'b' } + +function midpoint(list) { + let slow = list.getFirst(); + let fast = list.getFirst(); + + while (fast.next && fast.next.next) { + slow = slow.next; + fast = fast.next.next; + } + + return slow; +} + +module.exports = midpoint; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/midpoint/linkedlist.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/midpoint/linkedlist.js new file mode 100644 index 0000000..b7da56b --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/midpoint/linkedlist.js @@ -0,0 +1,178 @@ +class Node { + constructor(data, next = null) { + this.data = data; + this.next = next; + } +} + +class LinkedList { + constructor(values = []) { + this.head = null; + + for (let value of values) { + this.insertLast(value); + } + } + + clear() { + this.head = null; + } + + size() { + let counter = 0; + let node = this.head; + + while (node) { + counter++; + node = node.next; + } + + return counter; + } + + getAt(index) { + if (!this.head) { + return null; + } + + let counter = 0; + let node = this.head; + while (node) { + if (counter === index) { + return node; + } + node = node.next; + counter++; + } + return null; + } + + insertAt(data, index) { + if (!this.head) { + this.head = new Node(data); + return; + } + + if (index === 0) { + this.head = new Node(data, this.head); + return; + } + + let counter = 1; + let previous = this.head; + let node = this.head.next; + while (node) { + if (counter === index) { + previous.next = new Node(data, node); + return; + } + previous = node; + node = node.next; + counter++; + } + + previous.next = new Node(data, node); + } + + removeFirst() { + if (!this.head) { + return; + } + + this.head = this.head.next; + } + + removeLast() { + if (!this.head) { + return; + } + + if (!this.head.next) { + this.head = null; + return; + } + + let previous = this.head; + let node = this.head.next; + while (node.next) { + previous = node; + node = node.next; + } + previous.next = null; + } + + removeAt(index) { + if (!this.head) { + return; + } + + let counter = 0; + let node = this.head; + while (node) { + if (counter === index - 1) { + if (node.next) { + return (node.next = node.next.next); + } else { + return (node.next = null); + } + } + node = node.next; + counter++; + } + } + + getFirst() { + return this.head; + } + + insertFirst(data) { + this.head = new Node(data, this.getFirst()); + } + + getLast() { + if (!this.head) { + return null; + } + + let node = this.head; + while (node.next) { + node = node.next; + } + + return node; + } + + insertLast(data) { + const last = this.getLast(); + + if (last) { + last.next = new Node(data); + return last.next; + } else { + this.head = new Node(data); + return this.head; + } + } + + forEach(fn) { + if (!this.head) { + return null; + } + + let node = this.head; + while (node) { + fn(node); + node = node.next; + } + } + + *[Symbol.iterator]() { + let node = this.head; + while (node) { + yield node; + node = node.next; + } + } +} + +module.exports = { Node, LinkedList }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/midpoint/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/midpoint/test.js new file mode 100644 index 0000000..277597e --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/midpoint/test.js @@ -0,0 +1,46 @@ +const midpoint = require('./index'); +const L = require('./linkedlist'); +const Node = L.Node; +const LinkedList = L.LinkedList; + +test('Midpoint is a function', () => { + expect(typeof midpoint).toEqual('function'); +}); + +describe('Midpoint returns the middle node of an odd numbered list', () => { + test('when the list has 3 elements', () => { + const l = new LinkedList(); + l.insertLast('a'); + l.insertLast('b'); + l.insertLast('c'); + expect(midpoint(l).data).toEqual('b'); + }); + + test('when the list has 5 elements', () => { + const l = new LinkedList(); + l.insertLast('a'); + l.insertLast('b'); + l.insertLast('c'); + l.insertLast('d'); + l.insertLast('e'); + expect(midpoint(l).data).toEqual('c'); + }); +}); + +describe('Midpoint returns the middle node of an even numbered list', () => { + test('when the list has 2 elements', () => { + const l = new LinkedList(); + l.insertLast('a'); + l.insertLast('b'); + expect(midpoint(l).data).toEqual('a'); + }); + + test('when the list has 4 elements', () => { + const l = new LinkedList(); + l.insertLast('a'); + l.insertLast('b'); + l.insertLast('c'); + l.insertLast('d'); + expect(midpoint(l).data).toEqual('b'); + }); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/package.json b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/package.json new file mode 100644 index 0000000..7ab32a4 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/package.json @@ -0,0 +1,11 @@ +{ + "name": "dev", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/palindrome/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/palindrome/index.js new file mode 100644 index 0000000..43bffe8 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/palindrome/index.js @@ -0,0 +1,25 @@ +// --- Directions +// Given a string, return true if the string is a palindrome +// or false if it is not. Palindromes are strings that +// form the same word if it is reversed. *Do* include spaces +// and punctuation in determining if the string is a palindrome. +// --- Examples: +// palindrome("abba") === true +// palindrome("abcdefg") === false + +function palindrome(str) { + return str.split('').every((char, i) => { + return char === str[str.length - i - 1]; + }); +} + +module.exports = palindrome; + +// function palindrome(str) { +// const reversed = str +// .split('') +// .reverse() +// .join(''); +// +// return str === reversed; +// } diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/palindrome/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/palindrome/test.js new file mode 100644 index 0000000..abdbcb1 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/palindrome/test.js @@ -0,0 +1,33 @@ +const palindrome = require('./index'); + +test('palindrome function is defined', () => { + expect(typeof palindrome).toEqual('function'); +}); + +test('"aba" is a palindrome', () => { + expect(palindrome('aba')).toBeTruthy(); +}); + +test('" aba" is not a palindrome', () => { + expect(palindrome(' aba')).toBeFalsy(); +}); + +test('"aba " is not a palindrome', () => { + expect(palindrome('aba ')).toBeFalsy(); +}); + +test('"greetings" is not a palindrome', () => { + expect(palindrome('greetings')).toBeFalsy(); +}); + +test('"1000000001" a palindrome', () => { + expect(palindrome('1000000001')).toBeTruthy(); +}); + +test('"Fish hsif" is not a palindrome', () => { + expect(palindrome('Fish hsif')).toBeFalsy(); +}); + +test('"pennep" a palindrome', () => { + expect(palindrome('pennep')).toBeTruthy(); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/pyramid/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/pyramid/index.js new file mode 100644 index 0000000..003b0a0 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/pyramid/index.js @@ -0,0 +1,55 @@ +// --- Directions +// Write a function that accepts a positive number N. +// The function should console log a pyramid shape +// with N levels using the # character. Make sure the +// pyramid has spaces on both the left *and* right hand sides +// --- Examples +// pyramid(1) +// '#' +// pyramid(2) +// ' # ' +// '###' +// pyramid(3) +// ' # ' +// ' ### ' +// '#####' + +function pyramid(n, row = 0, level = '') { + if (row === n) { + return; + } + + if (level.length === 2 * n - 1) { + console.log(level); + return pyramid(n, row + 1); + } + + const midpoint = Math.floor((2 * n - 1) / 2); + let add; + if (midpoint - row <= level.length && midpoint + row >= level.length) { + add = '#'; + } else { + add = ' '; + } + pyramid(n, row, level + add); +} + +module.exports = pyramid; +// +// function pyramid(n) { +// const midpoint = Math.floor((2 * n - 1) / 2); +// +// for (let row = 0; row < n; row++) { +// let level = ''; +// +// for (let column = 0; column < 2 * n - 1; column++) { +// if (midpoint - row <= column && midpoint + row >= column) { +// level += '#'; +// } else { +// level += ' '; +// } +// } +// +// console.log(level); +// } +// } diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/pyramid/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/pyramid/test.js new file mode 100644 index 0000000..8ffc318 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/pyramid/test.js @@ -0,0 +1,37 @@ +const pyramid = require('./index'); + +beforeEach(() => { + jest.spyOn(console, 'log'); +}); + +afterEach(() => { + console.log.mockRestore(); +}); + +test('pyramid is a function', () => { + expect(typeof pyramid).toEqual('function'); +}); + +test('prints a pryamid for n = 2', () => { + pyramid(2); + expect(console.log.mock.calls[0][0]).toEqual(' # '); + expect(console.log.mock.calls[1][0]).toEqual('###'); + expect(console.log.mock.calls.length).toEqual(2); +}); + +test('prints a pryamid for n = 3', () => { + pyramid(3); + expect(console.log.mock.calls[0][0]).toEqual(' # '); + expect(console.log.mock.calls[1][0]).toEqual(' ### '); + expect(console.log.mock.calls[2][0]).toEqual('#####'); + expect(console.log.mock.calls.length).toEqual(3); +}); + +test('prints a pryamid for n = 4', () => { + pyramid(4); + expect(console.log.mock.calls[0][0]).toEqual(' # '); + expect(console.log.mock.calls[1][0]).toEqual(' ### '); + expect(console.log.mock.calls[2][0]).toEqual(' ##### '); + expect(console.log.mock.calls[3][0]).toEqual('#######'); + expect(console.log.mock.calls.length).toEqual(4); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/qfroms/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/qfroms/index.js new file mode 100644 index 0000000..829c30e --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/qfroms/index.js @@ -0,0 +1,56 @@ +// --- Directions +// Implement a Queue datastructure using two stacks. +// *Do not* create an array inside of the 'Queue' class. +// Queue should implement the methods 'add', 'remove', and 'peek'. +// For a reminder on what each method does, look back +// at the Queue exercise. +// --- Examples +// const q = new Queue(); +// q.add(1); +// q.add(2); +// q.peek(); // returns 1 +// q.remove(); // returns 1 +// q.remove(); // returns 2 + +const Stack = require('./stack'); + +class Queue { + constructor() { + this.first = new Stack(); + this.second = new Stack(); + } + + add(record) { + this.first.push(record); + } + + remove() { + while (this.first.peek()) { + this.second.push(this.first.pop()); + } + + const record = this.second.pop(); + + while (this.second.peek()) { + this.first.push(this.second.pop()); + } + + return record; + } + + peek() { + while (this.first.peek()) { + this.second.push(this.first.pop()); + } + + const record = this.second.peek(); + + while (this.second.peek()) { + this.first.push(this.second.pop()); + } + + return record; + } +} + +module.exports = Queue; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/qfroms/stack.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/qfroms/stack.js new file mode 100644 index 0000000..2032acb --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/qfroms/stack.js @@ -0,0 +1,19 @@ +class Stack { + constructor() { + this.data = []; + } + + push(record) { + this.data.push(record); + } + + pop() { + return this.data.pop(); + } + + peek() { + return this.data[this.data.length - 1]; + } +} + +module.exports = Stack; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/qfroms/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/qfroms/test.js new file mode 100644 index 0000000..3fc84c7 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/qfroms/test.js @@ -0,0 +1,41 @@ +const Queue = require('./index'); + +test('Queue is a class', () => { + expect(typeof Queue.prototype.constructor).toEqual('function'); +}); + +test('can add elements to a queue', () => { + const q = new Queue(); + expect(() => { + q.add(1); + }).not.toThrow(); +}); + +test('can remove elements from a queue', () => { + const q = new Queue(); + expect(() => { + q.add(1); + q.remove(); + }).not.toThrow(); +}); + +test('Order of elements is maintained', () => { + const q = new Queue(); + q.add(1); + q.add(2); + q.add(3); + expect(q.remove()).toEqual(1); + expect(q.remove()).toEqual(2); + expect(q.remove()).toEqual(3); + expect(q.remove()).toEqual(undefined); +}); + +test('peek returns, but does not remove, the first value', () => { + const q = new Queue(); + q.add(1); + q.add(2); + expect(q.peek()).toEqual(1); + expect(q.peek()).toEqual(1); + expect(q.remove()).toEqual(1); + expect(q.remove()).toEqual(2); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/queue/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/queue/index.js new file mode 100644 index 0000000..e475d6e --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/queue/index.js @@ -0,0 +1,25 @@ +// --- Description +// Create a queue data structure. The queue +// should be a class with methods 'add' and 'remove'. +// Adding to the queue should store an element until +// it is removed +// --- Examples +// const q = new Queue(); +// q.add(1); +// q.remove(); // returns 1; + +class Queue { + constructor() { + this.data = []; + } + + add(record) { + this.data.unshift(record); + } + + remove() { + return this.data.pop(); + } +} + +module.exports = Queue; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/queue/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/queue/test.js new file mode 100644 index 0000000..867bd42 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/queue/test.js @@ -0,0 +1,31 @@ +const Queue = require('./index'); + +test('Queue is a class', () => { + expect(typeof Queue.prototype.constructor).toEqual('function'); +}); + +test('can add elements to a queue', () => { + const q = new Queue(); + expect(() => { + q.add(1); + }).not.toThrow(); +}); + +test('can remove elements from a queue', () => { + const q = new Queue(); + expect(() => { + q.add(1); + q.remove(); + }).not.toThrow(); +}); + +test('Order of elements is maintained', () => { + const q = new Queue(); + q.add(1); + q.add(2); + q.add(3); + expect(q.remove()).toEqual(1); + expect(q.remove()).toEqual(2); + expect(q.remove()).toEqual(3); + expect(q.remove()).toEqual(undefined); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reverseint/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reverseint/index.js new file mode 100644 index 0000000..c2e6a0d --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reverseint/index.js @@ -0,0 +1,21 @@ +// --- Directions +// Given an integer, return an integer that is the reverse +// ordering of numbers. +// --- Examples +// reverseInt(15) === 51 +// reverseInt(981) === 189 +// reverseInt(500) === 5 +// reverseInt(-15) === -51 +// reverseInt(-90) === -9 + +function reverseInt(n) { + const reversed = n + .toString() + .split('') + .reverse() + .join(''); + + return parseInt(reversed) * Math.sign(n); +} + +module.exports = reverseInt; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reverseint/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reverseint/test.js new file mode 100644 index 0000000..e5092e2 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reverseint/test.js @@ -0,0 +1,23 @@ +const reverseInt = require('./index'); + +test('ReverseInt function exists', () => { + expect(reverseInt).toBeDefined(); +}); + +test('ReverseInt handles 0 as an input', () => { + expect(reverseInt(0)).toEqual(0); +}); + +test('ReverseInt flips a positive number', () => { + expect(reverseInt(5)).toEqual(5); + expect(reverseInt(15)).toEqual(51); + expect(reverseInt(90)).toEqual(9); + expect(reverseInt(2359)).toEqual(9532); +}); + +test('ReverseInt flips a negative number', () => { + expect(reverseInt(-5)).toEqual(-5); + expect(reverseInt(-15)).toEqual(-51); + expect(reverseInt(-90)).toEqual(-9); + expect(reverseInt(-2359)).toEqual(-9532); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reversestring/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reversestring/index.js new file mode 100644 index 0000000..5f036a9 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reversestring/index.js @@ -0,0 +1,30 @@ +// --- Directions +// Given a string, return a new string with the reversed +// order of characters +// --- Examples +// reverse('apple') === 'leppa' +// reverse('hello') === 'olleh' +// reverse('Greetings!') === '!sgniteerG' + +function reverse(str) { + return str.split('').reduce((rev, char) => char + rev, ''); +} + +module.exports = reverse; + +// function reverse(str) { +// return str +// .split('') +// .reverse() +// .join(''); +// } + +// function reverse(str) { +// let reversed = ''; +// +// for (let character of str) { +// reversed = character + reversed; +// } +// +// return reversed; +// } diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reversestring/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reversestring/test.js new file mode 100644 index 0000000..8d264c0 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/reversestring/test.js @@ -0,0 +1,13 @@ +const reverse = require('./index'); + +test('Reverse function exists', () => { + expect(reverse).toBeDefined(); +}); + +test('Reverse reverses a string', () => { + expect(reverse('abcd')).toEqual('dcba'); +}); + +test('Reverse reverses a string', () => { + expect(reverse(' abcd')).toEqual('dcba '); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/sorting/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/sorting/index.js new file mode 100644 index 0000000..5ad4201 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/sorting/index.js @@ -0,0 +1,66 @@ +// --- Directions +// Implement bubbleSort, selectionSort, and mergeSort + +function bubbleSort(arr) { + // Implement bubblesort + for (let i = 0; i < arr.length; i++) { + for (let j = 0; j < (arr.length - i - 1); j++) { + if (arr[j] > arr[j+1]) { + const lesser = arr[j+1]; + arr[j+1] = arr[j]; + arr[j] = lesser; + } + } + } + + // return the sorted array + return arr; +} + +function selectionSort(arr) { + for (let i = 0; i < arr.length; i++) { + let indexOfMin = i; + + for (let j = i+1; j { + test('sorts an array', () => { + expect(bubbleSort(getArray())).toEqual(getSortedArray()); + }); +}); + +describe('Selection sort', () => { + test('sorts an array', () => { + expect(selectionSort(getArray())).toEqual(getSortedArray()); + }); +}); + +describe('Merge sort', () => { + test('merge function can join together two sorted arrays', () => { + const left = [1, 10]; + const right = [2, 8, 12]; + + expect(merge(left, right)).toEqual([1,2,8,10,12]); + }); + + test('sorts an array', () => { + expect(mergeSort(getArray())).toEqual(getSortedArray()); + }); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/stack/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/stack/index.js new file mode 100644 index 0000000..7e95441 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/stack/index.js @@ -0,0 +1,31 @@ +// --- Directions +// Create a stack data structure. The stack +// should be a class with methods 'push', 'pop', and +// 'peek'. Adding an element to the stack should +// store it until it is removed. +// --- Examples +// const s = new Stack(); +// s.push(1); +// s.push(2); +// s.pop(); // returns 2 +// s.pop(); // returns 1 + +class Stack { + constructor() { + this.data = []; + } + + push(record) { + this.data.push(record); + } + + pop() { + return this.data.pop(); + } + + peek() { + return this.data[this.data.length - 1]; + } +} + +module.exports = Stack; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/stack/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/stack/test.js new file mode 100644 index 0000000..457e5a2 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/stack/test.js @@ -0,0 +1,36 @@ +const Stack = require('./index'); + +test('Stack is a class', () => { + expect(typeof Stack.prototype.constructor).toEqual('function'); +}); + +test('stack can add and remove items', () => { + const s = new Stack(); + s.push(1); + expect(s.pop()).toEqual(1); + s.push(2); + expect(s.pop()).toEqual(2); +}); + +test('stack can follows first in, last out', () => { + const s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + expect(s.pop()).toEqual(3); + expect(s.pop()).toEqual(2); + expect(s.pop()).toEqual(1); +}); + +test('peek returns the first element but doesnt pop it', () => { + const s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + expect(s.peek()).toEqual(3); + expect(s.pop()).toEqual(3); + expect(s.peek()).toEqual(2); + expect(s.pop()).toEqual(2); + expect(s.peek()).toEqual(1); + expect(s.pop()).toEqual(1); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/steps/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/steps/index.js new file mode 100644 index 0000000..fd73326 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/steps/index.js @@ -0,0 +1,50 @@ +// --- Directions +// Write a function that accepts a positive number N. +// The function should console log a step shape +// with N levels using the # character. Make sure the +// step has spaces on the right hand side! +// --- Examples +// steps(2) +// '# ' +// '##' +// steps(3) +// '# ' +// '## ' +// '###' +// steps(4) +// '# ' +// '## ' +// '### ' +// '####' + +function steps(n, row = 0, stair = '') { + if (n === row) { + return; + } + + if (n === stair.length) { + console.log(stair); + return steps(n, row + 1); + } + + const add = stair.length <= row ? '#' : ' '; + steps(n, row, stair + add); +} + +module.exports = steps; + +// function steps(n) { +// for (let row = 0; row < n; row++) { +// let stair = ''; +// +// for (let column = 0; column < n; column++) { +// if (column <= row) { +// stair += '#'; +// } else { +// stair += ' '; +// } +// } +// +// console.log(stair); +// } +// } diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/steps/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/steps/test.js new file mode 100644 index 0000000..007af11 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/steps/test.js @@ -0,0 +1,34 @@ +const steps = require('./index'); + +beforeEach(() => { + jest.spyOn(console, 'log'); +}); + +afterEach(() => { + console.log.mockRestore(); +}); + +test('steps is a function', () => { + expect(typeof steps).toEqual('function'); +}); + +test('steps called with n = 1', () => { + steps(1); + expect(console.log.mock.calls[0][0]).toEqual('#'); + expect(console.log.mock.calls.length).toEqual(1); +}); + +test('steps called with n = 2', () => { + steps(2); + expect(console.log.mock.calls[0][0]).toEqual('# '); + expect(console.log.mock.calls[1][0]).toEqual('##'); + expect(console.log.mock.calls.length).toEqual(2); +}); + +test('steps called with n = 3', () => { + steps(3); + expect(console.log.mock.calls[0][0]).toEqual('# '); + expect(console.log.mock.calls[1][0]).toEqual('## '); + expect(console.log.mock.calls[2][0]).toEqual('###'); + expect(console.log.mock.calls.length).toEqual(3); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/tree/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/tree/index.js new file mode 100644 index 0000000..3bfb536 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/tree/index.js @@ -0,0 +1,56 @@ +// --- Directions +// 1) Create a node class. The constructor +// should accept an argument that gets assigned +// to the data property and initialize an +// empty array for storing children. The node +// class should have methods 'add' and 'remove'. +// 2) Create a tree class. The tree constructor +// should initialize a 'root' property to null. +// 3) Implement 'traverseBF' and 'traverseDF' +// on the tree class. Each method should accept a +// function that gets called with each element in the tree + +class Node { + constructor(data) { + this.data = data; + this.children = []; + } + + add(data) { + this.children.push(new Node(data)); + } + + remove(data) { + this.children = this.children.filter(node => { + return node.data !== data; + }); + } +} + +class Tree { + constructor() { + this.root = null; + } + + traverseBF(fn) { + const arr = [this.root]; + while (arr.length) { + const node = arr.shift(); + + arr.push(...node.children); + fn(node); + } + } + + traverseDF(fn) { + const arr = [this.root]; + while (arr.length) { + const node = arr.shift(); + + arr.unshift(...node.children); + fn(node); + } + } +} + +module.exports = { Tree, Node }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/tree/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/tree/test.js new file mode 100644 index 0000000..69dab5d --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/tree/test.js @@ -0,0 +1,67 @@ +const T = require('./index'); +const Node = T.Node; +const Tree = T.Tree; + +describe('Node', () => { + test('Node is a constructor', () => { + expect(typeof Node.prototype.constructor).toEqual('function'); + }); + + test('Node has a data and children properties', () => { + const n = new Node('a'); + expect(n.data).toEqual('a'); + expect(n.children.length).toEqual(0); + }); + + test('Node can add children', () => { + const n = new Node('a'); + n.add('b'); + expect(n.children.length).toEqual(1); + expect(n.children[0].children).toEqual([]); + }); + + test('Node can remove children', () => { + const n = new Node('a'); + n.add('b'); + expect(n.children.length).toEqual(1); + n.remove('b'); + expect(n.children.length).toEqual(0); + }); +}); + +describe('Tree', () => { + test('starts empty', () => { + const t = new Tree(); + expect(t.root).toEqual(null); + }); + + test('Can traverse bf', () => { + const letters = []; + const t = new Tree(); + t.root = new Node('a'); + t.root.add('b'); + t.root.add('c'); + t.root.children[0].add('d'); + + t.traverseBF(node => { + letters.push(node.data); + }); + + expect(letters).toEqual(['a', 'b', 'c', 'd']); + }); + + test('Can traverse DF', () => { + const letters = []; + const t = new Tree(); + t.root = new Node('a'); + t.root.add('b'); + t.root.add('d'); + t.root.children[0].add('c'); + + t.traverseDF(node => { + letters.push(node.data); + }); + + expect(letters).toEqual(['a', 'b', 'c', 'd']); + }); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/validate/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/validate/index.js new file mode 100644 index 0000000..9f4da37 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/validate/index.js @@ -0,0 +1,28 @@ +// --- Directions +// Given a node, validate the binary search tree, +// ensuring that every node's left hand child is +// less than the parent node's value, and that +// every node's right hand child is greater than +// the parent + +function validate(node, min = null, max = null) { + if (max !== null && node.data > max) { + return false; + } + + if (min !== null && node.data < min) { + return false; + } + + if (node.left && !validate(node.left, min, node.data)) { + return false; + } + + if (node.right && !validate(node.right, node.data, max)) { + return false; + } + + return true; +} + +module.exports = validate; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/validate/node.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/validate/node.js new file mode 100644 index 0000000..d19e208 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/validate/node.js @@ -0,0 +1,21 @@ +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + + insert(data) { + if (data < this.data && this.left) { + this.left.insert(data); + } else if (data < this.data) { + this.left = new Node(data); + } else if (data > this.data && this.right) { + this.right.insert(data); + } else if (data > this.data) { + this.right = new Node(data); + } + } +} + +module.exports = Node; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/validate/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/validate/test.js new file mode 100644 index 0000000..6ea4dc3 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/validate/test.js @@ -0,0 +1,23 @@ +const Node = require('./node'); +const validate = require('./index'); + +test('Validate recognizes a valid BST', () => { + const n = new Node(10); + n.insert(5); + n.insert(15); + n.insert(0); + n.insert(20); + + expect(validate(n)).toEqual(true); +}); + +test('Validate recognizes an invalid BST', () => { + const n = new Node(10); + n.insert(5); + n.insert(15); + n.insert(0); + n.insert(20); + n.left.left.right = new Node(999); + + expect(validate(n)).toEqual(false); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/vowels/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/vowels/index.js new file mode 100644 index 0000000..379ba6c --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/vowels/index.js @@ -0,0 +1,28 @@ +// --- Directions +// Write a function that returns the number of vowels +// used in a string. Vowels are the characters 'a', 'e' +// 'i', 'o', and 'u'. +// --- Examples +// vowels('Hi There!') --> 3 +// vowels('Why do you ask?') --> 4 +// vowels('Why?') --> 0 + +function vowels(str) { + const matches = str.match(/[aeiou]/gi); + return matches ? matches.length : 0; +} + +module.exports = vowels; + +// function vowels(str) { +// let count = 0; +// const checker = ['a', 'e', 'i', 'o', 'u']; +// +// for (let char of str.toLowerCase()) { +// if (checker.includes(char)) { +// count++; +// } +// } +// +// return count; +// } diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/vowels/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/vowels/test.js new file mode 100644 index 0000000..0bbf430 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/vowels/test.js @@ -0,0 +1,17 @@ +const vowels = require('./index'); + +test('Vowels is a function', () => { + expect(typeof vowels).toEqual('function'); +}); + +test('returns the number of vowels used', () => { + expect(vowels('aeiou')).toEqual(5); +}); + +test('returns the number of vowels used', () => { + expect(vowels('abcdefghijklmnopqrstuvwxyz')).toEqual(5); +}); + +test('returns the number of vowels used', () => { + expect(vowels('bcdfghjkl')).toEqual(0); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/weave/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/weave/index.js new file mode 100644 index 0000000..0818cb2 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/weave/index.js @@ -0,0 +1,43 @@ +// --- Directions +// 1) Complete the task in weave/queue.js +// 2) Implement the 'weave' function. Weave +// receives two queues as arguments and combines the +// contents of each into a new, third queue. +// The third queue should contain the *alterating* content +// of the two queues. The function should handle +// queues of different lengths without inserting +// 'undefined' into the new one. +// *Do not* access the array inside of any queue, only +// use the 'add', 'remove', and 'peek' functions. +// --- Example +// const queueOne = new Queue(); +// queueOne.add(1); +// queueOne.add(2); +// const queueTwo = new Queue(); +// queueTwo.add('Hi'); +// queueTwo.add('There'); +// const q = weave(queueOne, queueTwo); +// q.remove() // 1 +// q.remove() // 'Hi' +// q.remove() // 2 +// q.remove() // 'There' + +const Queue = require('./queue'); + +function weave(sourceOne, sourceTwo) { + const q = new Queue(); + + while (sourceOne.peek() || sourceTwo.peek()) { + if (sourceOne.peek()) { + q.add(sourceOne.remove()); + } + + if (sourceTwo.peek()) { + q.add(sourceTwo.remove()); + } + } + + return q; +} + +module.exports = weave; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/weave/queue.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/weave/queue.js new file mode 100644 index 0000000..20044c2 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/weave/queue.js @@ -0,0 +1,25 @@ +// --- Directions +// Implement a 'peek' method in this Queue class. +// Peek should return the last element (the next +// one to be returned) from the queue *without* +// removing it. + +class Queue { + constructor() { + this.data = []; + } + + add(record) { + this.data.unshift(record); + } + + remove() { + return this.data.pop(); + } + + peek() { + return this.data[this.data.length - 1]; + } +} + +module.exports = Queue; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/weave/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/weave/test.js new file mode 100644 index 0000000..f173360 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/completed_exercises/weave/test.js @@ -0,0 +1,45 @@ +const weave = require('./index'); +const Queue = require('./queue'); + +test('queues have a peek function', () => { + const q = new Queue(); + expect(typeof q.peek).toEqual('function'); +}); + +test('peek returns, but does not remove, the first value', () => { + const q = new Queue(); + q.add(1); + q.add(2); + expect(q.peek()).toEqual(1); + expect(q.peek()).toEqual(1); + expect(q.remove()).toEqual(1); + expect(q.remove()).toEqual(2); +}); + +test('weave is a function', () => { + expect(typeof weave).toEqual('function'); +}); + +test('weave can combine two queues', () => { + const one = new Queue(); + one.add(1); + one.add(2); + one.add(3); + one.add(4); + const two = new Queue(); + two.add('one'); + two.add('two'); + two.add('three'); + two.add('four'); + + const result = weave(one, two); + expect(result.remove()).toEqual(1); + expect(result.remove()).toEqual('one'); + expect(result.remove()).toEqual(2); + expect(result.remove()).toEqual('two'); + expect(result.remove()).toEqual(3); + expect(result.remove()).toEqual('three'); + expect(result.remove()).toEqual(4); + expect(result.remove()).toEqual('four'); + expect(result.remove()).toBeUndefined(); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/01/.gitkeep b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/01/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/01/diagrams.xml b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/01/diagrams.xml new file mode 100644 index 0000000..8b9e993 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/01/diagrams.xml @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/02/.gitkeep b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/02/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/02/diagrams.xml b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/02/diagrams.xml new file mode 100644 index 0000000..19e74dd --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/02/diagrams.xml @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/03/.gitkeep b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/03/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/03/diagrams.xml b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/03/diagrams.xml new file mode 100644 index 0000000..d837be7 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/03/diagrams.xml @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/04/.gitkeep b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/04/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/04/diagrams.xml b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/04/diagrams.xml new file mode 100644 index 0000000..2224edd --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/04/diagrams.xml @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/05/.gitkeep b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/05/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/05/diagrams.xml b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/05/diagrams.xml new file mode 100644 index 0000000..ce1f41b --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/05/diagrams.xml @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/06/.gitkeep b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/06/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/06/diagrams.xml b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/06/diagrams.xml new file mode 100644 index 0000000..d593c22 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/06/diagrams.xml @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/07/.gitkeep b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/07/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/07/diagrams.xml b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/07/diagrams.xml new file mode 100644 index 0000000..15b0902 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/07/diagrams.xml @@ -0,0 +1 @@ +7ZxLc6s2FIB/jbcZ0IPH8iZN2kU705ks2i5lkDG9GHmwfOP011cYCQNyaoIRmkxFZjJwJDCcT0fnYeEVfNqdfq7IfvsbS2mxAl56WsGfVgDEsSf+14L3RoCgFGRVnjYi/yJ4zf+hUqi6HfOUHnodOWMFz/d9YcLKkia8JyNVxd763Tas6H/qnmRUE7wmpNClf+Qp30qp73mXhl9onm3lR0dYNqxJ8j2r2LGUn7cCcHPemuYdUdeS/Q9bkrK3jgg+r+BTxRhv9nanJ1rUqlVqa857+aC1ve+KlnzMCbg54QcpjlTd8fm++LvSxflpaN3fW8HHt23O6eueJHXrm4AvZFu+K8SRL3bb56n7FmRNi8dWI0+sYJVoKllJ6668Yt+pEgpFeVH917YoxQudPG7youj0lCoVclZyOXp8LI+7VzxvQk6KPCuFLBFqoaLxUT42rTg9fag6vwUixjllO8qrd9FFnYCk8uQYB1he4q0zYtS433YGSyBlRA7SrL30BZTYkayucws0bllFaWkPXgTWMAjGwEsxjVL0BeCFhtiFGiWaitlHHrKKb1nGSlI8X6SPfY4dZvSU8z87+3/VXR7wGQSp+Ld6MuxiE7KXvL6184VomaoeSUEOhzxphLJLfdG/KefvEhM5ciZEl1v8lbG9GjyaOSt+/REBB+SD/yDfKKrWTg/zgR2rRIoi6R1IlVFF3hs9GipaEJ7/6F/+HraRm0+nmiTwb5tkYMgkY4dtKjboQXtuUJl6B9y63rMGL0giut6McoOERpvkC8Az5QZ9X8Pk/OBkP+gD3RECi45Q3Y+bUidYZXjbKk15Qh/e5ibOEIk4vc2MHPZNdr7JTzXngfkug7RF1UEK0MJIgfKACmkQaEihryOFc5gickhNWGkU2UOq121SwomGVTwdH0yjPa1LFF31SpGmsVpXeUKKb7Jhl6dp8dGAmTwoxnrEcz/5nGAGmH7Qt0+oNNyBia5MuWCOKVcv5pQ1Nwdz6mQLsD2YobPMWWFCZR42YOrlHGeZ9/lM3x5MV+SZzA0Fg1hnySIP0Is8lWBkjd06wgjrCf01dlFCE9s1njHsTNV4gKvxzFjjURNWr8YTjh4Ps9d41P24GfXzVonhbas0VeMBrsZjBCkelO0WLAgAvcbj0o67vKbFSPXKqhyXdtxlmcheDnllqY5zkiO5BcDid8tAr+SwipSZxW+X0zBeXwkzr+KjgfXMYww+U5mHsniXeUzNPDTOg2TkysortFjm4dZZTbfK2N63y1Av5ehm6jKPzyINPXtfRapruMxjNU+wGkB7wSrUKzou87jPMu2lkQEyEQI1YU8bBP2fQyCI7gx35Km/s1x8SjtmosFaIYgHg6EJueRZg/HQ3sY4e9fLRhty0O19uVjqOssrjvflvH2CsZFYKuzP1QiFmnlHoW7eaA7zhs68zZo3NmLe2FvOvPVC4qEQlJx5jywCx31US5o3GpEquRT3g6grjHvcFq0bIj0h2h+rfWGxbhgHISSjXs6kfopp+AXwmaob4siEV3V1w9arImDEq8bQe0DeZeunXSDyH0Cn1cOmXC7SM2g3bY+0+wjdtntTlUnk1kQYQaqKEBYqk8itiZi5mBWDHswli1nIrYmYF2aEQ2swscttJnOLh28SLpnbYD23ySr6bg9ecN5GwcP13xeAZyyzcSsizGY22Exm43sRfhhEUYulM9ilM9PfKfW829ZuKp/BLp8xw3T4K0ULJjTYJTTzxsAx6i+FWjQGdgnNzK/we4NVUAZpisPLb3Q2bvXyO6jw+V8=7ZxNk5s4EIZ/ja8pQHwe48nM7mFzmkM2RxlkzEZGLlmO7fz6FUbCQDMxY/NRsyunKgUtgaEfdYt+kWeBnranPzjebb6yhNCFYyWnBfqycJwosuT/heFcGlykDCnPktJkXw2v2S+ijLrbIUvIvtFRMEZFtmsaY5bnJBYNG+acHZvd1ow2v3WHUwIMrzGm0PotS8RGWW3Lujb8SbJ0o7469FTDCsc/Us4Oufq+hYPWl0/ZvMX6XKr/foMTdqyZ0PMCPXHGRLm1PT0RWrhWu6087uWN1uq6OclFnwOc8oCfmB6IvuLLdYmz9sXlbkjR31qg5XGTCfK6w3HRepTwpW0jtlTu2XKzup+iL8UrQpeVR54YZVw25SwnRVfB2Q+ijdJRVlj8q1q046VPluuM0lpP5VJpZ7lQo8f21H79jJePtGOapbm0xdItRDYu1W0TLsjpTdfZFRA5zgnbEsHPsos6QI7q8pBza/9YGzF63G9qg8VXNqwGaVqd+gpKbihW3dwQ4JZyQvL54IXOCvl+H3iJR8LE/QDwgpHYuYASSWT2UbuMiw1LWY7p89W6bHKsMSOnTPxd2/5edPnkXUBgLj4XybCOTdpesuLSLicieaJ7xBTv91lcGlWX4qT/ECHOChM+CCZN10v8i7GdHjwgnDW/5ohALfL+b8iXjiq808C8ZwceK5OnZgfMU6IYBb0HAycUi+xn8+yPoPVMOr07IqPbEemPFJG+wXYvNpn455sFA8BtVWzNxs6PQ7Ja95oEMQnX8QdgN9YkGJpJcLhJMIKToD3jLBiZdHpvSLre7ZAcaxbUxffvuMkjZA1ObjPD+11ZmK+zU8G5FbzTIK1Q1ZA67sRIkRU1kaIIIEU2RIoGiETbNkjHiFI/mA8plGwSLDDAKu9OtNJow+sKRd29ygQ8VvgqizH9rBq2WZLQtwbM3YOi73x46afu0xkAZgVPwwxDANPtSLnOECkX6jh5wc3AvDvZuvPBdE1kDgsz8uaDCaUcE5mPzZnWfDCNwHM3N89tPetMKfDYUOHhktFs7Fah53qwnO9iF8Yknlvg6cNuLIHHNgrPgAqP3SHxaJhzSDy20Xjujkrfvh2VY2k8jtF4RkGKWrLdhIKAAzUeU3Y8NGvO+KSqw9GUHQPB9J1WsrVgsh0NJlR3zCTZk1tgtTLqlGWHA5UcxnGezvhqOQmiVcdjZic+4s9eefTBN9r6qokqD+kKfq6aip2yzflvlyVgEDQrFb2Ypl6poKB7sAxelpiVPA+EbHA7ZEcrS6DOA2PYlCXvRhrO955Sr/AxZclimCfZwJ7vbUjHkh5TljwWmfPVmAgKBmu8hzCnmyi7n1U6surL5fMObuOs/miyc0MbsNOJt87OHYIdLCn3VPrdsOv5SrmlvU7KDlaV5uG0t8Da5Ib0Cqwp5ADfgw+jjxeUqojUJWW9oKzVl9+refR/Wk+ijl/4lG+fJqgnEVwFsjvwHZ1RCIr8AOFeP7QjduKR4AME7lhCEOpRVZqE+5aAd5vbWGoAgqUjTMBGDXg3Uu1GjVT//GcCNQDBAtKoAQ/lVa9VhCD4IDtWAenCRQRGDRhS2hkRpty9/nWJS1vtL3ig538B7Zxdc6M2FIZ/jW8zCImvy3U2aS/amc7kou2lDDKmi5FHltd2f32FkTAgsiY2oKYVmcnAQXxYj450zotgAZ+3p58Y3m1+pQnJF66TnBbw68J1o8gR/0vDuTIgKA0py5LKBK6Gt+xvIo2q2CFLyL5VkFOa82zXNsa0KEjMWzbMGD22i61p3r7qDqdEM7zFONetv2cJ30grcJzrjp9Jlm7kpUNP7ljh+FvK6KGQ11u4cH1Zqt1brM4ly+83OKHHhgm+LOAzo5RXa9vTM8nLqlXVVh33+s7e+r4ZKfiQA9zqgO84PxB1x5f74mdVF5dfQ8ryzgIuj5uMk7cdjsu9RwFf2DZ8m4stIFbr31OWzfGK5Mu6Rp5pTpnYVdCClEU5o9+IMoqKcsLyr96jKl7UyXKd5XmjpKxSYacFl60HeHK7ecbLIuw4z9JC2GJRLUTsXMqfTRgnp3erDtRARDsndEs4O4siqpFLhLKJ10iPjQajmv2m0VZ8acOyjab1ma+cxIpE1Y8NathSRkhhjl3orqDvD2GXeCRM0L+fXTAROqRBIonoe+QmZXxDU1rg/OVqXbYxNpCRU8b/aKz/WRZ58i4cMONfyq6wSU3YXrPy1i4nIkWiSsQ53u+zuDLKIuVJ/yKcnyUlfOBUmK63+AulO9V2NGdW+NoNAnbA+z8AX1VUWTstynt6YLE0eXJswCwlklEwuC0wkmOefW+f/RG0nu1M73VI4N/2SH8ij/QttnuxuSg0NwgGGrdVuWaMnR+HZLUeNAZiEq7jT8BuqkEwtIPgeINgpA+CwOAoGNnu9F6XhOC2S041CqrU+0fcxBEiAye3meH9rkrL19mp5Nxx3nmQ1qgaSF00M1IQeG2k0NOQQqAjhSN4IgAW6RReCqE5pLpgk2CONazi1/FON9qqdYmiWb3SpNVYWVdZjPMvcsc2S5L8vQZzd6MYOh5eysnf6Y4AEzgd/wyRBhP1dLnuGF2uLuMUJTcL8+7O1jEHE1nPHBWm6wNzMHUpx3rmQ2OmUllMwLQCz93cEOjEOnMKPEBXeJhgZIzdKvSQp6fzfezCmMSmBZ4h7KYSeIBVeEZUeECPxKMeJJmQeIDVeO73yvC2V06l8bhW45kEadSR7WYUBFxd47Fpx0MwDUaqyh1t2jEWzMhcDtkzSccOkgO5eb7B58quruRQhovU4KPlJIhWPWFmLz7iG888huCbKvNQs3Bs5jFG5qEGw2bmoaIbE5mHnaxzv1f60NzT5Z7JOrqb2szjw0g9c48i1SQem3ksxglWvdBgsKorOjbzeMgzkbk00uvpWx8Pgaqwpw6C/tMhkMa5HRXBR8MdeehvNBNXub6VoOZgndVlOo2hisLkUZ32UN/GsBdIdNlojfe6v88XS/Wz7Bl4Xy/LBxhPkuEE7VgKqYeMDfcOA9290RjuDTRM1r1HdW84iXujIJrNvXXtaZ8LSta9B+qGsD0rbE73hrr8ZJDb50pxA6XdGXkpU580tDuwXW5QN4z8AOJBr2USkHgk+AT4ptINoT/FqPp/1Q3hBC+g9I+qYeA9dXQtz3lyncbiTTbMDlC1bFf9jq9Ht319KjUS6tKV7vxWjfwo0tBpB7hzqpFQF7CsGvmQf6rOzYCApc5r1ciRYIaOaw7mgLfQ7CD5Drfu24Nz5jPI1cCljJzNwfMvyyB4Xvn3CeBN9pUZqAc0Npu5N5tBE8y17s9mgAOdJxBdF1OpDbIq1P1fl0K3HX+q1AYN+AiRTW0+jrT7faIZUxukz3myqc1DA3PY6VXnjIZ1ycimNg95ZncK1JwwdR2pEJuXNUePwOzTtmGz9OuMppnlqHGs1buiDzMUm9evq1Zx0fULtvDlHw== \ No newline at end of file diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/08/.gitkeep b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/08/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/08/diagrams.xml b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/08/diagrams.xml new file mode 100644 index 0000000..c461e6e --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/08/diagrams.xml @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/09/.gitkeep b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/09/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/09/diagrams.xml b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/09/diagrams.xml new file mode 100644 index 0000000..657f03c --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/09/diagrams.xml @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/10/.gitkeep b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/10/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/10/diagrams.xml b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/10/diagrams.xml new file mode 100644 index 0000000..0273620 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/diagrams/10/diagrams.xml @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/index.js new file mode 100644 index 0000000..35cd037 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/index.js @@ -0,0 +1,13 @@ +// --- Directions +// Check to see if two provided strings are anagrams of eachother. +// One string is an anagram of another if it uses the same characters +// in the same quantity. Only consider characters, not spaces +// or punctuation. Consider capital letters to be the same as lower case +// --- Examples +// anagrams('rail safety', 'fairy tales') --> True +// anagrams('RAIL! SAFETY!', 'fairy tales') --> True +// anagrams('Hi there', 'Bye there') --> False + +function anagrams(stringA, stringB) {} + +module.exports = anagrams; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/test.js new file mode 100644 index 0000000..60f117b --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/test.js @@ -0,0 +1,27 @@ +const anagrams = require('./index.js'); + +test('anagrams function exists', () => { + expect(typeof anagrams).toEqual('function'); +}); + +test('"hello" is an anagram of "llohe"', () => { + expect(anagrams('hello', 'llohe')).toBeTruthy(); +}); + +test('"Whoa! Hi!" is an anagram of "Hi! Whoa!"', () => { + expect(anagrams('Whoa! Hi!', 'Hi! Whoa!')).toBeTruthy(); +}); + +test('"One One" is not an anagram of "Two two two"', () => { + expect(anagrams('One One', 'Two two two')).toBeFalsy(); +}); + +test('"One one" is not an anagram of "One one c"', () => { + expect(anagrams('One one', 'One one c')).toBeFalsy(); +}); + +test('"A tree, a life, a bench" is not an anagram of "A tree, a fence, a yard"', () => { + expect( + anagrams('A tree, a life, a bench', 'A tree, a fence, a yard') + ).toBeFalsy(); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/bst/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/bst/index.js new file mode 100644 index 0000000..25aabd6 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/bst/index.js @@ -0,0 +1,16 @@ +// --- Directions +// 1) Implement the Node class to create +// a binary search tree. The constructor +// should initialize values 'data', 'left', +// and 'right'. +// 2) Implement the 'insert' method for the +// Node class. Insert should accept an argument +// 'data', then create an insert a new node +// at the appropriate location in the tree. +// 3) Implement the 'contains' method for the Node +// class. Contains should accept a 'data' argument +// and return the Node in the tree with the same value. + +class Node {} + +module.exports = Node; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/bst/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/bst/test.js new file mode 100644 index 0000000..331ae22 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/bst/test.js @@ -0,0 +1,41 @@ +const Node = require('./index'); + +test('Node is a constructor', () => { + expect(typeof Node.prototype.constructor).toEqual('function'); +}); + +test('Node can insert correctly', () => { + const node = new Node(10); + node.insert(5); + node.insert(15); + node.insert(17); + + expect(node.left.data).toEqual(5); + expect(node.right.data).toEqual(15); + expect(node.right.right.data).toEqual(17); +}); + +test('Contains returns node with the same data', () => { + const node = new Node(10); + node.insert(5); + node.insert(15); + node.insert(20); + node.insert(0); + node.insert(-5); + node.insert(3); + + const three = node.left.left.right; + expect(node.contains(3)).toEqual(three); +}); + +test('Contains returns null if value not found', () => { + const node = new Node(10); + node.insert(5); + node.insert(15); + node.insert(20); + node.insert(0); + node.insert(-5); + node.insert(3); + + expect(node.contains(9999)).toEqual(null); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/index.js new file mode 100644 index 0000000..ba9cb59 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/index.js @@ -0,0 +1,12 @@ +// --- Directions +// Write a function that accepts a string. The function should +// capitalize the first letter of each word in the string then +// return the capitalized string. +// --- Examples +// capitalize('a short sentence') --> 'A Short Sentence' +// capitalize('a lazy fox') --> 'A Lazy Fox' +// capitalize('look, it is working!') --> 'Look, It Is Working!' + +function capitalize(str) {} + +module.exports = capitalize; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/test.js new file mode 100644 index 0000000..21a2423 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/test.js @@ -0,0 +1,17 @@ +const capitalize = require('./index'); + +test('Capitalize is a function', () => { + expect(typeof capitalize).toEqual('function'); +}); + +test('capitalizes the first letter of every word in a sentence', () => { + expect(capitalize('hi there, how is it going?')).toEqual( + 'Hi There, How Is It Going?' + ); +}); + +test('capitalizes the first letter', () => { + expect(capitalize('i love breakfast at bill miller bbq')).toEqual( + 'I Love Breakfast At Bill Miller Bbq' + ); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/index.js new file mode 100644 index 0000000..8e7a800 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/index.js @@ -0,0 +1,13 @@ +// --- Directions +// Given an array and chunk size, divide the array into many subarrays +// where each subarray is of length size +// --- Examples +// chunk([1, 2, 3, 4], 2) --> [[ 1, 2], [3, 4]] +// chunk([1, 2, 3, 4, 5], 2) --> [[ 1, 2], [3, 4], [5]] +// chunk([1, 2, 3, 4, 5, 6, 7, 8], 3) --> [[ 1, 2, 3], [4, 5, 6], [7, 8]] +// chunk([1, 2, 3, 4, 5], 4) --> [[ 1, 2, 3, 4], [5]] +// chunk([1, 2, 3, 4, 5], 10) --> [[ 1, 2, 3, 4, 5]] + +function chunk(array, size) {} + +module.exports = chunk; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/test.js new file mode 100644 index 0000000..ef3d645 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/test.js @@ -0,0 +1,33 @@ +const chunk = require('./index'); + +test('function chunk exists', () => { + expect(typeof chunk).toEqual('function'); +}); + +test('chunk divides an array of 10 elements with chunk size 2', () => { + const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + const chunked = chunk(arr, 2); + + expect(chunked).toEqual([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]); +}); + +test('chunk divides an array of 3 elements with chunk size 1', () => { + const arr = [1, 2, 3]; + const chunked = chunk(arr, 1); + + expect(chunked).toEqual([[1], [2], [3]]); +}); + +test('chunk divides an array of 5 elements with chunk size 3', () => { + const arr = [1, 2, 3, 4, 5]; + const chunked = chunk(arr, 3); + + expect(chunked).toEqual([[1, 2, 3], [4, 5]]); +}); + +test('chunk divides an array of 13 elements with chunk size 5', () => { + const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; + const chunked = chunk(arr, 5); + + expect(chunked).toEqual([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13]]); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/index.js new file mode 100644 index 0000000..6a1a9a9 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/index.js @@ -0,0 +1,17 @@ +// --- Directions +// Given a linked list, return true if the list +// is circular, false if it is not. +// --- Examples +// const l = new List(); +// const a = new Node('a'); +// const b = new Node('b'); +// const c = new Node('c'); +// l.head = a; +// a.next = b; +// b.next = c; +// c.next = b; +// circular(l) // true + +function circular(list) {} + +module.exports = circular; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/linkedlist.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/linkedlist.js new file mode 100644 index 0000000..b7da56b --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/linkedlist.js @@ -0,0 +1,178 @@ +class Node { + constructor(data, next = null) { + this.data = data; + this.next = next; + } +} + +class LinkedList { + constructor(values = []) { + this.head = null; + + for (let value of values) { + this.insertLast(value); + } + } + + clear() { + this.head = null; + } + + size() { + let counter = 0; + let node = this.head; + + while (node) { + counter++; + node = node.next; + } + + return counter; + } + + getAt(index) { + if (!this.head) { + return null; + } + + let counter = 0; + let node = this.head; + while (node) { + if (counter === index) { + return node; + } + node = node.next; + counter++; + } + return null; + } + + insertAt(data, index) { + if (!this.head) { + this.head = new Node(data); + return; + } + + if (index === 0) { + this.head = new Node(data, this.head); + return; + } + + let counter = 1; + let previous = this.head; + let node = this.head.next; + while (node) { + if (counter === index) { + previous.next = new Node(data, node); + return; + } + previous = node; + node = node.next; + counter++; + } + + previous.next = new Node(data, node); + } + + removeFirst() { + if (!this.head) { + return; + } + + this.head = this.head.next; + } + + removeLast() { + if (!this.head) { + return; + } + + if (!this.head.next) { + this.head = null; + return; + } + + let previous = this.head; + let node = this.head.next; + while (node.next) { + previous = node; + node = node.next; + } + previous.next = null; + } + + removeAt(index) { + if (!this.head) { + return; + } + + let counter = 0; + let node = this.head; + while (node) { + if (counter === index - 1) { + if (node.next) { + return (node.next = node.next.next); + } else { + return (node.next = null); + } + } + node = node.next; + counter++; + } + } + + getFirst() { + return this.head; + } + + insertFirst(data) { + this.head = new Node(data, this.getFirst()); + } + + getLast() { + if (!this.head) { + return null; + } + + let node = this.head; + while (node.next) { + node = node.next; + } + + return node; + } + + insertLast(data) { + const last = this.getLast(); + + if (last) { + last.next = new Node(data); + return last.next; + } else { + this.head = new Node(data); + return this.head; + } + } + + forEach(fn) { + if (!this.head) { + return null; + } + + let node = this.head; + while (node) { + fn(node); + node = node.next; + } + } + + *[Symbol.iterator]() { + let node = this.head; + while (node) { + yield node; + node = node.next; + } + } +} + +module.exports = { Node, LinkedList }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/test.js new file mode 100644 index 0000000..7cb50b2 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/test.js @@ -0,0 +1,50 @@ +const circular = require('./index'); +const L = require('./linkedlist'); +const List = L.LinkedList; +const Node = L.Node; + +test('circular', () => { + expect(typeof circular).toEqual('function'); +}); + +test('circular detects circular linked lists', () => { + const l = new List(); + const a = new Node('a'); + const b = new Node('b'); + const c = new Node('c'); + + l.head = a; + a.next = b; + b.next = c; + c.next = b; + + expect(circular(l)).toEqual(true); +}); + +test('circular detects circular linked lists linked at the head', () => { + const l = new List(); + const a = new Node('a'); + const b = new Node('b'); + const c = new Node('c'); + + l.head = a; + a.next = b; + b.next = c; + c.next = a; + + expect(circular(l)).toEqual(true); +}); + +test('circular detects non-circular linked lists', () => { + const l = new List(); + const a = new Node('a'); + const b = new Node('b'); + const c = new Node('c'); + + l.head = a; + a.next = b; + b.next = c; + c.next = null; + + expect(circular(l)).toEqual(false); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/example.html b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/example.html new file mode 100644 index 0000000..3de3dae --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/example.html @@ -0,0 +1,10 @@ + + + + +

Click the button

+ + + diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/index.js new file mode 100644 index 0000000..7d9b0dd --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/index.js @@ -0,0 +1,19 @@ +// --- Directions +// Create an 'eventing' library out of the +// Events class. The Events class should +// have methods 'on', 'trigger', and 'off'. + +class Events { + // Register an event handler + on(eventName, callback) {} + + // Trigger all callbacks associated + // with a given eventName + trigger(eventName) {} + + // Remove all event handlers associated + // with the given eventName + off(eventName) {} +} + +module.exports = Events; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/test.js new file mode 100644 index 0000000..e015819 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/test.js @@ -0,0 +1,77 @@ +const Events = require('./index'); + +test('Events can be registered then triggered', () => { + const events = new Events(); + + const cb1 = jest.fn(); + + events.on('click', cb1); + events.trigger('click'); + + expect(cb1.mock.calls.length).toBe(1); +}); + +test('Multiple events can be registered then triggered', () => { + const events = new Events(); + + const cb1 = jest.fn(); + const cb2 = jest.fn(); + + events.on('click', cb1); + events.on('click', cb2); + events.trigger('click'); + + expect(cb1.mock.calls.length).toBe(1); + expect(cb2.mock.calls.length).toBe(1); +}); + +test('Events can be triggered multiple times', () => { + const events = new Events(); + + const cb1 = jest.fn(); + const cb2 = jest.fn(); + + events.on('click', cb1); + events.trigger('click'); + events.on('click', cb2); + events.trigger('click'); + events.trigger('click'); + + expect(cb1.mock.calls.length).toBe(3); + expect(cb2.mock.calls.length).toBe(2); +}); + +test('Events can have different names', () => { + const events = new Events(); + + const cb1 = jest.fn(); + const cb2 = jest.fn(); + + events.on('click', cb1); + events.trigger('click'); + events.on('hover', cb2); + events.trigger('click'); + events.trigger('hover'); + + expect(cb1.mock.calls.length).toBe(2); + expect(cb2.mock.calls.length).toBe(1); +}); + +test('Events can be toggled off', () => { + const events = new Events(); + + const cb1 = jest.fn(); + const cb2 = jest.fn(); + + events.on('hover', cb2); + + events.on('click', cb1); + events.trigger('click'); + events.off('click'); + events.trigger('click'); + + events.trigger('hover'); + + expect(cb1.mock.calls.length).toBe(1); + expect(cb2.mock.calls.length).toBe(1); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fib/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fib/index.js new file mode 100644 index 0000000..9efe84f --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fib/index.js @@ -0,0 +1,13 @@ +// --- Directions +// Print out the n-th entry in the fibonacci series. +// The fibonacci series is an ordering of numbers where +// each number is the sum of the preceeding two. +// For example, the sequence +// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] +// forms the first ten entries of the fibonacci series. +// Example: +// fib(4) === 3 + +function fib(n) {} + +module.exports = fib; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fib/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fib/test.js new file mode 100644 index 0000000..02a385d --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fib/test.js @@ -0,0 +1,25 @@ +const fib = require('./index'); + +test('Fib function is defined', () => { + expect(typeof fib).toEqual('function'); +}); + +test('calculates correct fib value for 1', () => { + expect(fib(1)).toEqual(1); +}); + +test('calculates correct fib value for 2', () => { + expect(fib(2)).toEqual(1); +}); + +test('calculates correct fib value for 3', () => { + expect(fib(3)).toEqual(2); +}); + +test('calculates correct fib value for 4', () => { + expect(fib(4)).toEqual(3); +}); + +test('calculates correct fib value for 15', () => { + expect(fib(39)).toEqual(63245986); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fizzbuzz/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fizzbuzz/index.js new file mode 100644 index 0000000..0aeab88 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fizzbuzz/index.js @@ -0,0 +1,17 @@ +// --- Directions +// Write a program that console logs the numbers +// from 1 to n. But for multiples of three print +// “fizz” instead of the number and for the multiples +// of five print “buzz”. For numbers which are multiples +// of both three and five print “fizzbuzz”. +// --- Example +// fizzBuzz(5); +// 1 +// 2 +// fizz +// 4 +// buzz + +function fizzBuzz(n) {} + +module.exports = fizzBuzz; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fizzbuzz/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fizzbuzz/test.js new file mode 100644 index 0000000..b25dc82 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fizzbuzz/test.js @@ -0,0 +1,39 @@ +const fizzBuzz = require('./index'); + +test('fizzBuzz function is defined', () => { + expect(fizzBuzz).toBeDefined(); +}); + +test('Calling fizzbuzz with `5` prints out 5 statements', () => { + fizzBuzz(5); + + expect(console.log.mock.calls.length).toEqual(5); +}); + +test('Calling fizzbuzz with 15 prints out the correct values', () => { + fizzBuzz(15); + + expect(console.log.mock.calls[0][0]).toEqual(1); + expect(console.log.mock.calls[1][0]).toEqual(2); + expect(console.log.mock.calls[2][0]).toEqual('fizz'); + expect(console.log.mock.calls[3][0]).toEqual(4); + expect(console.log.mock.calls[4][0]).toEqual('buzz'); + expect(console.log.mock.calls[5][0]).toEqual('fizz'); + expect(console.log.mock.calls[6][0]).toEqual(7); + expect(console.log.mock.calls[7][0]).toEqual(8); + expect(console.log.mock.calls[8][0]).toEqual('fizz'); + expect(console.log.mock.calls[9][0]).toEqual('buzz'); + expect(console.log.mock.calls[10][0]).toEqual(11); + expect(console.log.mock.calls[11][0]).toEqual('fizz'); + expect(console.log.mock.calls[12][0]).toEqual(13); + expect(console.log.mock.calls[13][0]).toEqual(14); + expect(console.log.mock.calls[14][0]).toEqual('fizzbuzz'); +}); + +beforeEach(() => { + jest.spyOn(console, 'log'); +}); + +afterEach(() => { + console.log.mockRestore(); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/index.js new file mode 100644 index 0000000..e5c9f31 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/index.js @@ -0,0 +1,16 @@ +// --- Directions +// Given a linked list, return the element n spaces +// from the last node in the list. Do not call the 'size' +// method of the linked list. Assume that n will always +// be less than the length of the list. +// --- Examples +// const list = new List(); +// list.insertLast('a'); +// list.insertLast('b'); +// list.insertLast('c'); +// list.insertLast('d'); +// fromLast(list, 2).data // 'b' + +function fromLast(list, n) {} + +module.exports = fromLast; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/linkedlist.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/linkedlist.js new file mode 100644 index 0000000..2029b3b --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/linkedlist.js @@ -0,0 +1,156 @@ +class Node { + constructor(data, next = null) { + this.data = data; + this.next = next; + } +} + +class LinkedList { + constructor() { + this.head = null; + } + + insertFirst(data) { + this.head = new Node(data, this.head); + } + + size() { + let counter = 0; + let node = this.head; + + while (node) { + counter++; + node = node.next; + } + + return counter; + } + + getFirst() { + return this.head; + } + + getLast() { + if (!this.head) { + return null; + } + + let node = this.head; + while (node) { + if (!node.next) { + return node; + } + node = node.next; + } + } + + clear() { + this.head = null; + } + + removeFirst() { + if (!this.head) { + return; + } + + this.head = this.head.next; + } + + removeLast() { + if (!this.head) { + return; + } + + if (!this.head.next) { + this.head = null; + return; + } + + let previous = this.head; + let node = this.head.next; + while (node.next) { + previous = node; + node = node.next; + } + previous.next = null; + } + + insertLast(data) { + const last = this.getLast(); + + if (last) { + // There are some existing nodes in our chain + last.next = new Node(data); + } else { + // The chain is empty! + this.head = new Node(data); + } + } + + getAt(index) { + let counter = 0; + let node = this.head; + while (node) { + if (counter === index) { + return node; + } + + counter++; + node = node.next; + } + return null; + } + + removeAt(index) { + if (!this.head) { + return; + } + + if (index === 0) { + this.head = this.head.next; + return; + } + + const previous = this.getAt(index - 1); + if (!previous || !previous.next) { + return; + } + previous.next = previous.next.next; + } + + insertAt(data, index) { + if (!this.head) { + this.head = new Node(data); + return; + } + + if (index === 0) { + this.head = new Node(data, this.head); + return; + } + + const previous = this.getAt(index - 1) || this.getLast(); + const node = new Node(data, previous.next); + previous.next = node; + } + + forEach(fn) { + let node = this.head; + let counter = 0; + while (node) { + fn(node, counter); + node = node.next; + counter++; + } + } + + *[Symbol.iterator]() { + let node = this.head; + while (node) { + yield node; + node = node.next; + } + } +} + +module.exports = { Node, LinkedList }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/test.js new file mode 100644 index 0000000..e4684d5 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/test.js @@ -0,0 +1,20 @@ +const fromLast = require('./index'); +const L = require('./linkedlist'); +const List = L.LinkedList; +const Node = L.Node; + +test('fromLast is a function', () => { + expect(typeof fromLast).toEqual('function'); +}); + +test('fromLast returns the node n elements from the end', () => { + const l = new List(); + + l.insertLast('a'); + l.insertLast('b'); + l.insertLast('c'); + l.insertLast('d'); + l.insertLast('e'); + + expect(fromLast(l, 3).data).toEqual('b'); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/index.js new file mode 100644 index 0000000..802cc4a --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/index.js @@ -0,0 +1,16 @@ +// --- Directions +// Given the root node of a tree, return +// an array where each element is the width +// of the tree at each level. +// --- Example +// Given: +// 0 +// / | \ +// 1 2 3 +// | | +// 4 5 +// Answer: [1, 3, 2] + +function levelWidth(root) {} + +module.exports = levelWidth; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/node.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/node.js new file mode 100644 index 0000000..5238e8f --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/node.js @@ -0,0 +1,10 @@ +module.exports = class Node { + constructor(data) { + this.data = data; + this.children = []; + } + + add(data) { + this.children.push(new Node(data)); + } +}; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/test.js new file mode 100644 index 0000000..35d20c2 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/test.js @@ -0,0 +1,27 @@ +const Node = require('./node'); +const levelWidth = require('./index'); + +test('levelWidth is a function', () => { + expect(typeof levelWidth).toEqual('function'); +}); + +test('levelWidth returns number of nodes at widest point', () => { + const root = new Node(0); + root.add(1); + root.add(2); + root.add(3); + root.children[0].add(4); + root.children[2].add(5); + + expect(levelWidth(root)).toEqual([1, 3, 2]); +}); + +test('levelWidth returns number of nodes at widest point', () => { + const root = new Node(0); + root.add(1); + root.children[0].add(2); + root.children[0].add(3); + root.children[0].children[0].add(4); + + expect(levelWidth(root)).toEqual([1, 1, 2, 1]); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/directions.html b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/directions.html new file mode 100644 index 0000000..ecb118d --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/directions.html @@ -0,0 +1,377 @@ + + + + + +

Node Class API

+ + + + + + + + + + + + + + + + + + + +
FunctionArgumentsReturnsDirectionsExample
Node.constructor(Data, Node)Node + Creates a class instance to represent a node. The node should + have two properties, 'data' and 'next'. Accept both + of these as arguments to the 'Node' constructor, then + assign them to the instance as properties 'data' and 'next'. + If 'next' is not provided to the constructor, then default its + value to be 'null'. + +
+            const n = new Node('There');
+            n.data // 'Hi'
+            n.next // null
+            const n2 = new Node('Hi', n);
+            n.next // returns n
+          
+
+ +

LinkedList Class API

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FunctionArgumentsReturnsDirectionsExample
constructor-(LinkedList) + Create a class to represent a linked list. When created, + a linked list should have *no* head node associated with it. + The LinkedList instance will have one property, 'head', which + is a reference to the first node of the linked list. By default + 'head' should be 'null'. + +
+            const list = new LinkedList();
+            list.head // null
+          
+
insertFirst(data)- + Creates a new Node from argument 'data' and assigns the resulting + node to the 'head' property. Make sure to handle the case in which + the linked list already has a node assigned to the 'head' property. + +
+            const list = new LinkedList();
+            list.insertFirst('Hi There'); // List has one node
+          
+
size-(integer) + Returns the number of nodes in the linked list. + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.insertFirst('c');
+            list.size(); // returns 3
+          
+
getFirst-(Node) + Returns the first node of the linked list. + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.getFirst(); // returns Node instance with data 'a'
+          
+
+ getLast + + - + + (Node) + + Returns the last node of the linked list + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.getLast(); // returns node with data 'a'
+          
+
+ clear + + - + + - + + Empties the linked list of any nodes. + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.clear();
+            list.size(); // returns 0
+          
+
+ removeFirst + + - + + - + + Removes only the first node of the linked list. The list's head should + now be the second element. + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.removeFirst();
+            list.getFirst(); // returns node with data 'a'
+          
+
+ removeLast + + - + + - + + Removes the last node of the chain + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.removeLast();
+            list.size(); // returns 1
+            list.getLast(); // returns node with data of 'b'
+          
+
+ insertLast + + (Data) + + - + + Inserts a new node with provided data at the end of the chain + +
+            const list = new LinkedList();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.insertLast('c');
+            list.getLast(); // returns node with data 'C'
+          
+
+ getAt + + (integer) + + (Node) + + Returns the node at the provided index + +
+            const list = new List();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.insertFirst('c');
+            list.getAt(1); // returns node with data 'b'
+          
+
+ removeAt + + (integer) + + - + + Removes node at the provided index + +
+            const list = new List();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.insertFirst('c');
+            list.removeAt(1);
+            list.getAt(1); // returns node with data 'a'
+          
+
+ insertAt + + (Data, integer) + + - + + Create an insert a new node at provided index. + If index is out of bounds, add the node to the end + of the list. + +
+            const list = new List();
+            list.insertFirst('a');
+            list.insertFirst('b');
+            list.insertFirst('c');
+            list.insertAt('Hi', 1)
+            list.getAt(1); // returns node with data 'Hi'
+          
+
+ forEach + + (function) + + - + + Calls the provided function with every node of the chain + +
+            const list = new List();
+
+            list.insertLast(1);
+            list.insertLast(2);
+            list.insertLast(3);
+            list.insertLast(4);
+
+            list.forEach(node => {
+              node.data += 10;
+            });
+            list.getAt(0); // Returns node with data '11'
+          
+
+ for...of Loop + + - + + - + + Linked list should be compatible as the subject of a 'for...of' loop + +
+            const list = new List();
+
+            list.insertLast(1);
+            list.insertLast(2);
+            list.insertLast(3);
+            list.insertLast(4);
+
+            for (let node of list) {
+              node.data += 10;
+            }
+
+            node.getAt(1); // returns node with data 11
+          
+
+ diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js new file mode 100644 index 0000000..c75cc87 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js @@ -0,0 +1,9 @@ +// --- Directions +// Implement classes Node and Linked Lists +// See 'directions' document + +class Node {} + +class LinkedList {} + +module.exports = { Node, LinkedList }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js new file mode 100644 index 0000000..18bdb64 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js @@ -0,0 +1,321 @@ +const L = require('./index'); +const List = L.LinkedList; +const Node = L.Node; + +test('List is a class', () => { + expect(typeof List.prototype.constructor).toEqual('function'); +}); + +test('Node is a class', () => { + expect(typeof Node.prototype.constructor).toEqual('function'); +}); + +describe.skip('A Node', () => { + test('has properties "data" and "next"', () => { + const node = new Node('a', 'b'); + expect(node.data).toEqual('a'); + expect(node.next).toEqual('b'); + }); +}); + +describe.skip('Insert First', () => { + test('appends a node to the start of the list', () => { + const l = new List(); + l.insertFirst(1); + expect(l.head.data).toEqual(1); + l.insertFirst(2); + expect(l.head.data).toEqual(2); + }); +}); + +describe.skip('Size', () => { + test('returns the number of items in the linked list', () => { + const l = new List(); + expect(l.size()).toEqual(0); + l.insertFirst(1); + l.insertFirst(1); + l.insertFirst(1); + l.insertFirst(1); + expect(l.size()).toEqual(4); + }); +}); + +describe.skip('GetFirst', () => { + test('returns the first element', () => { + const l = new List(); + l.insertFirst(1); + expect(l.getFirst().data).toEqual(1); + l.insertFirst(2); + expect(l.getFirst().data).toEqual(2); + }); +}); + +describe.skip('GetLast', () => { + test('returns the last element', () => { + const l = new List(); + l.insertFirst(2); + expect(l.getLast()).toEqual({ data: 2, next: null }); + l.insertFirst(1); + expect(l.getLast()).toEqual({ data: 2, next: null }); + }); +}); + +describe.skip('Clear', () => { + test('empties out the list', () => { + const l = new List(); + expect(l.size()).toEqual(0); + l.insertFirst(1); + l.insertFirst(1); + l.insertFirst(1); + l.insertFirst(1); + expect(l.size()).toEqual(4); + l.clear(); + expect(l.size()).toEqual(0); + }); +}); + +describe.skip('RemoveFirst', () => { + test('removes the first node when the list has a size of one', () => { + const l = new List(); + l.insertFirst('a'); + l.removeFirst(); + expect(l.size()).toEqual(0); + expect(l.getFirst()).toEqual(null); + }); + + test('removes the first node when the list has a size of three', () => { + const l = new List(); + l.insertFirst('c'); + l.insertFirst('b'); + l.insertFirst('a'); + l.removeFirst(); + expect(l.size()).toEqual(2); + expect(l.getFirst().data).toEqual('b'); + l.removeFirst(); + expect(l.size()).toEqual(1); + expect(l.getFirst().data).toEqual('c'); + }); +}); + +describe.skip('RemoveLast', () => { + test('RemoveLast removes the last node when list is empty', () => { + const l = new List(); + expect(() => { + l.removeLast(); + }).not.toThrow(); + }); + + test('RemoveLast removes the last node when list is length 1', () => { + const l = new List(); + l.insertFirst('a'); + l.removeLast(); + expect(l.head).toEqual(null); + }); + + test('RemoveLast removes the last node when list is length 2', () => { + const l = new List(); + l.insertFirst('b'); + l.insertFirst('a'); + + l.removeLast(); + + expect(l.size()).toEqual(1); + expect(l.head.data).toEqual('a'); + }); + + test('RemoveLast removes the last node when list is length 3', () => { + const l = new List(); + l.insertFirst('c'); + l.insertFirst('b'); + l.insertFirst('a'); + l.removeLast(); + + expect(l.size()).toEqual(2); + expect(l.getLast().data).toEqual('b'); + }); +}); + +describe.skip('InsertLast', () => { + test('adds to the end of the list', () => { + const l = new List(); + l.insertFirst('a'); + + l.insertLast('b'); + + expect(l.size()).toEqual(2); + expect(l.getLast().data).toEqual('b'); + }); +}); + +describe.skip('GetAt', () => { + test('returns the node at given index', () => { + const l = new List(); + expect(l.getAt(10)).toEqual(null); + + l.insertLast(1); + l.insertLast(2); + l.insertLast(3); + l.insertLast(4); + + expect(l.getAt(0).data).toEqual(1); + expect(l.getAt(1).data).toEqual(2); + expect(l.getAt(2).data).toEqual(3); + expect(l.getAt(3).data).toEqual(4); + }); +}); + +describe.skip('RemoveAt', () => { + test('removeAt doesnt crash on an empty list', () => { + const l = new List(); + expect(() => { + l.removeAt(0); + l.removeAt(1); + l.removeAt(2); + }).not.toThrow(); + }); + + test('removeAt doesnt crash on an index out of bounds', () => { + const l = new List(); + expect(() => { + const l = new List(); + l.insertFirst('a'); + l.removeAt(1); + }).not.toThrow(); + }); + + test('removeAt deletes the first node', () => { + const l = new List(); + l.insertLast(1); + l.insertLast(2); + l.insertLast(3); + l.insertLast(4); + expect(l.getAt(0).data).toEqual(1); + l.removeAt(0); + expect(l.getAt(0).data).toEqual(2); + }); + + test('removeAt deletes the node at the given index', () => { + const l = new List(); + l.insertLast(1); + l.insertLast(2); + l.insertLast(3); + l.insertLast(4); + expect(l.getAt(1).data).toEqual(2); + l.removeAt(1); + expect(l.getAt(1).data).toEqual(3); + }); + + test('removeAt works on the last node', () => { + const l = new List(); + l.insertLast(1); + l.insertLast(2); + l.insertLast(3); + l.insertLast(4); + expect(l.getAt(3).data).toEqual(4); + l.removeAt(3); + expect(l.getAt(3)).toEqual(null); + }); +}); + +describe.skip('InsertAt', () => { + test('inserts a new node with data at the 0 index when the list is empty', () => { + const l = new List(); + l.insertAt('hi', 0); + expect(l.getFirst().data).toEqual('hi'); + }); + + test('inserts a new node with data at the 0 index when the list has elements', () => { + const l = new List(); + l.insertLast('a'); + l.insertLast('b'); + l.insertLast('c'); + l.insertAt('hi', 0); + expect(l.getAt(0).data).toEqual('hi'); + expect(l.getAt(1).data).toEqual('a'); + expect(l.getAt(2).data).toEqual('b'); + expect(l.getAt(3).data).toEqual('c'); + }); + + test('inserts a new node with data at a middle index', () => { + const l = new List(); + l.insertLast('a'); + l.insertLast('b'); + l.insertLast('c'); + l.insertLast('d'); + l.insertAt('hi', 2); + expect(l.getAt(0).data).toEqual('a'); + expect(l.getAt(1).data).toEqual('b'); + expect(l.getAt(2).data).toEqual('hi'); + expect(l.getAt(3).data).toEqual('c'); + expect(l.getAt(4).data).toEqual('d'); + }); + + test('inserts a new node with data at a last index', () => { + const l = new List(); + l.insertLast('a'); + l.insertLast('b'); + l.insertAt('hi', 2); + expect(l.getAt(0).data).toEqual('a'); + expect(l.getAt(1).data).toEqual('b'); + expect(l.getAt(2).data).toEqual('hi'); + }); + + test('insert a new node when index is out of bounds', () => { + const l = new List(); + l.insertLast('a'); + l.insertLast('b'); + l.insertAt('hi', 30); + + expect(l.getAt(0).data).toEqual('a'); + expect(l.getAt(1).data).toEqual('b'); + expect(l.getAt(2).data).toEqual('hi'); + }); +}); + +describe.skip('ForEach', () => { + test('applies a transform to each node', () => { + const l = new List(); + + l.insertLast(1); + l.insertLast(2); + l.insertLast(3); + l.insertLast(4); + + l.forEach(node => { + node.data += 10; + }); + + expect(l.getAt(0).data).toEqual(11); + expect(l.getAt(1).data).toEqual(12); + expect(l.getAt(2).data).toEqual(13); + expect(l.getAt(3).data).toEqual(14); + }); +}); + +describe.skip('for...of loops', () => { + test('works with the linked list', () => { + const l = new List(); + + l.insertLast(1); + l.insertLast(2); + l.insertLast(3); + l.insertLast(4); + + for (let node of l) { + node.data += 10; + } + + expect(l.getAt(0).data).toEqual(11); + expect(l.getAt(1).data).toEqual(12); + expect(l.getAt(2).data).toEqual(13); + expect(l.getAt(3).data).toEqual(14); + }); + + test('for...of works on an empty list', () => { + const l = new List(); + expect(() => { + for (let node of l) { + } + }).not.toThrow(); + }); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/matrix/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/matrix/index.js new file mode 100644 index 0000000..13bdc31 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/matrix/index.js @@ -0,0 +1,20 @@ +// --- Directions +// Write a function that accepts an integer N +// and returns a NxN spiral matrix. +// --- Examples +// matrix(2) +// [[1, 2], +// [4, 3]] +// matrix(3) +// [[1, 2, 3], +// [8, 9, 4], +// [7, 6, 5]] +// matrix(4) +// [[1, 2, 3, 4], +// [12, 13, 14, 5], +// [11, 16, 15, 6], +// [10, 9, 8, 7]] + +function matrix(n) {} + +module.exports = matrix; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/matrix/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/matrix/test.js new file mode 100644 index 0000000..4476dda --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/matrix/test.js @@ -0,0 +1,29 @@ +const matrix = require('./index'); + +test('matrix is a function', () => { + expect(typeof matrix).toEqual('function'); +}); + +test('matrix produces a 2x2 array', () => { + const m = matrix(2); + expect(m.length).toEqual(2); + expect(m[0]).toEqual([1, 2]); + expect(m[1]).toEqual([4, 3]); +}); + +test('matrix produces a 3x3 array', () => { + const m = matrix(3); + expect(m.length).toEqual(3); + expect(m[0]).toEqual([1, 2, 3]); + expect(m[1]).toEqual([8, 9, 4]); + expect(m[2]).toEqual([7, 6, 5]); +}); + +test('matrix produces a 4x4 array', () => { + const m = matrix(4); + expect(m.length).toEqual(4); + expect(m[0]).toEqual([1, 2, 3, 4]); + expect(m[1]).toEqual([12, 13, 14, 5]); + expect(m[2]).toEqual([11, 16, 15, 6]); + expect(m[3]).toEqual([10, 9, 8, 7]); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/maxchar/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/maxchar/index.js new file mode 100644 index 0000000..12f32ba --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/maxchar/index.js @@ -0,0 +1,10 @@ +// --- Directions +// Given a string, return the character that is most +// commonly used in the string. +// --- Examples +// maxChar("abcccccccd") === "c" +// maxChar("apple 1231111") === "1" + +function maxChar(str) {} + +module.exports = maxChar; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/maxchar/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/maxchar/test.js new file mode 100644 index 0000000..14918ee --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/maxchar/test.js @@ -0,0 +1,14 @@ +const maxChar = require('./index'); + +test('maxChar function exists', () => { + expect(typeof maxChar).toEqual('function'); +}); + +test('Finds the most frequently used char', () => { + expect(maxChar('a')).toEqual('a'); + expect(maxChar('abcdefghijklmnaaaaa')).toEqual('a'); +}); + +test('Works with numbers in the string', () => { + expect(maxChar('ab1c1d1e1f1g1')).toEqual('1'); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/index.js new file mode 100644 index 0000000..8bf6894 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/index.js @@ -0,0 +1,17 @@ +// --- Directions +// Return the 'middle' node of a linked list. +// If the list has an even number of elements, return +// the node at the end of the first half of the list. +// *Do not* use a counter variable, *do not* retrieve +// the size of the list, and only iterate +// through the list one time. +// --- Example +// const l = new LinkedList(); +// l.insertLast('a') +// l.insertLast('b') +// l.insertLast('c') +// midpoint(l); // returns { data: 'b' } + +function midpoint(list) {} + +module.exports = midpoint; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/linkedlist.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/linkedlist.js new file mode 100644 index 0000000..b7da56b --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/linkedlist.js @@ -0,0 +1,178 @@ +class Node { + constructor(data, next = null) { + this.data = data; + this.next = next; + } +} + +class LinkedList { + constructor(values = []) { + this.head = null; + + for (let value of values) { + this.insertLast(value); + } + } + + clear() { + this.head = null; + } + + size() { + let counter = 0; + let node = this.head; + + while (node) { + counter++; + node = node.next; + } + + return counter; + } + + getAt(index) { + if (!this.head) { + return null; + } + + let counter = 0; + let node = this.head; + while (node) { + if (counter === index) { + return node; + } + node = node.next; + counter++; + } + return null; + } + + insertAt(data, index) { + if (!this.head) { + this.head = new Node(data); + return; + } + + if (index === 0) { + this.head = new Node(data, this.head); + return; + } + + let counter = 1; + let previous = this.head; + let node = this.head.next; + while (node) { + if (counter === index) { + previous.next = new Node(data, node); + return; + } + previous = node; + node = node.next; + counter++; + } + + previous.next = new Node(data, node); + } + + removeFirst() { + if (!this.head) { + return; + } + + this.head = this.head.next; + } + + removeLast() { + if (!this.head) { + return; + } + + if (!this.head.next) { + this.head = null; + return; + } + + let previous = this.head; + let node = this.head.next; + while (node.next) { + previous = node; + node = node.next; + } + previous.next = null; + } + + removeAt(index) { + if (!this.head) { + return; + } + + let counter = 0; + let node = this.head; + while (node) { + if (counter === index - 1) { + if (node.next) { + return (node.next = node.next.next); + } else { + return (node.next = null); + } + } + node = node.next; + counter++; + } + } + + getFirst() { + return this.head; + } + + insertFirst(data) { + this.head = new Node(data, this.getFirst()); + } + + getLast() { + if (!this.head) { + return null; + } + + let node = this.head; + while (node.next) { + node = node.next; + } + + return node; + } + + insertLast(data) { + const last = this.getLast(); + + if (last) { + last.next = new Node(data); + return last.next; + } else { + this.head = new Node(data); + return this.head; + } + } + + forEach(fn) { + if (!this.head) { + return null; + } + + let node = this.head; + while (node) { + fn(node); + node = node.next; + } + } + + *[Symbol.iterator]() { + let node = this.head; + while (node) { + yield node; + node = node.next; + } + } +} + +module.exports = { Node, LinkedList }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/test.js new file mode 100644 index 0000000..277597e --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/test.js @@ -0,0 +1,46 @@ +const midpoint = require('./index'); +const L = require('./linkedlist'); +const Node = L.Node; +const LinkedList = L.LinkedList; + +test('Midpoint is a function', () => { + expect(typeof midpoint).toEqual('function'); +}); + +describe('Midpoint returns the middle node of an odd numbered list', () => { + test('when the list has 3 elements', () => { + const l = new LinkedList(); + l.insertLast('a'); + l.insertLast('b'); + l.insertLast('c'); + expect(midpoint(l).data).toEqual('b'); + }); + + test('when the list has 5 elements', () => { + const l = new LinkedList(); + l.insertLast('a'); + l.insertLast('b'); + l.insertLast('c'); + l.insertLast('d'); + l.insertLast('e'); + expect(midpoint(l).data).toEqual('c'); + }); +}); + +describe('Midpoint returns the middle node of an even numbered list', () => { + test('when the list has 2 elements', () => { + const l = new LinkedList(); + l.insertLast('a'); + l.insertLast('b'); + expect(midpoint(l).data).toEqual('a'); + }); + + test('when the list has 4 elements', () => { + const l = new LinkedList(); + l.insertLast('a'); + l.insertLast('b'); + l.insertLast('c'); + l.insertLast('d'); + expect(midpoint(l).data).toEqual('b'); + }); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/package.json b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/package.json new file mode 100644 index 0000000..b978e88 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/package.json @@ -0,0 +1,14 @@ +{ + "name": "dev", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "jest": { + "testEnvironment": "node" + }, + "author": "stephen grider", + "license": "ISC" +} diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/palindrome/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/palindrome/index.js new file mode 100644 index 0000000..58115ed --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/palindrome/index.js @@ -0,0 +1,12 @@ +// --- Directions +// Given a string, return true if the string is a palindrome +// or false if it is not. Palindromes are strings that +// form the same word if it is reversed. *Do* include spaces +// and punctuation in determining if the string is a palindrome. +// --- Examples: +// palindrome("abba") === true +// palindrome("abcdefg") === false + +function palindrome(str) {} + +module.exports = palindrome; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/palindrome/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/palindrome/test.js new file mode 100644 index 0000000..abdbcb1 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/palindrome/test.js @@ -0,0 +1,33 @@ +const palindrome = require('./index'); + +test('palindrome function is defined', () => { + expect(typeof palindrome).toEqual('function'); +}); + +test('"aba" is a palindrome', () => { + expect(palindrome('aba')).toBeTruthy(); +}); + +test('" aba" is not a palindrome', () => { + expect(palindrome(' aba')).toBeFalsy(); +}); + +test('"aba " is not a palindrome', () => { + expect(palindrome('aba ')).toBeFalsy(); +}); + +test('"greetings" is not a palindrome', () => { + expect(palindrome('greetings')).toBeFalsy(); +}); + +test('"1000000001" a palindrome', () => { + expect(palindrome('1000000001')).toBeTruthy(); +}); + +test('"Fish hsif" is not a palindrome', () => { + expect(palindrome('Fish hsif')).toBeFalsy(); +}); + +test('"pennep" a palindrome', () => { + expect(palindrome('pennep')).toBeTruthy(); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js new file mode 100644 index 0000000..627bab3 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js @@ -0,0 +1,19 @@ +// --- Directions +// Write a function that accepts a positive number N. +// The function should console log a pyramid shape +// with N levels using the # character. Make sure the +// pyramid has spaces on both the left *and* right hand sides +// --- Examples +// pyramid(1) +// '#' +// pyramid(2) +// ' # ' +// '###' +// pyramid(3) +// ' # ' +// ' ### ' +// '#####' + +function pyramid(n) {} + +module.exports = pyramid; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/test.js new file mode 100644 index 0000000..8ffc318 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/test.js @@ -0,0 +1,37 @@ +const pyramid = require('./index'); + +beforeEach(() => { + jest.spyOn(console, 'log'); +}); + +afterEach(() => { + console.log.mockRestore(); +}); + +test('pyramid is a function', () => { + expect(typeof pyramid).toEqual('function'); +}); + +test('prints a pryamid for n = 2', () => { + pyramid(2); + expect(console.log.mock.calls[0][0]).toEqual(' # '); + expect(console.log.mock.calls[1][0]).toEqual('###'); + expect(console.log.mock.calls.length).toEqual(2); +}); + +test('prints a pryamid for n = 3', () => { + pyramid(3); + expect(console.log.mock.calls[0][0]).toEqual(' # '); + expect(console.log.mock.calls[1][0]).toEqual(' ### '); + expect(console.log.mock.calls[2][0]).toEqual('#####'); + expect(console.log.mock.calls.length).toEqual(3); +}); + +test('prints a pryamid for n = 4', () => { + pyramid(4); + expect(console.log.mock.calls[0][0]).toEqual(' # '); + expect(console.log.mock.calls[1][0]).toEqual(' ### '); + expect(console.log.mock.calls[2][0]).toEqual(' ##### '); + expect(console.log.mock.calls[3][0]).toEqual('#######'); + expect(console.log.mock.calls.length).toEqual(4); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/index.js new file mode 100644 index 0000000..93af154 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/index.js @@ -0,0 +1,19 @@ +// --- Directions +// Implement a Queue datastructure using two stacks. +// *Do not* create an array inside of the 'Queue' class. +// Queue should implement the methods 'add', 'remove', and 'peek'. +// For a reminder on what each method does, look back +// at the Queue exercise. +// --- Examples +// const q = new Queue(); +// q.add(1); +// q.add(2); +// q.peek(); // returns 1 +// q.remove(); // returns 1 +// q.remove(); // returns 2 + +const Stack = require('./stack'); + +class Queue {} + +module.exports = Queue; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/stack.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/stack.js new file mode 100644 index 0000000..2032acb --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/stack.js @@ -0,0 +1,19 @@ +class Stack { + constructor() { + this.data = []; + } + + push(record) { + this.data.push(record); + } + + pop() { + return this.data.pop(); + } + + peek() { + return this.data[this.data.length - 1]; + } +} + +module.exports = Stack; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/test.js new file mode 100644 index 0000000..3fc84c7 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/test.js @@ -0,0 +1,41 @@ +const Queue = require('./index'); + +test('Queue is a class', () => { + expect(typeof Queue.prototype.constructor).toEqual('function'); +}); + +test('can add elements to a queue', () => { + const q = new Queue(); + expect(() => { + q.add(1); + }).not.toThrow(); +}); + +test('can remove elements from a queue', () => { + const q = new Queue(); + expect(() => { + q.add(1); + q.remove(); + }).not.toThrow(); +}); + +test('Order of elements is maintained', () => { + const q = new Queue(); + q.add(1); + q.add(2); + q.add(3); + expect(q.remove()).toEqual(1); + expect(q.remove()).toEqual(2); + expect(q.remove()).toEqual(3); + expect(q.remove()).toEqual(undefined); +}); + +test('peek returns, but does not remove, the first value', () => { + const q = new Queue(); + q.add(1); + q.add(2); + expect(q.peek()).toEqual(1); + expect(q.peek()).toEqual(1); + expect(q.remove()).toEqual(1); + expect(q.remove()).toEqual(2); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/queue/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/queue/index.js new file mode 100644 index 0000000..e11ff2a --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/queue/index.js @@ -0,0 +1,13 @@ +// --- Description +// Create a queue data structure. The queue +// should be a class with methods 'add' and 'remove'. +// Adding to the queue should store an element until +// it is removed +// --- Examples +// const q = new Queue(); +// q.add(1); +// q.remove(); // returns 1; + +class Queue {} + +module.exports = Queue; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/queue/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/queue/test.js new file mode 100644 index 0000000..867bd42 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/queue/test.js @@ -0,0 +1,31 @@ +const Queue = require('./index'); + +test('Queue is a class', () => { + expect(typeof Queue.prototype.constructor).toEqual('function'); +}); + +test('can add elements to a queue', () => { + const q = new Queue(); + expect(() => { + q.add(1); + }).not.toThrow(); +}); + +test('can remove elements from a queue', () => { + const q = new Queue(); + expect(() => { + q.add(1); + q.remove(); + }).not.toThrow(); +}); + +test('Order of elements is maintained', () => { + const q = new Queue(); + q.add(1); + q.add(2); + q.add(3); + expect(q.remove()).toEqual(1); + expect(q.remove()).toEqual(2); + expect(q.remove()).toEqual(3); + expect(q.remove()).toEqual(undefined); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/index.js new file mode 100644 index 0000000..5db3bfd --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/index.js @@ -0,0 +1,13 @@ +// --- Directions +// Given an integer, return an integer that is the reverse +// ordering of numbers. +// --- Examples +// reverseInt(15) === 51 +// reverseInt(981) === 189 +// reverseInt(500) === 5 +// reverseInt(-15) === -51 +// reverseInt(-90) === -9 + +function reverseInt(n) {} + +module.exports = reverseInt; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/test.js new file mode 100644 index 0000000..e5092e2 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/test.js @@ -0,0 +1,23 @@ +const reverseInt = require('./index'); + +test('ReverseInt function exists', () => { + expect(reverseInt).toBeDefined(); +}); + +test('ReverseInt handles 0 as an input', () => { + expect(reverseInt(0)).toEqual(0); +}); + +test('ReverseInt flips a positive number', () => { + expect(reverseInt(5)).toEqual(5); + expect(reverseInt(15)).toEqual(51); + expect(reverseInt(90)).toEqual(9); + expect(reverseInt(2359)).toEqual(9532); +}); + +test('ReverseInt flips a negative number', () => { + expect(reverseInt(-5)).toEqual(-5); + expect(reverseInt(-15)).toEqual(-51); + expect(reverseInt(-90)).toEqual(-9); + expect(reverseInt(-2359)).toEqual(-9532); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/index.js new file mode 100644 index 0000000..fc90903 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/index.js @@ -0,0 +1,11 @@ +// --- Directions +// Given a string, return a new string with the reversed +// order of characters +// --- Examples +// reverse('apple') === 'leppa' +// reverse('hello') === 'olleh' +// reverse('Greetings!') === '!sgniteerG' + +function reverse(str) {} + +module.exports = reverse; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/test.js new file mode 100644 index 0000000..8d264c0 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/test.js @@ -0,0 +1,13 @@ +const reverse = require('./index'); + +test('Reverse function exists', () => { + expect(reverse).toBeDefined(); +}); + +test('Reverse reverses a string', () => { + expect(reverse('abcd')).toEqual('dcba'); +}); + +test('Reverse reverses a string', () => { + expect(reverse(' abcd')).toEqual('dcba '); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js new file mode 100644 index 0000000..acbaf3f --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js @@ -0,0 +1,20 @@ +// --- Directions +// Implement bubbleSort, selectionSort, and mergeSort + +function bubbleSort(arr) { + +} + +function selectionSort(arr) { + +} + +function mergeSort(arr) { + +} + +function merge(left, right) { + +} + +module.exports = { bubbleSort, selectionSort, mergeSort, merge }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/test.js new file mode 100644 index 0000000..0ff475b --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/test.js @@ -0,0 +1,38 @@ +const S = require('./index'); +const bubbleSort = S.bubbleSort; +const selectionSort = S.selectionSort; +const mergeSort = S.mergeSort; +const merge = S.merge; + +function getArray() { + return [100, -40, 500, -124, 0, 21, 7]; +} + +function getSortedArray() { + return [-124, -40, 0, 7, 21, 100, 500]; +} + +describe('Bubble sort', () => { + test('sorts an array', () => { + expect(bubbleSort(getArray())).toEqual(getSortedArray()); + }); +}); + +describe('Selection sort', () => { + test('sorts an array', () => { + expect(selectionSort(getArray())).toEqual(getSortedArray()); + }); +}); + +describe('Merge sort', () => { + test('merge function can join together two sorted arrays', () => { + const left = [1, 10]; + const right = [2, 8, 12]; + + expect(merge(left, right)).toEqual([1,2,8,10,12]); + }); + + test('sorts an array', () => { + expect(mergeSort(getArray())).toEqual(getSortedArray()); + }); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/stack/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/stack/index.js new file mode 100644 index 0000000..5c7c460 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/stack/index.js @@ -0,0 +1,15 @@ +// --- Directions +// Create a stack data structure. The stack +// should be a class with methods 'push', 'pop', and +// 'peek'. Adding an element to the stack should +// store it until it is removed. +// --- Examples +// const s = new Stack(); +// s.push(1); +// s.push(2); +// s.pop(); // returns 2 +// s.pop(); // returns 1 + +class Stack {} + +module.exports = Stack; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/stack/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/stack/test.js new file mode 100644 index 0000000..457e5a2 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/stack/test.js @@ -0,0 +1,36 @@ +const Stack = require('./index'); + +test('Stack is a class', () => { + expect(typeof Stack.prototype.constructor).toEqual('function'); +}); + +test('stack can add and remove items', () => { + const s = new Stack(); + s.push(1); + expect(s.pop()).toEqual(1); + s.push(2); + expect(s.pop()).toEqual(2); +}); + +test('stack can follows first in, last out', () => { + const s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + expect(s.pop()).toEqual(3); + expect(s.pop()).toEqual(2); + expect(s.pop()).toEqual(1); +}); + +test('peek returns the first element but doesnt pop it', () => { + const s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + expect(s.peek()).toEqual(3); + expect(s.pop()).toEqual(3); + expect(s.peek()).toEqual(2); + expect(s.pop()).toEqual(2); + expect(s.peek()).toEqual(1); + expect(s.pop()).toEqual(1); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js new file mode 100644 index 0000000..400adc9 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js @@ -0,0 +1,22 @@ +// --- Directions +// Write a function that accepts a positive number N. +// The function should console log a step shape +// with N levels using the # character. Make sure the +// step has spaces on the right hand side! +// --- Examples +// steps(2) +// '# ' +// '##' +// steps(3) +// '# ' +// '## ' +// '###' +// steps(4) +// '# ' +// '## ' +// '### ' +// '####' + +function steps(n) {} + +module.exports = steps; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/test.js new file mode 100644 index 0000000..007af11 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/test.js @@ -0,0 +1,34 @@ +const steps = require('./index'); + +beforeEach(() => { + jest.spyOn(console, 'log'); +}); + +afterEach(() => { + console.log.mockRestore(); +}); + +test('steps is a function', () => { + expect(typeof steps).toEqual('function'); +}); + +test('steps called with n = 1', () => { + steps(1); + expect(console.log.mock.calls[0][0]).toEqual('#'); + expect(console.log.mock.calls.length).toEqual(1); +}); + +test('steps called with n = 2', () => { + steps(2); + expect(console.log.mock.calls[0][0]).toEqual('# '); + expect(console.log.mock.calls[1][0]).toEqual('##'); + expect(console.log.mock.calls.length).toEqual(2); +}); + +test('steps called with n = 3', () => { + steps(3); + expect(console.log.mock.calls[0][0]).toEqual('# '); + expect(console.log.mock.calls[1][0]).toEqual('## '); + expect(console.log.mock.calls[2][0]).toEqual('###'); + expect(console.log.mock.calls.length).toEqual(3); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/index.js new file mode 100644 index 0000000..0ef59b8 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/index.js @@ -0,0 +1,17 @@ +// --- Directions +// 1) Create a node class. The constructor +// should accept an argument that gets assigned +// to the data property and initialize an +// empty array for storing children. The node +// class should have methods 'add' and 'remove'. +// 2) Create a tree class. The tree constructor +// should initialize a 'root' property to null. +// 3) Implement 'traverseBF' and 'traverseDF' +// on the tree class. Each method should accept a +// function that gets called with each element in the tree + +class Node {} + +class Tree {} + +module.exports = { Tree, Node }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/test.js new file mode 100644 index 0000000..1a103ed --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/test.js @@ -0,0 +1,67 @@ +const T = require('./index'); +const Node = T.Node; +const Tree = T.Tree; + +describe('Node', () => { + test('Node is a constructor', () => { + expect(typeof Node.prototype.constructor).toEqual('function'); + }); + + test('Node has a data and children properties', () => { + const n = new Node('a'); + expect(n.data).toEqual('a'); + expect(n.children.length).toEqual(0); + }); + + test('Node can add children', () => { + const n = new Node('a'); + n.add('b'); + expect(n.children.length).toEqual(1); + expect(n.children[0].children).toEqual([]); + }); + + test('Node can remove children', () => { + const n = new Node('a'); + n.add('b'); + expect(n.children.length).toEqual(1); + n.remove('b'); + expect(n.children.length).toEqual(0); + }); +}); + +describe.skip('Tree', () => { + test('starts empty', () => { + const t = new Tree(); + expect(t.root).toEqual(null); + }); + + test('Can traverse bf', () => { + const letters = []; + const t = new Tree(); + t.root = new Node('a'); + t.root.add('b'); + t.root.add('c'); + t.root.children[0].add('d'); + + t.traverseBF(node => { + letters.push(node.data); + }); + + expect(letters).toEqual(['a', 'b', 'c', 'd']); + }); + + test('Can traverse DF', () => { + const letters = []; + const t = new Tree(); + t.root = new Node('a'); + t.root.add('b'); + t.root.add('d'); + t.root.children[0].add('c'); + + t.traverseDF(node => { + letters.push(node.data); + }); + + expect(letters).toEqual(['a', 'b', 'c', 'd']); + }); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/index.js new file mode 100644 index 0000000..a5f99d6 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/index.js @@ -0,0 +1,10 @@ +// --- Directions +// Given a node, validate the binary search tree, +// ensuring that every node's left hand child is +// less than the parent node's value, and that +// every node's right hand child is greater than +// the parent + +function validate(node, min = null, max = null) {} + +module.exports = validate; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/node.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/node.js new file mode 100644 index 0000000..d19e208 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/node.js @@ -0,0 +1,21 @@ +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + + insert(data) { + if (data < this.data && this.left) { + this.left.insert(data); + } else if (data < this.data) { + this.left = new Node(data); + } else if (data > this.data && this.right) { + this.right.insert(data); + } else if (data > this.data) { + this.right = new Node(data); + } + } +} + +module.exports = Node; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/test.js new file mode 100644 index 0000000..6ea4dc3 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/test.js @@ -0,0 +1,23 @@ +const Node = require('./node'); +const validate = require('./index'); + +test('Validate recognizes a valid BST', () => { + const n = new Node(10); + n.insert(5); + n.insert(15); + n.insert(0); + n.insert(20); + + expect(validate(n)).toEqual(true); +}); + +test('Validate recognizes an invalid BST', () => { + const n = new Node(10); + n.insert(5); + n.insert(15); + n.insert(0); + n.insert(20); + n.left.left.right = new Node(999); + + expect(validate(n)).toEqual(false); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/vowels/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/vowels/index.js new file mode 100644 index 0000000..ad3b67b --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/vowels/index.js @@ -0,0 +1,12 @@ +// --- Directions +// Write a function that returns the number of vowels +// used in a string. Vowels are the characters 'a', 'e' +// 'i', 'o', and 'u'. +// --- Examples +// vowels('Hi There!') --> 3 +// vowels('Why do you ask?') --> 4 +// vowels('Why?') --> 0 + +function vowels(str) {} + +module.exports = vowels; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/vowels/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/vowels/test.js new file mode 100644 index 0000000..6283592 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/vowels/test.js @@ -0,0 +1,21 @@ +const vowels = require('./index'); + +test('Vowels is a function', () => { + expect(typeof vowels).toEqual('function'); +}); + +test('returns the number of vowels used', () => { + expect(vowels('aeiou')).toEqual(5); +}); + +test('returns the number of vowels used when they are capitalized', () => { + expect(vowels('AEIOU')).toEqual(5); +}); + +test('returns the number of vowels used', () => { + expect(vowels('abcdefghijklmnopqrstuvwxyz')).toEqual(5); +}); + +test('returns the number of vowels used', () => { + expect(vowels('bcdfghjkl')).toEqual(0); +}); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/index.js new file mode 100644 index 0000000..3d49df9 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/index.js @@ -0,0 +1,29 @@ +// --- Directions +// 1) Complete the task in weave/queue.js +// 2) Implement the 'weave' function. Weave +// receives two queues as arguments and combines the +// contents of each into a new, third queue. +// The third queue should contain the *alterating* content +// of the two queues. The function should handle +// queues of different lengths without inserting +// 'undefined' into the new one. +// *Do not* access the array inside of any queue, only +// use the 'add', 'remove', and 'peek' functions. +// --- Example +// const queueOne = new Queue(); +// queueOne.add(1); +// queueOne.add(2); +// const queueTwo = new Queue(); +// queueTwo.add('Hi'); +// queueTwo.add('There'); +// const q = weave(queueOne, queueTwo); +// q.remove() // 1 +// q.remove() // 'Hi' +// q.remove() // 2 +// q.remove() // 'There' + +const Queue = require('./queue'); + +function weave(sourceOne, sourceTwo) {} + +module.exports = weave; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/queue.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/queue.js new file mode 100644 index 0000000..451eb90 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/queue.js @@ -0,0 +1,21 @@ +// --- Directions +// Implement a 'peek' method in this Queue class. +// Peek should return the last element (the next +// one to be returned) from the queue *without* +// removing it. + +class Queue { + constructor() { + this.data = []; + } + + add(record) { + this.data.unshift(record); + } + + remove() { + return this.data.pop(); + } +} + +module.exports = Queue; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/test.js new file mode 100644 index 0000000..f173360 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/test.js @@ -0,0 +1,45 @@ +const weave = require('./index'); +const Queue = require('./queue'); + +test('queues have a peek function', () => { + const q = new Queue(); + expect(typeof q.peek).toEqual('function'); +}); + +test('peek returns, but does not remove, the first value', () => { + const q = new Queue(); + q.add(1); + q.add(2); + expect(q.peek()).toEqual(1); + expect(q.peek()).toEqual(1); + expect(q.remove()).toEqual(1); + expect(q.remove()).toEqual(2); +}); + +test('weave is a function', () => { + expect(typeof weave).toEqual('function'); +}); + +test('weave can combine two queues', () => { + const one = new Queue(); + one.add(1); + one.add(2); + one.add(3); + one.add(4); + const two = new Queue(); + two.add('one'); + two.add('two'); + two.add('three'); + two.add('four'); + + const result = weave(one, two); + expect(result.remove()).toEqual(1); + expect(result.remove()).toEqual('one'); + expect(result.remove()).toEqual(2); + expect(result.remove()).toEqual('two'); + expect(result.remove()).toEqual(3); + expect(result.remove()).toEqual('three'); + expect(result.remove()).toEqual(4); + expect(result.remove()).toEqual('four'); + expect(result.remove()).toBeUndefined(); +}); From 06800db43a9ca3b6a8e2ca080b255c4b19cabaf3 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sun, 18 Feb 2024 15:27:02 -0500 Subject: [PATCH 02/46] reverseString: -solution 1: -loop through str in reverse -add each string val to reversed -return reversed -solution 2: -split.reverse.join -solution 3: -reversed to empty string -for let char of str -set rev to char plus rev -solution 4: -return str split reduced passing in rev, char -return char plus rev -close with empty qoutes --- AlgoCasts | 1 - AlgoCasts_3 | 1 - .../.gitignore | 1 + .../exercises/reversestring/index.js | 64 ++++++++++- Traub-Eric-JS-Practice/6_hoisting.js | 101 ++++++++++++++++++ 5 files changed, 165 insertions(+), 3 deletions(-) delete mode 160000 AlgoCasts delete mode 160000 AlgoCasts_3 create mode 100644 Grider-Stephen-AlgoCasts-JS-Practice/.gitignore create mode 100644 Traub-Eric-JS-Practice/6_hoisting.js diff --git a/AlgoCasts b/AlgoCasts deleted file mode 160000 index 7d6ff43..0000000 --- a/AlgoCasts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7d6ff439f752c868a341ad0b8360084a88540549 diff --git a/AlgoCasts_3 b/AlgoCasts_3 deleted file mode 160000 index feeab87..0000000 --- a/AlgoCasts_3 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit feeab87936c294d647721184753b164bbf9f46d6 diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/.gitignore b/Grider-Stephen-AlgoCasts-JS-Practice/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/Grider-Stephen-AlgoCasts-JS-Practice/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/index.js index fc90903..ef5c419 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/index.js @@ -6,6 +6,68 @@ // reverse('hello') === 'olleh' // reverse('Greetings!') === '!sgniteerG' -function reverse(str) {} +// function reverse(str) { +// // recursive soltuion +// if (str.length <= 1) {return str}; +// return reverse(str.slice(1)) +str[0]; +// } + + +// function reverse(str) { +// // reverse loop through string +// res = "" +// for (let i = str.length-1; i >= 0; i--){ +// res += str[i]; +// } +// return res; +// } + +// function reverse(str) { +// // split reverse join solution + +// return str.split("").reverse().join(""); +// } + + +function reverse(str){ + let reversed = ''; + + for (let character of str) { + reversed = character + reversed; + } + return reversed; +} + + +// function reverse(str) { +// return str.split('').reduce((reversed, character) => { +// return character + reversed; +// }, "") +// } + +// function reverse(str) { + + + +// } + + + + + + + + + + + + + + + + + + + module.exports = reverse; diff --git a/Traub-Eric-JS-Practice/6_hoisting.js b/Traub-Eric-JS-Practice/6_hoisting.js new file mode 100644 index 0000000..465f1b0 --- /dev/null +++ b/Traub-Eric-JS-Practice/6_hoisting.js @@ -0,0 +1,101 @@ +/* ex 1 +first console log fails +due to variable hoisting +before variable assignment +*/ + +console.log(color); +var color = "red"; +console.log(color); + + + +//ex 2 +var color; +console.log(color); +color = "orange"; +console.log(color); + + + +// ex 3 +/* +function expression vs +function declaration +*/ + +console.log(getProduct(2, 3)); +var getProduct = function(num1, num2) { + return num1 * num2; +}; +console.log(getProduct(2, 3)); + + + +// ex 4 + +console.log(getProduct(2, 3)); +function getProduct(num1, num2) { + return num1 * num2; +} + + + +// ex 5 +/* +hoisting of varibles only +occur within encompassing function +*/ + +var globalVar = 'global'; +(function() { + var name = 'Jen'; + var getAge = function() { + return '30'; + }; + function getState() { + return 'Delaware'; + } +})(); + + +// ex 6 + +function getTotal() { + console.log(multiplier); + console.log(total); + + let total = 0; + for(var i = 0; i < 10; i++) { + let valueToAdd = i; + var multiplier = 2; + total += valueToAdd * multiplier; + } + return total; + } + getTotal(); + + + + // ex 7 + /* + keywords with let, const are not initialized + until they are declared + */ + + function getTotal() { + let total; + var multiplier; + + total = 0; + + for(var i = 0; i < 10; i++) { + let valueToAdd; + valueToAdd = i; + multiplier = 2; + total += valueToAdd * multiplier; + } + return total; + } + + getTotal(); \ No newline at end of file From 191862cf53a7d03322761d54c7593917068fbe4b Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sun, 18 Feb 2024 21:47:48 -0500 Subject: [PATCH 03/46] palindrome solutions: -solution_1: -set reversed to split.reverse.join -return if str equals reversed -solution_2: -set left, right pointers -while left is less than right -check if string at left equals string at right -increment, decrement pointers -return false -return true -solution_3: -return string split.every passing in char, index -return if char equals string at length minus index, minus one --- .../exercises/palindrome/index.js | 32 ++++++++++++++++++- .../exercises/reversestring/index.js | 27 +++++++--------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/palindrome/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/palindrome/index.js index 58115ed..c8ed075 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/palindrome/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/palindrome/index.js @@ -7,6 +7,36 @@ // palindrome("abba") === true // palindrome("abcdefg") === false -function palindrome(str) {} +// function palindrome(str) { +// reversed = ""; +// for (let char of str){ +// reversed = char + reversed; +// } +// return reversed === str; +// } + +// function palindrome(str) { +// left = 0; +// right = str.length-1; + +// while (left < right) { +// if (str[left] === str[right]){ +// left += 1; +// right -= 1; +// } else { +// return false; +// } +// } +// return true; +// } + +function palindrome(str) { + return str.split('').every((char, i) => { + return char === str[str.length -i -1]; + }) +} + + + module.exports = palindrome; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/index.js index ef5c419..bc4cc56 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reversestring/index.js @@ -29,27 +29,22 @@ // } -function reverse(str){ - let reversed = ''; +// function reverse(str){ +// let reversed = ''; - for (let character of str) { - reversed = character + reversed; - } - return reversed; -} - - -// function reverse(str) { -// return str.split('').reduce((reversed, character) => { -// return character + reversed; -// }, "") +// for (let character of str) { +// reversed = character + reversed; +// } +// return reversed; // } -// function reverse(str) { - +function reverse(str) { + return str.split('').reduce((reversed, character) => { + return character + reversed; + }, "") +} -// } From f1ac1b4490a3516c33366bcaf35b4e941ca755a5 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sun, 18 Feb 2024 21:59:05 -0500 Subject: [PATCH 04/46] reverseInt solution: -convert int toString then reverse.split.join -multiply parsedInt of result by math.sign of n --- .../exercises/reverseint/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/index.js index 5db3bfd..7a9b452 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/index.js @@ -8,6 +8,10 @@ // reverseInt(-15) === -51 // reverseInt(-90) === -9 -function reverseInt(n) {} +function reverseInt(n) { + n.toString().split('').reverse().join(); + + return Math.sign(n) * parseInt(n); +} module.exports = reverseInt; From e7d731a2eefc6d427b490b1b47cb06d285f967c7 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sun, 18 Feb 2024 22:00:54 -0500 Subject: [PATCH 05/46] fixes to reverseInt by setting const --- .../exercises/reverseint/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/index.js index 7a9b452..822e9d3 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/reverseint/index.js @@ -9,9 +9,9 @@ // reverseInt(-90) === -9 function reverseInt(n) { - n.toString().split('').reverse().join(); + const reversed = n.toString().split('').reverse().join(''); - return Math.sign(n) * parseInt(n); + return Math.sign(n) * parseInt(reversed); } module.exports = reverseInt; From aa371fa402e687256ed980b6a4b640036d5787a4 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sun, 18 Feb 2024 23:47:42 -0500 Subject: [PATCH 06/46] maxChar solution: -set max, charMax, charMap -iterate str and populate charMap to plus one or one -iterate charMap -check charMap at char against max -update max -update maxChar -return maxChar --- .../exercises/maxchar/index.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/maxchar/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/maxchar/index.js index 12f32ba..0db5089 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/maxchar/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/maxchar/index.js @@ -5,6 +5,23 @@ // maxChar("abcccccccd") === "c" // maxChar("apple 1231111") === "1" -function maxChar(str) {} +function maxChar(str) { + let max = 0; + let maxChar = ""; + let charMap = {}; + + for (let char of str){ + charMap[char] = charMap[char] + 1 || 1; + } + + for(let char in charMap){ + if(charMap[char] > max){ + max = charMap[char]; + maxChar = char; + } + } + return maxChar; + +} module.exports = maxChar; From 61c7e3fe09fe57a9d1516027a009f2054a499faa Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Mon, 19 Feb 2024 10:43:28 -0500 Subject: [PATCH 07/46] capitalize solutions: solution_1: -set words to empty arr -for word in str split by spaces -push toUpperCase word plus word.slice at one to words -return words joined by space solution_2: -let result equal string zero uppercased -iterate through string -if string at index minus one is empty -add upperCased str at index to result -else add string at index -return result --- .../exercises/capitalize/index.js | 31 ++++++++++++++++++- .../exercises/fizzbuzz/index.js | 13 ++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/index.js index ba9cb59..9a9b3d7 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/index.js @@ -7,6 +7,35 @@ // capitalize('a lazy fox') --> 'A Lazy Fox' // capitalize('look, it is working!') --> 'Look, It Is Working!' -function capitalize(str) {} +// function capitalize(str) { +// const words = []; + +// for (let word of str.split(' ')) { +// words.push(word[0].toUpperCase() + word.slice(1)); +// } + +// return words.join(' '); +// } + + +function capitalize(str){ + + let result = str[0].toUpperCase(); + + for (let i = 1; i < str.length; i++) { + if(str[i - 1] === ' '){ + result += str[i].toUpperCase(); + } else { + result += str[i] + } + } + + return result; + +} + + + + module.exports = capitalize; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fizzbuzz/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fizzbuzz/index.js index 0aeab88..f7e12d9 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fizzbuzz/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fizzbuzz/index.js @@ -12,6 +12,15 @@ // 4 // buzz -function fizzBuzz(n) {} - +function fizzBuzz(n) { + for(let i = 1; i <= n; i++){ + if (i % 15 === 0){ + console.log("fizzbuzz"); + } else if (i % 3 === 0) { + console.log("fizz"); + } else if (i % 5 === 0) { + console.log("buzz"); + } else console.log(i); + } +} module.exports = fizzBuzz; From a9aec0b57c7f5e42dea987f9889395b64e66a372 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Mon, 19 Feb 2024 14:53:01 -0500 Subject: [PATCH 08/46] anagram solutions: -solution_1: -set empty charMap -for char of str replace special char.toLowerCase -populate charMap[char] to plus one or one -return charMap -buildCharMap A and B -check if length of Object keys are equal return false if not -for char in charMap A -check if char equals char in charMapB -else return false -return true -solution_2 -cleanString: -return str.replace special characters -toLowerCase.split.sort.join -return if cleanString A equals cleanString B --- .../exercises/anagrams/index.js | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/index.js index 35cd037..737e197 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/index.js @@ -8,6 +8,33 @@ // anagrams('RAIL! SAFETY!', 'fairy tales') --> True // anagrams('Hi there', 'Bye there') --> False -function anagrams(stringA, stringB) {} +function anagrams(stringA, stringB) { + const aCharMap = buildCharMap(stringA); + const bCharMap = buildCharMap(stringB); + + if(Object.keys(aCharMap).length !== Object.keys(bCharMap).length) { + return false; + } + + for (let char in aCharMap) { + if (aCharMap[char] !== bCharMap[char]){ + return false; + } + } + + return true; +} + + +function buildCharMap(str){ + const charMap = {}; + + for (let char of str.replace(/[^\w]/g, "").toLowerCase()) { + charMap[char] = charMap[char] + 1 || 1; + } + + return charMap; + +} module.exports = anagrams; From d42fd55581664f423a2f601e61045e14cd3bbdb7 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Mon, 19 Feb 2024 15:02:20 -0500 Subject: [PATCH 09/46] capitalize solutions: solution_1: -set words to empty arr -for word of str.split by empty space -push upperCased word at zero index plus word.slice at one to words -return words joined by empty space solution_2: -set result to str at zero toUpperCase -iterate through str -if str at index minus one is empty -add str at index uppercased to result -else add str at index to result -return result --- .../exercises/anagrams/index.js | 46 +++++++++++-------- .../exercises/capitalize/index.js | 2 - 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/index.js index 737e197..f57259d 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/anagrams/index.js @@ -8,33 +8,41 @@ // anagrams('RAIL! SAFETY!', 'fairy tales') --> True // anagrams('Hi there', 'Bye there') --> False -function anagrams(stringA, stringB) { - const aCharMap = buildCharMap(stringA); - const bCharMap = buildCharMap(stringB); +// function anagrams(stringA, stringB) { +// const aCharMap = buildCharMap(stringA); +// const bCharMap = buildCharMap(stringB); - if(Object.keys(aCharMap).length !== Object.keys(bCharMap).length) { - return false; - } +// if(Object.keys(aCharMap).length !== Object.keys(bCharMap).length) { +// return false; +// } - for (let char in aCharMap) { - if (aCharMap[char] !== bCharMap[char]){ - return false; - } - } +// for (let char in aCharMap) { +// if (aCharMap[char] !== bCharMap[char]){ +// return false; +// } +// } - return true; -} +// return true; +// } -function buildCharMap(str){ - const charMap = {}; +// function buildCharMap(str){ +// const charMap = {}; - for (let char of str.replace(/[^\w]/g, "").toLowerCase()) { - charMap[char] = charMap[char] + 1 || 1; - } +// for (let char of str.replace(/[^\w]/g, "").toLowerCase()) { +// charMap[char] = charMap[char] + 1 || 1; +// } +// return charMap; +// } - return charMap; +function anagrams(stringA, stringB){ + return cleanString(stringA) === cleanString(stringB); +} +function cleanString(str){ + return str.replace(/[^\w]/g, "").toLowerCase().split("").sort().join(""); } + + module.exports = anagrams; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/index.js index 9a9b3d7..c3b36b6 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/capitalize/index.js @@ -29,9 +29,7 @@ function capitalize(str){ result += str[i] } } - return result; - } From d769fb8f1164517537f387a2d99efffd85f7b328 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Mon, 19 Feb 2024 15:15:17 -0500 Subject: [PATCH 10/46] vowels solutions: solution_1: -set count to zero -create checker array of vowels -iterate str.lowerCased -if checker includes char -increment count -return count solution_2: -set matches to str.match/[aeiou]/gi -return length of matches or zero --- .../exercises/vowels/index.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/vowels/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/vowels/index.js index ad3b67b..a274eac 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/vowels/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/vowels/index.js @@ -7,6 +7,23 @@ // vowels('Why do you ask?') --> 4 // vowels('Why?') --> 0 -function vowels(str) {} +// function vowels(str) { +// let count = 0; + +// const checker = ['a', 'e', 'i', 'o', 'u'] + +// for (let char of str.toLowerCase()) { +// if(checker.includes(char)){ +// count++; +// } +// } +// return count; +// } + +function vowels(str) { + const matches = str.match(/[aeiou]/gi); + return matches ? matches.length : 0; +} + module.exports = vowels; From 83800452a87ffdfafe1ccfa3270eb3780812911a Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Tue, 20 Feb 2024 20:18:18 -0500 Subject: [PATCH 11/46] object oriented game example --- Traversy_Brad_Modern_JS/objects.js | 159 +++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 Traversy_Brad_Modern_JS/objects.js diff --git a/Traversy_Brad_Modern_JS/objects.js b/Traversy_Brad_Modern_JS/objects.js new file mode 100644 index 0000000..70bf9ed --- /dev/null +++ b/Traversy_Brad_Modern_JS/objects.js @@ -0,0 +1,159 @@ +function Player(name) { + this.name = name; + this.lvl = 1; + this.points = 0; +} + +Player.prototype.gainXp = function (xp) { + this.points += xp; + + if(this.points >= 10) + { this.lvl++; + this.points -= 10; + } +} + +Player.prototype.describe = function(){ + return `${this.name} is level ${this.lvl} with ${this.points} + experience points`; +} + +const player1 = new Player('Bob'); +const player2 = new Player('Alice'); + +player1.gainXp(4); +player2.gainXp(7); +player1.gainXp(5); +player2.gainXp(1); +player1.gainXp(7); +player2.gainXp(9); +player1.gainXp(5); +player2.gainXp(2); + +console.log(player1.describe()); +console.log(player2.describe()); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// function Rectangle(name, width, height) { +// this.name = name; +// this.width = width; +// this.height = height; +// this.area = function() { +// return this.width * this.height; +// }; +// } + +// const rect = new Rectangle('React', 10, 10); +// console.log(rect); + +// Rectangle.prototype.area = function () { +// return (this.width * this.height); +// } + +// const rectanglePrototypes = { +// area: function () { +// return this.width * this.height +// }, +// perimeter: function () { +// return 2 * (this.width + this.height) +// }, +// isSquare: function () { +// return (this.height === this.width) +// } +// } + + +// function createRectangle(height, width) { +// return Object.create(rectanglePrototypes, { +// height: { +// value: height, +// }, +// width: { +// value: width, +// }, +// }); +// } + +// const rect = createRectangle(10, 20); +// console.log(rect); +// console.log(rect.area()); +// console.log(rect.isSquare()); + +// const rect2 = createRectangle(20, 20); +// console.log(rect2.area()); + + + + + + + + + + + + + + + + + + + + + + + +// const strLit = 'hello'; +// const strObj = new String('HELLO'); + +// console.log(strLit, typeof strLit); +// console.log(strObj, typeof strObj); + +// console.log(strLit.toUpperCase()); +// console.log(strLit[0]); + +// const funcLit = function(x) { +// return x * x; +// } + +// console.log(funcLit, typeof funcLit); + +// const funcObj = new Function('x', 'return x * x'); + +// console.log(funcObj(3)); + +// const obj1 = {}; +// const obj2 = new Object(); + +// console.log(obj1, typeof obj1); +// console.log(obj2, typeof obj2); + From 64e8ce6fb32a25457bc91760699376c6b45cfc96 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Tue, 20 Feb 2024 23:08:18 -0500 Subject: [PATCH 12/46] class inheritance w. polymorphism example --- Traversy_Brad_Modern_JS/index.html | 12 ++ .../{objects.js => script.js} | 121 ++++++++++++++---- 2 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 Traversy_Brad_Modern_JS/index.html rename Traversy_Brad_Modern_JS/{objects.js => script.js} (53%) diff --git a/Traversy_Brad_Modern_JS/index.html b/Traversy_Brad_Modern_JS/index.html new file mode 100644 index 0000000..8f0c482 --- /dev/null +++ b/Traversy_Brad_Modern_JS/index.html @@ -0,0 +1,12 @@ + + + + + + Document + + +

Objects

+ + + \ No newline at end of file diff --git a/Traversy_Brad_Modern_JS/objects.js b/Traversy_Brad_Modern_JS/script.js similarity index 53% rename from Traversy_Brad_Modern_JS/objects.js rename to Traversy_Brad_Modern_JS/script.js index 70bf9ed..097d2b3 100644 --- a/Traversy_Brad_Modern_JS/objects.js +++ b/Traversy_Brad_Modern_JS/script.js @@ -1,37 +1,110 @@ -function Player(name) { - this.name = name; - this.lvl = 1; - this.points = 0; +// Parent class +class Shape { + constructor(name) { + this.name = name; + } + + logName() { + console.log('Shape name: ', this.name); + } } -Player.prototype.gainXp = function (xp) { - this.points += xp; +// Sub Class +class Rectangle extends Shape { + constructor(name, width, height) { + super(name); - if(this.points >= 10) - { this.lvl++; - this.points -= 10; + this.height = height; + this.width = width; } } -Player.prototype.describe = function(){ - return `${this.name} is level ${this.lvl} with ${this.points} - experience points`; +class Circle extends Shape { + constructor(name, radius) { + super(name); + + this.readius = radius; + } + + logName() { + console.log('Circle Name: ' + this.name) + } } -const player1 = new Player('Bob'); -const player2 = new Player('Alice'); -player1.gainXp(4); -player2.gainXp(7); -player1.gainXp(5); -player2.gainXp(1); -player1.gainXp(7); -player2.gainXp(9); -player1.gainXp(5); -player2.gainXp(2); -console.log(player1.describe()); -console.log(player2.describe()); + +const rect = new Rectangle('Rect 1', 20, 20); +console.log(rect); +rect.logName(); + +const cir = new Circle('Cir 1', 30); +cir.logName(); + +console.log(rect instanceof Rectangle); +console.log(rect instanceof Shape); + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// function Player(name) { +// this.name = name; +// this.lvl = 1; +// this.points = 0; +// } + +// Player.prototype.gainXp = function (xp) { +// this.points += xp; + +// if(this.points >= 10) +// { this.lvl++; +// this.points -= 10; +// } +// } + +// Player.prototype.describe = function(){ +// return `${this.name} is level ${this.lvl} with ${this.points} +// experience points`; +// } + +// const player1 = new Player('Bob'); +// const player2 = new Player('Alice'); + +// player1.gainXp(4); +// player2.gainXp(7); +// player1.gainXp(5); +// player2.gainXp(1); +// player1.gainXp(7); +// player2.gainXp(9); +// player1.gainXp(5); +// player2.gainXp(2); + +// console.log(player1.describe()); +// console.log(player2.describe()); From 72860ef08d1f124f0e671262cd100c392f18851d Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Tue, 20 Feb 2024 23:11:38 -0500 Subject: [PATCH 13/46] static method example --- Traversy_Brad_Modern_JS/script.js | 121 +++++++++++++++++++++++------- 1 file changed, 92 insertions(+), 29 deletions(-) diff --git a/Traversy_Brad_Modern_JS/script.js b/Traversy_Brad_Modern_JS/script.js index 097d2b3..a2f0f75 100644 --- a/Traversy_Brad_Modern_JS/script.js +++ b/Traversy_Brad_Modern_JS/script.js @@ -1,48 +1,111 @@ -// Parent class -class Shape { - constructor(name) { +class Rectangle { + constructor(name, height, width) { this.name = name; + this.height = height; + this.width = width; } - logName() { - console.log('Shape name: ', this.name); + area() { + return this.height * this.width; } -} -// Sub Class -class Rectangle extends Shape { - constructor(name, width, height) { - super(name); - - this.height = height; - this.width = width; + static getClass() { + return 'Rectangle'; } } -class Circle extends Shape { - constructor(name, radius) { - super(name); - this.readius = radius; - } +const rect = new Rectangle('Rect', 10, 10); +console.log(rect.area()); +console.log(Rectangle.getClass()); + + + + + + + + + + + + + + + + + + + + + + + + - logName() { - console.log('Circle Name: ' + this.name) - } -} -const rect = new Rectangle('Rect 1', 20, 20); -console.log(rect); -rect.logName(); -const cir = new Circle('Cir 1', 30); -cir.logName(); -console.log(rect instanceof Rectangle); -console.log(rect instanceof Shape); + + + + + + + + + + + + +// // Parent class +// class Shape { +// constructor(name) { +// this.name = name; +// } + +// logName() { +// console.log('Shape name: ', this.name); +// } +// } + +// // Sub Class +// class Rectangle extends Shape { +// constructor(name, width, height) { +// super(name); + +// this.height = height; +// this.width = width; +// } +// } + +// class Circle extends Shape { +// constructor(name, radius) { +// super(name); + +// this.readius = radius; +// } + +// logName() { +// console.log('Circle Name: ' + this.name) +// } +// } + + + + +// const rect = new Rectangle('Rect 1', 20, 20); +// console.log(rect); +// rect.logName(); + +// const cir = new Circle('Cir 1', 30); +// cir.logName(); + +// console.log(rect instanceof Rectangle); +// console.log(rect instanceof Shape); From 33cdfeeaf2b868bdd3d55accf0af17a6dd31f239 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Tue, 20 Feb 2024 23:21:28 -0500 Subject: [PATCH 14/46] bind(this) example with click button and eventListener --- Traversy_Brad_Modern_JS/index.html | 1 + Traversy_Brad_Modern_JS/script.js | 76 +++++++++++++++++++++++++----- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/Traversy_Brad_Modern_JS/index.html b/Traversy_Brad_Modern_JS/index.html index 8f0c482..f15b337 100644 --- a/Traversy_Brad_Modern_JS/index.html +++ b/Traversy_Brad_Modern_JS/index.html @@ -8,5 +8,6 @@

Objects

+ \ No newline at end of file diff --git a/Traversy_Brad_Modern_JS/script.js b/Traversy_Brad_Modern_JS/script.js index a2f0f75..2e34ec4 100644 --- a/Traversy_Brad_Modern_JS/script.js +++ b/Traversy_Brad_Modern_JS/script.js @@ -1,23 +1,73 @@ -class Rectangle { - constructor(name, height, width) { - this.name = name; - this.height = height; - this.width = width; - } +class App { + constructor() { + this.serverName = 'localhost'; - area() { - return this.height * this.width; + document.querySelector('button').addEventListener('Click', this.getServerName.bind(this)); } - static getClass() { - return 'Rectangle'; + getServerName() { + console.log(this.serverName); } } + +const app = new App(); +// app.getServerName(); + + + + + + + + + + + + + + + + + + + + + + -const rect = new Rectangle('Rect', 10, 10); -console.log(rect.area()); -console.log(Rectangle.getClass()); + + + + + + + + + + + + +// class Rectangle { +// constructor(name, height, width) { +// this.name = name; +// this.height = height; +// this.width = width; +// } + +// area() { +// return this.height * this.width; +// } + +// static getClass() { +// return 'Rectangle'; +// } +// } + + +// const rect = new Rectangle('Rect', 10, 10); +// console.log(rect.area()); +// console.log(Rectangle.getClass()); From 0709cd4dd3587f9eef5a6c41405639e4f8d82006 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Tue, 20 Feb 2024 23:37:11 -0500 Subject: [PATCH 15/46] getters and setters w. classes --- Traversy_Brad_Modern_JS/script.js | 92 ++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/Traversy_Brad_Modern_JS/script.js b/Traversy_Brad_Modern_JS/script.js index 2e34ec4..cd753a8 100644 --- a/Traversy_Brad_Modern_JS/script.js +++ b/Traversy_Brad_Modern_JS/script.js @@ -1,17 +1,93 @@ -class App { - constructor() { - this.serverName = 'localhost'; +class Person { + constructor (firstName, lastName) { + this._firstName = firstName; + this._lastName = lastName; + } + + get firstName() { + // return this._firstName.charAt(0).toUpperCase() + this._firstName.slice(1); + return this.captializeFirst(this._firstName); + } + + set firstName(value) { + this._firstName = value.charAt(0).toUpperCase() + value.slice(1); + } + + get lastName() { + // return this._firstName.charAt(0).toUpperCase() + this._firstName.slice(1); + return this.captializeFirst(this._lastName); + } - document.querySelector('button').addEventListener('Click', this.getServerName.bind(this)); + set lastName(value) { + this._lastName = value.charAt(0).toUpperCase() + value.slice(1); } - getServerName() { - console.log(this.serverName); + captializeFirst(value) { + return value.charAt(0).toUpperCase() + value.slice(1); + } + + get fullName() { + return `${this.firstName} ${this._lastName}`; } } -const app = new App(); -// app.getServerName(); + +const person1 = new Person('john', 'doe'); +console.log(person1.firstName); +console.log(person1.lastName); + + +person1.firstName = 'joseph'; +person1.lastName = 'smith'; +console.log(person1); +console.log(person1.fullName); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// class App { +// constructor() { +// this.serverName = 'localhost'; + +// document.querySelector('button').addEventListener('Click', this.getServerName.bind(this)); +// } + +// getServerName() { +// console.log(this.serverName); +// } +// } + +// const app = new App(); +// // app.getServerName(); From bb165246f8f7d4add31bc7fc3b956f243cb5abab Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Wed, 21 Feb 2024 22:50:57 -0500 Subject: [PATCH 16/46] geters and setters w. define property --- Traversy_Brad_Modern_JS/script.js | 151 +++++++++++++++++++++++++----- 1 file changed, 125 insertions(+), 26 deletions(-) diff --git a/Traversy_Brad_Modern_JS/script.js b/Traversy_Brad_Modern_JS/script.js index cd753a8..b7b03ea 100644 --- a/Traversy_Brad_Modern_JS/script.js +++ b/Traversy_Brad_Modern_JS/script.js @@ -1,46 +1,145 @@ -class Person { - constructor (firstName, lastName) { - this._firstName = firstName; - this._lastName = lastName; - } +// Constructor function +function Person (firstName, lastName){ + this._firstName = firstName; + this._lastName = lastName; + + Object.defineProperty(this, 'firstName', { + get: function () { + return this.captializeFirst(this._firstName); + }, + set: function (value) { + this._firstName = value; + } + }); + + Object.defineProperty(this, 'lastName', { + get: function () { + return this.captializeFirst(this._lastName); + }, + set: function (value) { + this._lasstName = value; + } + }); + + Object.defineProperty(this, 'fullName', { + get: function () { + return this.firstName + " " + this.lastName; + }, + }); + +} + +Person.prototype.captializeFirst = function(value) { + return value.charAt(0).toUpperCase() + value.slice(1); +}; + +//Object literal +const PersonObj = { + _firstName: 'jane', + _lastName: 'doe', get firstName() { - // return this._firstName.charAt(0).toUpperCase() + this._firstName.slice(1); - return this.captializeFirst(this._firstName); - } + return Person.prototype.captializeFirst(this._firstName) + }, set firstName(value) { - this._firstName = value.charAt(0).toUpperCase() + value.slice(1); - } + this._firstName = value; + }, get lastName() { - // return this._firstName.charAt(0).toUpperCase() + this._firstName.slice(1); - return this.captializeFirst(this._lastName); - } + return Person.prototype.captializeFirst(this._lastName); + }, set lastName(value) { - this._lastName = value.charAt(0).toUpperCase() + value.slice(1); - } - - captializeFirst(value) { - return value.charAt(0).toUpperCase() + value.slice(1); - } - + this._lastName = value; + }, + get fullName() { - return `${this.firstName} ${this._lastName}`; + return this._firstName + " " + this.lastName; } } - const person1 = new Person('john', 'doe'); console.log(person1.firstName); console.log(person1.lastName); +console.log(person1.fullName); +const person2 = new Person('jane', 'dough'); +console.log(person2.firstName); +console.log(person2.lastName); +console.log(person2.fullName); -person1.firstName = 'joseph'; -person1.lastName = 'smith'; -console.log(person1); -console.log(person1.fullName); + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// class Person { +// constructor (firstName, lastName) { +// this._firstName = firstName; +// this._lastName = lastName; +// } + +// get firstName() { +// // return this._firstName.charAt(0).toUpperCase() + this._firstName.slice(1); +// return this.captializeFirst(this._firstName); +// } + +// set firstName(value) { +// this._firstName = value.charAt(0).toUpperCase() + value.slice(1); +// } + +// get lastName() { +// // return this._firstName.charAt(0).toUpperCase() + this._firstName.slice(1); +// return this.captializeFirst(this._lastName); +// } + +// set lastName(value) { +// this._lastName = value.charAt(0).toUpperCase() + value.slice(1); +// } + +// captializeFirst(value) { +// return value.charAt(0).toUpperCase() + value.slice(1); +// } + +// get fullName() { +// return `${this.firstName} ${this._lastName}`; +// } +// } + + +// const person1 = new Person('john', 'doe'); +// console.log(person1.firstName); +// console.log(person1.lastName); + + +// person1.firstName = 'joseph'; +// person1.lastName = 'smith'; +// console.log(person1); +// console.log(person1.fullName); From a98bab0d018cad0ac404f8534737aaeb52547f88 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Wed, 21 Feb 2024 23:08:54 -0500 Subject: [PATCH 17/46] private property convention w. getters and setters --- Traversy_Brad_Modern_JS/script.js | 205 +++++++++++++++++++++--------- 1 file changed, 148 insertions(+), 57 deletions(-) diff --git a/Traversy_Brad_Modern_JS/script.js b/Traversy_Brad_Modern_JS/script.js index b7b03ea..a3fce5f 100644 --- a/Traversy_Brad_Modern_JS/script.js +++ b/Traversy_Brad_Modern_JS/script.js @@ -1,73 +1,164 @@ -// Constructor function -function Person (firstName, lastName){ - this._firstName = firstName; - this._lastName = lastName; - - Object.defineProperty(this, 'firstName', { - get: function () { - return this.captializeFirst(this._firstName); - }, - set: function (value) { - this._firstName = value; - } - }); - - Object.defineProperty(this, 'lastName', { - get: function () { - return this.captializeFirst(this._lastName); - }, - set: function (value) { - this._lasstName = value; +class Wallet { + constructor() { + this._balance = 0; + this._transactions = []; + } + + deposit(amount) { + this._processDeposit(amount); + this._balance += amount; + } + + withdraw(amount) { + if(amount >= this._balance){ + console.log('Not enough funds'); + return; } - }); + this._processWithdraw(amount); + this._balance -= amount; + } - Object.defineProperty(this, 'fullName', { - get: function () { - return this.firstName + " " + this.lastName; - }, - }); + _processDeposit(amount) { + console.log(`Depositng ${amount}`); + + this._transactions.push({ + type: 'deposit', + amount + }) + } + + _processWithdraw(amount) { + console.log(`Withdrawing ${amount}`); + + this._transactions.push({ + type: 'withdraw', + amount + }) + } + get balance() { + return this._balance; + } + + get transactions() { + return this._transactions; + } } -Person.prototype.captializeFirst = function(value) { - return value.charAt(0).toUpperCase() + value.slice(1); -}; +const wallet = new Wallet(); +wallet.deposit(300); +wallet.withdraw(50); +// console.log(wallet._balance); +console.log(wallet.balance); +console.log(wallet.transactions); + + + + + + + + + + + + + + + + + + + + + + + + + + + -//Object literal -const PersonObj = { - _firstName: 'jane', - _lastName: 'doe', - get firstName() { - return Person.prototype.captializeFirst(this._firstName) - }, - set firstName(value) { - this._firstName = value; - }, - get lastName() { - return Person.prototype.captializeFirst(this._lastName); - }, - set lastName(value) { - this._lastName = value; - }, + + + + + + +// // Constructor function +// function Person (firstName, lastName){ +// this._firstName = firstName; +// this._lastName = lastName; + +// Object.defineProperty(this, 'firstName', { +// get: function () { +// return this.captializeFirst(this._firstName); +// }, +// set: function (value) { +// this._firstName = value; +// } +// }); + +// Object.defineProperty(this, 'lastName', { +// get: function () { +// return this.captializeFirst(this._lastName); +// }, +// set: function (value) { +// this._lasstName = value; +// } +// }); + +// Object.defineProperty(this, 'fullName', { +// get: function () { +// return this.firstName + " " + this.lastName; +// }, +// }); + +// } + +// Person.prototype.captializeFirst = function(value) { +// return value.charAt(0).toUpperCase() + value.slice(1); +// }; + +// //Object literal +// const PersonObj = { +// _firstName: 'jane', +// _lastName: 'doe', + +// get firstName() { +// return Person.prototype.captializeFirst(this._firstName) +// }, + +// set firstName(value) { +// this._firstName = value; +// }, + +// get lastName() { +// return Person.prototype.captializeFirst(this._lastName); +// }, + +// set lastName(value) { +// this._lastName = value; +// }, - get fullName() { - return this._firstName + " " + this.lastName; - } -} +// get fullName() { +// return this._firstName + " " + this.lastName; +// } +// } -const person1 = new Person('john', 'doe'); -console.log(person1.firstName); -console.log(person1.lastName); -console.log(person1.fullName); +// const person1 = new Person('john', 'doe'); +// console.log(person1.firstName); +// console.log(person1.lastName); +// console.log(person1.fullName); -const person2 = new Person('jane', 'dough'); -console.log(person2.firstName); -console.log(person2.lastName); -console.log(person2.fullName); +// const person2 = new Person('jane', 'dough'); +// console.log(person2.firstName); +// console.log(person2.lastName); +// console.log(person2.fullName); From 55078c11d44191d41648ff76bb8b9e349db71e0b Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Thu, 22 Feb 2024 08:09:08 -0500 Subject: [PATCH 18/46] private class fields example --- Traversy_Brad_Modern_JS/script.js | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Traversy_Brad_Modern_JS/script.js b/Traversy_Brad_Modern_JS/script.js index a3fce5f..5b0e602 100644 --- a/Traversy_Brad_Modern_JS/script.js +++ b/Traversy_Brad_Modern_JS/script.js @@ -1,24 +1,28 @@ class Wallet { + #balance = 0; + #transactions = []; + + constructor() { this._balance = 0; this._transactions = []; } deposit(amount) { - this._processDeposit(amount); - this._balance += amount; + this.#processDeposit(amount); + this.#balance += amount; } withdraw(amount) { - if(amount >= this._balance){ + if(amount >= this.#balance){ console.log('Not enough funds'); return; } - this._processWithdraw(amount); - this._balance -= amount; + this.#processWithdraw(amount); + this.#balance -= amount; } - _processDeposit(amount) { + #processDeposit(amount) { console.log(`Depositng ${amount}`); this._transactions.push({ @@ -27,7 +31,7 @@ class Wallet { }) } - _processWithdraw(amount) { + #processWithdraw(amount) { console.log(`Withdrawing ${amount}`); this._transactions.push({ @@ -37,11 +41,11 @@ class Wallet { } get balance() { - return this._balance; + return this.#balance; } get transactions() { - return this._transactions; + return this.#transactions; } } @@ -49,7 +53,10 @@ const wallet = new Wallet(); wallet.deposit(300); wallet.withdraw(50); // console.log(wallet._balance); -console.log(wallet.balance); +// console.log(wallet.balance); +// console.log(wallet.transactions); + +// console.log(wallet.#balance); console.log(wallet.transactions); From 9755cedcd8cc4f5c45e2ecf466617462fcd63352 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Fri, 23 Feb 2024 19:00:57 -0500 Subject: [PATCH 19/46] chunked solution: solution_1 -set chunked to empty array -iterate through array elms -set last to last elm in chunked -if last does not exit or length of last equals size -push [elm] to chunked as array -else push elm to last -return chunked solution_2 -set chunked to empty array -set index to zero -while index is less than array length -push array slice of index to plus size to chunked -increment index by size -return chunked --- .../exercises/chunk/index.js | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/index.js index 8e7a800..e82b3fe 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/index.js @@ -8,6 +8,32 @@ // chunk([1, 2, 3, 4, 5], 4) --> [[ 1, 2, 3, 4], [5]] // chunk([1, 2, 3, 4, 5], 10) --> [[ 1, 2, 3, 4, 5]] -function chunk(array, size) {} +function chunk(array, size) { + const chunked = []; + + for(let element of array) { + const last = chunked[chunked.length - 1]; + + if(!last || last.length === size) { + chunked.push([element]); + } else { + last.push(element); + } + } + + return chunked; +} + + +// function chunk(array, size) { +// const chunked = []; +// let index = 0; + +// while (index < array.length) { +// chunked.push(array.slice(index, index + size)); +// index += size; +// } +// return chunked; +// } module.exports = chunk; From e7acfc127fae35acb6da2daf6c281505188d5459 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sat, 24 Feb 2024 09:57:55 -0500 Subject: [PATCH 20/46] steps solutions: solution_1: iterate through row -set stair to empty string -iterate through column -if column is less than or equal to row -add step to stair -else -add space to stair -log stair --- .../exercises/steps/index.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js index 400adc9..ec8cb93 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js @@ -17,6 +17,19 @@ // '### ' // '####' -function steps(n) {} +function steps(n) { + for(let row = 0; row < n; row++) { + let stair = ""; + + for(let column = 0; column < n; column++){ + if(column <= row) { + stair += '#'; + } else { + stair += ' '; + } + } + console.log(stair); + } +} module.exports = steps; From e6c96cc128d0dc9d39c20e2f9beabda0b247780f Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sat, 24 Feb 2024 10:13:30 -0500 Subject: [PATCH 21/46] steps solutions: solution_2: -if n equals row, return -if n equals stair.length -console.log stair -return steps passing in n and row plus one -if stair.length is less than or equal to row -add pound to stair -else add space to stair -call steps with n, row, and stair --- .../exercises/steps/index.js | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js index ec8cb93..00eb81b 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js @@ -17,19 +17,41 @@ // '### ' // '####' -function steps(n) { - for(let row = 0; row < n; row++) { - let stair = ""; - - for(let column = 0; column < n; column++){ - if(column <= row) { - stair += '#'; - } else { - stair += ' '; - } - } +// function steps(n) { +// for(let row = 0; row < n; row++) { +// let stair = ""; + +// for(let column = 0; column < n; column++){ +// if(column <= row) { +// stair += '#'; +// } else { +// stair += ' '; +// } +// } +// console.log(stair); +// } +// } + +function steps(n, row=0, stair = '') { + if (n === row) { + return; + } + + if(n === stair.length) { console.log(stair); + return steps(n, row + 1); + } + + if(stair.length <= row) { + stair += '#'; + } else { + stair += ' '; } + + steps(n, row, stair); } + + + module.exports = steps; From f5719b90f75a66b1876aeb4578c9e9176207f10c Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sat, 24 Feb 2024 10:16:27 -0500 Subject: [PATCH 22/46] stairs: -convert conditional to ternary --- .../exercises/steps/index.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js index 00eb81b..7e9e9ed 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/steps/index.js @@ -42,13 +42,8 @@ function steps(n, row=0, stair = '') { return steps(n, row + 1); } - if(stair.length <= row) { - stair += '#'; - } else { - stair += ' '; - } - - steps(n, row, stair); + const add = stair.length <= row ? '#' : ' '; + steps(n, row, stair + add); } From 13689a8e7b9d441eb4284dcaae157797e307b5a3 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sat, 24 Feb 2024 10:57:55 -0500 Subject: [PATCH 23/46] pyramid solution_1: create midpoint as floor of two time n minus one divided by two -iterate through rows -set level to empty string -iterate through columns to midpoint -if midpoint minus row is less than or equal to column and midpoint plus row is greater than or equal to column -add pound to level -else add empty space to level -console.log level --- .../exercises/pyramid/index.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js index 627bab3..316dd9a 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js @@ -14,6 +14,21 @@ // ' ### ' // '#####' -function pyramid(n) {} +function pyramid(n) { + const midpoint = Math.floor((2 * n - 1) / 2); + + for (let row = 0; row < n; row++) { + let level = ''; + + for (let column = 0; column < 2 * n - 1; column++) { + if(midpoint - row <= column && midpoint + row >= column) { + level += '#'; + } else { + level += ' '; + } + } + console.log(level); + } +} module.exports = pyramid; From fb15dfec9e8c7ce4dbacc011b9f642f436bbc91b Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sat, 24 Feb 2024 11:40:31 -0500 Subject: [PATCH 24/46] pyramid solution_2: -if row equals n, return -if level.length equals 2 times n minus one log level return pyramid(n, row plus one) -set midpoint -let add -if midpoint minus row less than or equal to level.length and midpoint plus row greater than level.length -add pount -else add empty space -pyramid(n, row, level plus add --- .../exercises/pyramid/index.js | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js index 316dd9a..e5987c8 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js @@ -14,21 +14,45 @@ // ' ### ' // '#####' -function pyramid(n) { - const midpoint = Math.floor((2 * n - 1) / 2); +// function pyramid(n) { +// const midpoint = Math.floor((2 * n - 1) / 2); + +// for (let row = 0; row < n; row++) { +// let level = ''; + +// for (let column = 0; column < 2 * n - 1; column++) { +// if(midpoint - row <= column && midpoint + row >= column) { +// level += '#'; +// } else { +// level += ' '; +// } +// } +// console.log(level); +// } +// } + +function pyramid(n, row =0, level = '') { + if(row === n) { + return; + } - for (let row = 0; row < n; row++) { - let level = ''; - for (let column = 0; column < 2 * n - 1; column++) { - if(midpoint - row <= column && midpoint + row >= column) { - level += '#'; - } else { - level += ' '; - } + if(level.length === 2 * n -1) { + console.log(level); + return pyramid(n, row + 1); } - console.log(level); + + const midpoint = Math.floor((2 * n - 1) / 2); + let add; + if(midpoint - row <= level.length && midpoint + row >= level.length) { + add = '#'; + } else { + add = ' '; } + + pyramid(n, row, level + add); } + + module.exports = pyramid; From a07c696d5d4c22f9f818dab15456f96866670bc3 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Mon, 4 Mar 2024 15:32:45 -0500 Subject: [PATCH 25/46] matrix solution: -set results[], counter, start col|row to zero set end col|row to n-1 -iterate i to less than n push to results as [] -while start_col <= end_col and start_row <= end_row //top row -iterate i at start_col <= end_col -set start_row at i to counter increment counter -increment start_row //Right_col -iterate i at start_row <= end_row -set results at i at end_col to counter increment counter -decrement end_col //Bottom Row iterate i at end_col >= start_col decrement i -set results at end_row at i to counter -increment counter -decrement end_row //start col -iterate i at end_row >= start_row decrement i -set results at i at start_col to counter increment counter =increment start_col -return results --- .../exercises/matrix/index.js | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/matrix/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/matrix/index.js index 13bdc31..257b5f5 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/matrix/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/matrix/index.js @@ -15,6 +15,50 @@ // [11, 16, 15, 6], // [10, 9, 8, 7]] -function matrix(n) {} +function matrix(n) { + const results = []; + let counter = 1; + + for (let i = 0; i < n; i++) { + results.push([]); + } + + let start_col = 0; + let start_row = 0; + let end_col = n - 1; + let end_row = n - 1; + + while(start_col <= end_col && start_row <= end_row) { + + // Top Row + for(let i = start_col; i <= end_col; i++){ + results[start_row][i] = counter; + counter++; + } + start_row++; + + // Right Column + for(let i = start_row; i <= end_row; i++){ + results[i][end_col] = counter; + counter++; + } + end_col--; + + // Bottom Row + for(let i = end_col; i >= start_col; i--){ + results[end_row][i] = counter; + counter++; + } + end_row--; + + // Start Column + for(let i = end_row; i >= start_row; i--) { + results[i][start_col] = counter; + counter++; + } + start_col++; + } + return results; +} module.exports = matrix; From 62b2c90d139f6aff63b3aee862d50f9ab641e472 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Tue, 5 Mar 2024 15:15:32 -0500 Subject: [PATCH 26/46] fib solution: recursive solution: -if n less than two, return n -return fib (n minus 2) plus fib (n minus one) linear solution: -set result set to zero, one -iterate from two to n -set a to result of i minus 1 -set b to result of i minus 2 -push a plus b to result -return result at n memoize: -create cache as empty object -return function passing in ...args -if cache at args exists, return it -set result to fn.apply(this, args) -set cache at args to result -return result --- .../exercises/fib/index.js | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fib/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fib/index.js index 9efe84f..16b1451 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fib/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fib/index.js @@ -8,6 +8,49 @@ // Example: // fib(4) === 3 -function fib(n) {} +// recursive solution: exponential runtime +function slowFib(n) { + if(n < 2) return n; + return fib(n -1) + fib(n-2); +} + +// memoize: constant time +function memoize(fn) { + const cache = {}; + + return function(...args) { + if(cache[args]){ + return cache[args]; + } + + const result = fn.apply(this, args); + cache[args] = result; + + return result; + } +} + +// // iterative solution: linear runtime +// function fib(n) { +// const result = [0, 1]; + +// for(let i = 2; i <= n; i++) { +// const a = result[i - 1]; +// const b = result[i - 2]; + +// result.push(a + b); +// } +// return result[n]; +// } + + + +const fib = memoize(slowFib); + + + + + + module.exports = fib; From fc78af9ace4f1fe372e837504c9650cb67539805 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Tue, 5 Mar 2024 15:55:53 -0500 Subject: [PATCH 27/46] queue | weave: queue: -use constructor to create this.data as array -add: pass in record unshift record from this.data -remove -return this.data.pop -peek return last elm in this.data weave: create q as new Queue while peek exists in sourceOne or Two if peek in sourceOne add sourceOne.remove to q if peek in sourceTwo add sourceTwo.remove to q return q --- .../exercises/chunk/index.js | 42 +++++++++---------- .../exercises/pyramid/index.js | 2 - .../exercises/queue/index.js | 19 ++++++++- .../exercises/weave/index.js | 18 +++++++- .../exercises/weave/queue.js | 5 +++ 5 files changed, 61 insertions(+), 25 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/index.js index e82b3fe..e98891b 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/chunk/index.js @@ -8,32 +8,32 @@ // chunk([1, 2, 3, 4, 5], 4) --> [[ 1, 2, 3, 4], [5]] // chunk([1, 2, 3, 4, 5], 10) --> [[ 1, 2, 3, 4, 5]] -function chunk(array, size) { - const chunked = []; - - for(let element of array) { - const last = chunked[chunked.length - 1]; - - if(!last || last.length === size) { - chunked.push([element]); - } else { - last.push(element); - } - } - - return chunked; -} - - // function chunk(array, size) { // const chunked = []; -// let index = 0; -// while (index < array.length) { -// chunked.push(array.slice(index, index + size)); -// index += size; +// for(let element of array) { +// const last = chunked[chunked.length - 1]; + +// if(!last || last.length === size) { +// chunked.push([element]); +// } else { +// last.push(element); +// } // } + // return chunked; // } + +function chunk(array, size) { + const chunked = []; + let index = 0; + + while (index < array.length) { + chunked.push(array.slice(index, index + size)); + index += size; + } + return chunked; +} + module.exports = chunk; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js index e5987c8..6105bfb 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js @@ -35,8 +35,6 @@ function pyramid(n, row =0, level = '') { if(row === n) { return; } - - if(level.length === 2 * n -1) { console.log(level); return pyramid(n, row + 1); diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/queue/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/queue/index.js index e11ff2a..ca98ee9 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/queue/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/queue/index.js @@ -8,6 +8,23 @@ // q.add(1); // q.remove(); // returns 1; -class Queue {} +class Queue { + + constructor() { + this.data = []; + } + + add(record) { + this.data.unshift(record); + } + + remove() { + return this.data.pop(); + } + + peek() { + return this.data[this.data.length - 1]; + } +} module.exports = Queue; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/index.js index 3d49df9..480c108 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/index.js @@ -24,6 +24,22 @@ const Queue = require('./queue'); -function weave(sourceOne, sourceTwo) {} +function weave(sourceOne, sourceTwo) { + + const q = new Queue(); + + while(sourceOne.peek() || sourceTwo.peek()) { + + if(sourceOne.peek()) { + q.add(sourceOne.remove()); + } + if(sourceTwo.peek()) { + q.add(sourceTwo.remove()); + } + } + + return q; + +} module.exports = weave; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/queue.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/queue.js index 451eb90..fe93359 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/queue.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/weave/queue.js @@ -16,6 +16,11 @@ class Queue { remove() { return this.data.pop(); } + + peek() { + return this.data[this.data.length - 1]; + } + } module.exports = Queue; From d78d4b298a2f98a7521573ffad678eb782f423ec Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Tue, 5 Mar 2024 16:36:07 -0500 Subject: [PATCH 28/46] stack: constructor create this.data as array push(record) to data pop: return this.data.pop peek: return last elm in this.data --- .../exercises/stack/index.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/stack/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/stack/index.js index 5c7c460..efc8fa5 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/stack/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/stack/index.js @@ -10,6 +10,23 @@ // s.pop(); // returns 2 // s.pop(); // returns 1 -class Stack {} +class Stack { + + constructor() { + this.data = []; + } + + push(record) { + this.data.push(record); + } + + pop() { + return this.data.pop(); + } + + peek() { + return this.data[this.data.length - 1]; + } +} module.exports = Stack; From b9dddb5cf9a6cc1ccaf7914c8b207314ad340c1a Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Wed, 6 Mar 2024 05:37:40 -0500 Subject: [PATCH 29/46] qfroms: constructor init this.first, second as new Stacks() add(record) push record to first remove() while last record exists in first push the popped record from first to second record equals the last record popped from second while the last record exists in peek push the last record popped from second to first return record peek while last record exists in first push the last record popped from first to push record equals last record in second while last record exists in second push the last record popped from second to push return record --- .../exercises/qfroms/index.js | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/index.js index 93af154..c575ca1 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/qfroms/index.js @@ -14,6 +14,45 @@ const Stack = require('./stack'); -class Queue {} +class Queue { + constructor() { + this.first = new Stack(); + this.second = new Stack(); + } + + add(record) { + this.first.push(record); + } + + remove() { + while(this.first.peek()){ + // let record = this.first.pop(); + this.second.push(this.first.pop()); + + } + + const record = this.second.pop(); + + while(this.second.peek()) { + this.first.push(this.second.pop()); + } + + return record; + } + + peek() { + while(this.first.peek()) { + this.second.push(this.first.pop()); + } + + const record = this.second.peek(); + + while(this.second.peek()){ + this.first.push(this.second.pop()); + } + + return record; + } +} module.exports = Queue; From 94752a797fdaab5ff7f36a175bb14d90523e3e57 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Wed, 6 Mar 2024 07:09:54 -0500 Subject: [PATCH 30/46] clean up pyramid function with boolean and ternary --- .../exercises/pyramid/index.js | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js index 6105bfb..cc55237 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/pyramid/index.js @@ -21,11 +21,15 @@ // let level = ''; // for (let column = 0; column < 2 * n - 1; column++) { -// if(midpoint - row <= column && midpoint + row >= column) { -// level += '#'; -// } else { -// level += ' '; -// } + +// const condition = ((midpoint - row <= level.length) && (midpoint + row >= level.length)); +// condition ? level += "#" : level += " "; + +// // if((midpoint - row <= column) && (midpoint + row >= column)) { +// // level += '#'; +// // } else { +// // level += ' '; +// // } // } // console.log(level); // } @@ -35,18 +39,22 @@ function pyramid(n, row =0, level = '') { if(row === n) { return; } - if(level.length === 2 * n -1) { + if(level.length === 2 * n - 1) { console.log(level); return pyramid(n, row + 1); } const midpoint = Math.floor((2 * n - 1) / 2); let add; - if(midpoint - row <= level.length && midpoint + row >= level.length) { - add = '#'; - } else { - add = ' '; - } + + const condition = ((midpoint - row <= level.length) && (midpoint + row >= level.length)); + condition ? add = "#" : add = " "; + + // if((midpoint - row <= level.length) && (midpoint + row >= level.length)) { + // add = '#'; + // } else { + // add = ' '; + // } pyramid(n, row, level + add); } From d55b90dd76d5c84c960e130a2478a474ac3dcdb1 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Wed, 6 Mar 2024 07:55:22 -0500 Subject: [PATCH 31/46] linkedlist: node: constructor(data, next) this.data = data this.next = next linkedList constructor() this.head = null insertFirst(data) this.head = newNode(data, this.head) size() let counter = 0 let node = this.head while(node) increment counter; set node to next return counter --- .../exercises/linkedlist/index.js | 29 +++++++++++++++++-- .../exercises/linkedlist/test.js | 6 ++-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js index c75cc87..fc57dd5 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js @@ -2,8 +2,33 @@ // Implement classes Node and Linked Lists // See 'directions' document -class Node {} +class Node { + constructor(data, next){ + this.data = data; + this.next = next; + } +} -class LinkedList {} +class LinkedList { + constructor() { + this.head = null; + } + + insertFirst(data) { + this.head = new Node(data, this.head); + } + + size(){ + let counter = 0; + let node = this.head; + while(node) { + counter++; + node = node.next; + } + return counter; + + } + +} module.exports = { Node, LinkedList }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js index 18bdb64..f562755 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js @@ -10,7 +10,7 @@ test('Node is a class', () => { expect(typeof Node.prototype.constructor).toEqual('function'); }); -describe.skip('A Node', () => { +describe('A Node', () => { test('has properties "data" and "next"', () => { const node = new Node('a', 'b'); expect(node.data).toEqual('a'); @@ -18,7 +18,7 @@ describe.skip('A Node', () => { }); }); -describe.skip('Insert First', () => { +describe('Insert First', () => { test('appends a node to the start of the list', () => { const l = new List(); l.insertFirst(1); @@ -28,7 +28,7 @@ describe.skip('Insert First', () => { }); }); -describe.skip('Size', () => { +describe('Size', () => { test('returns the number of items in the linked list', () => { const l = new List(); expect(l.size()).toEqual(0); From 2a6808071e8251be8025a8da441cba1bc9a9fdbb Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Thu, 7 Mar 2024 08:29:14 -0500 Subject: [PATCH 32/46] linkedList: getFirst return this.head getLast if this.head doesn't exist, return null let node qual this.head while node exists if next node is null: return node node equals next node --- .../exercises/linkedlist/index.js | 18 ++++++++++++++++++ .../exercises/linkedlist/test.js | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js index fc57dd5..00ed6e5 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js @@ -26,7 +26,25 @@ class LinkedList { node = node.next; } return counter; + } + + getFirst() { + return this.head; + } + + getLast() { + if(!this.head){ + return null; + } + let node = this.head; + while(node){ + if (node.next === null){ + return node; + } + node = node.next; + + } } } diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js index f562755..7035c88 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js @@ -40,7 +40,7 @@ describe('Size', () => { }); }); -describe.skip('GetFirst', () => { +describe('GetFirst', () => { test('returns the first element', () => { const l = new List(); l.insertFirst(1); @@ -50,7 +50,7 @@ describe.skip('GetFirst', () => { }); }); -describe.skip('GetLast', () => { +describe('GetLast', () => { test('returns the last element', () => { const l = new List(); l.insertFirst(2); From dccae0ea88341828239c6fce855bb85e7deaf311 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Thu, 7 Mar 2024 19:03:29 -0500 Subject: [PATCH 33/46] linkedList: clear() set head to null removeFirst() if head does not exist: return null set head to next removeLast() if head does not exist: return if the next property of head does not exist set head to null, return set previous to head, set node to next while node.next exists set previous to node, node to next set the next of previous to null insertLast() set last to getLast() if last exists set next of last to new Node(data) else: set head to new Node(data) --- .../exercises/linkedlist/index.js | 48 +++++++++++++++++-- .../exercises/linkedlist/test.js | 8 ++-- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js index 00ed6e5..43f2e8d 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js @@ -39,14 +39,56 @@ class LinkedList { let node = this.head; while(node){ - if (node.next === null){ + if (!node.next){ return node; } - node = node.next; - + node = node.next; } } + clear() { + this.head = null; + } + + removeFirst() { + if(!this.head){ + return null; + } + + this.head = this.head.next; + } + + removeLast(){ + // for empty list + if(!this.head){ + return; + } + + // for list length one + if(!this.head.next){ + this.head = null; + return; + } + + // for list longer than one + let previous = this.head; + let node = this.head.next; + while(node.next){ + previous = node; + node = node.next + } + previous.next = null; + } + + insertLast(data) { + const last = this.getLast(); + + if(last) { + last.next = new Node(data); + } else { + this.head = new Node(data); + } + } } module.exports = { Node, LinkedList }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js index 7035c88..232b677 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js @@ -60,7 +60,7 @@ describe('GetLast', () => { }); }); -describe.skip('Clear', () => { +describe('Clear', () => { test('empties out the list', () => { const l = new List(); expect(l.size()).toEqual(0); @@ -74,7 +74,7 @@ describe.skip('Clear', () => { }); }); -describe.skip('RemoveFirst', () => { +describe('RemoveFirst', () => { test('removes the first node when the list has a size of one', () => { const l = new List(); l.insertFirst('a'); @@ -97,7 +97,7 @@ describe.skip('RemoveFirst', () => { }); }); -describe.skip('RemoveLast', () => { +describe('RemoveLast', () => { test('RemoveLast removes the last node when list is empty', () => { const l = new List(); expect(() => { @@ -135,7 +135,7 @@ describe.skip('RemoveLast', () => { }); }); -describe.skip('InsertLast', () => { +describe('InsertLast', () => { test('adds to the end of the list', () => { const l = new List(); l.insertFirst('a'); From 84758de969cb85bfbba534eb2e6d87f32441c5ad Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Thu, 7 Mar 2024 21:06:32 -0500 Subject: [PATCH 34/46] linkedList: getAt(index) if noHead: return null set counter at zero set node to head while node exists if counter equals index: return node increment counter, set node to next node return null removeAt(index) if index quals zero set head to next, return set previous to getAt(index minus one) if noPrevious or no previous.next return set previous.next to next of next inserAt(data, index) if noHead: set head to new Node data, return if index queals zero set head to new Node data, at index of this.head, return set previous to getAt(index minus one) or getLast() set node to new Node of data at prev.next set prev.next to node --- .../exercises/linkedlist/index.js | 59 ++++++++++++++++++- .../exercises/linkedlist/test.js | 6 +- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js index 43f2e8d..4842389 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js @@ -42,7 +42,8 @@ class LinkedList { if (!node.next){ return node; } - node = node.next; + node = node.next; + } } @@ -89,6 +90,62 @@ class LinkedList { this.head = new Node(data); } } + + getAt(index){ + if (!this.head){ + return null; + } + + let counter = 0; + let node = this.head; + while(node) { + if (counter === index) { + return node; + } + + counter++; + node = node.next; + } + return null; + } + + removeAt(index){ + if (!this.head){ + return; + } + + if (index === 0) { + this.head = this.head.next; + return; + } + + const previous = this.getAt(index - 1); + if(!previous || !previous.next) { + return; + } + previous.next = previous.next.next; + } + + insertAt(data, index){ + if(!this.head) { + this.head = new Node(data); + return; + } + + if(index === 0) { + this.head = new Node(data, this.head); + return + } + + const previous = this.getAt(index - 1) || this.getLast(); + const node = new Node(data, previous.next); + previous.next = node; + + + + + } + } module.exports = { Node, LinkedList }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js index 232b677..1694f3b 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js @@ -147,7 +147,7 @@ describe('InsertLast', () => { }); }); -describe.skip('GetAt', () => { +describe('GetAt', () => { test('returns the node at given index', () => { const l = new List(); expect(l.getAt(10)).toEqual(null); @@ -164,7 +164,7 @@ describe.skip('GetAt', () => { }); }); -describe.skip('RemoveAt', () => { +describe('RemoveAt', () => { test('removeAt doesnt crash on an empty list', () => { const l = new List(); expect(() => { @@ -217,7 +217,7 @@ describe.skip('RemoveAt', () => { }); }); -describe.skip('InsertAt', () => { +describe('InsertAt', () => { test('inserts a new node with data at the 0 index when the list is empty', () => { const l = new List(); l.insertAt('hi', 0); From eee2b577bc91235540c313557856d5e5d4df7c32 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sat, 9 Mar 2024 11:02:36 -0500 Subject: [PATCH 35/46] linkedList: code reuse: inserAt: insertFirst, insertLast getAt: getFirst, getLast removeAt: removeFirst, removeLast forEach(fn): set node to head while(node) pass node to fn set node to next *[Symbol.iterator]() { set node to head while node exists: yield node set node to next --- .../exercises/linkedlist/index.js | 182 ++++++++++-------- .../exercises/linkedlist/test.js | 4 +- 2 files changed, 105 insertions(+), 81 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js index 4842389..6edd76c 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/index.js @@ -14,83 +14,53 @@ class LinkedList { this.head = null; } - insertFirst(data) { - this.head = new Node(data, this.head); - } - - size(){ - let counter = 0; - let node = this.head; - while(node) { - counter++; - node = node.next; - } - return counter; - } - - getFirst() { - return this.head; - } - - getLast() { - if(!this.head){ - return null; - } - - let node = this.head; - while(node){ - if (!node.next){ - return node; - } - node = node.next; - - } - } - - clear() { - this.head = null; - } - - removeFirst() { - if(!this.head){ - return null; - } - - this.head = this.head.next; - } - - removeLast(){ - // for empty list - if(!this.head){ + insertAt(data, index) { + // if list is empty + if (!this.head) { + this.head = new Node(data); return; - } - - // for list length one - if(!this.head.next){ - this.head = null; + } + + // if inserting at first node + if (index === 0) { + this.head = new Node(data, this.head); return; - } + } - // for list longer than one - let previous = this.head; - let node = this.head.next; - while(node.next){ - previous = node; - node = node.next + // if inserting later in list + const previous = this.getAt(index - 1) || this.getLast(); + const node = new Node(data, previous.next); + previous.next = node; } - previous.next = null; - } + + + + insertFirst(data) { + this.head = new Node(data, this.head); + } insertLast(data) { const last = this.getLast(); if(last) { - last.next = new Node(data); + // last.next = new Node(data); + this.insertAt(data, last.next) } else { - this.head = new Node(data); + //this.head = new Node(data); + this.insertFirst(data); } } + size(){ + let counter = 0; + let node = this.head; + while(node) { + counter++; + node = node.next; + } + return counter; + } + getAt(index){ if (!this.head){ return null; @@ -109,6 +79,31 @@ class LinkedList { return null; } + getFirst() { + // return this.head; + return this.getAt(0); + } + + getLast() { + // if(!this.head){ + // return null; + // } + + // let node = this.head; + // while(node){ + // if (!node.next){ + // return node; + // } + // node = node.next; + + // } + return this.getAt(this.size()- 1); + } + + clear() { + this.head = null; + } + removeAt(index){ if (!this.head){ return; @@ -126,26 +121,55 @@ class LinkedList { previous.next = previous.next.next; } - insertAt(data, index){ - if(!this.head) { - this.head = new Node(data); - return; - } - - if(index === 0) { - this.head = new Node(data, this.head); - return - } - - const previous = this.getAt(index - 1) || this.getLast(); - const node = new Node(data, previous.next); - previous.next = node; + removeFirst() { + // if(!this.head){ + // return null; + // } + // this.head = this.head.next; + this.removeAt(0); + } + removeLast(){ + // // for empty list + // if(!this.head){ + // return; + // } + + // // for list length one + // if(!this.head.next){ + // this.head = null; + // return; + // } + + // // for list longer than one + // let previous = this.head; + // let node = this.head.next; + // while(node.next){ + // previous = node; + // node = node.next + // } + // previous.next = null; + this.removeAt(this.size() - 1); + } + forEach(fn) { + let node = this.head; + while(node){ + fn(node); + node = node.next; + } + } - } + *[Symbol.iterator]() { + let node = this.head; + while (node) { + yield node; + node = node.next; + } + } } + module.exports = { Node, LinkedList }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js index 1694f3b..f4de046 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/linkedlist/test.js @@ -272,7 +272,7 @@ describe('InsertAt', () => { }); }); -describe.skip('ForEach', () => { +describe('ForEach', () => { test('applies a transform to each node', () => { const l = new List(); @@ -292,7 +292,7 @@ describe.skip('ForEach', () => { }); }); -describe.skip('for...of loops', () => { +describe('for...of loops', () => { test('works with the linked list', () => { const l = new List(); From b68359c5c04057ec8484bdcc2b766bfc04b15f21 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sat, 9 Mar 2024 11:37:17 -0500 Subject: [PATCH 36/46] linkedList: midpoint let slow, fast equal getFirst() while fast & fast.next & fast.next.next increment slow, increment fast by two return slow circular let slow|fast equal getFirst() while fast & f.next & f.next.next increment slow|fast by two if(slow equals fast) rt: true, else false fromLast let slow|fast equal getFirst while n is greated than zero increment fast by one, decrement n while fast.next exists increment slow|fast by one return slow --- .../exercises/circular/index.js | 16 +++++++++++++++- .../exercises/fromlast/index.js | 16 +++++++++++++++- .../exercises/midpoint/index.js | 11 ++++++++++- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/index.js index 6a1a9a9..15e4cb7 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/circular/index.js @@ -12,6 +12,20 @@ // c.next = b; // circular(l) // true -function circular(list) {} +function circular(list) { + let slow = list.getFirst(); + let fast = list.getFirst(); + + while(fast && fast.next && fast.next.next){ + slow = slow.next; + fast = fast.next.next; + + if(slow === fast){ + return true; + } + } + + return false; +} module.exports = circular; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/index.js index e5c9f31..b62c92b 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/fromlast/index.js @@ -11,6 +11,20 @@ // list.insertLast('d'); // fromLast(list, 2).data // 'b' -function fromLast(list, n) {} +function fromLast(list, n) { + let fast = list.getFirst(); + let slow = list.getFirst(); + + while(n > 0){ + fast = fast.next; + n--; + } + + while(fast.next){ + slow = slow.next; + fast = fast.next; + } + return slow; +} module.exports = fromLast; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/index.js index 8bf6894..8aa4683 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/midpoint/index.js @@ -12,6 +12,15 @@ // l.insertLast('c') // midpoint(l); // returns { data: 'b' } -function midpoint(list) {} +function midpoint(list) { + let slow = list.getFirst(); + let fast = list.getFirst(); + + while(fast.next && fast.next.next){ + slow = slow.next; + fast = fast.next.next; + } + return slow; +} module.exports = midpoint; From d24436f976ba2cb0ebf88b86f2e1e3f7e96ddd0c Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Sat, 9 Mar 2024 13:27:53 -0500 Subject: [PATCH 37/46] tree: node constructor pass in data set this.data to data set this.children to empty array addd(data) this.children.push(new Node(data)) remove(data) this.children equals this.children filter(node => return nod.data !== data tree constructor this.root equals null traverseBF(fn) set arr to [this.root] while(arr.lenght) { const node equals arr.shift() arr.push(...node.children) fn(node) traverseDF(fn) const arr to [this.root] while arr.length set node to arr.shift() arr.unshift(...node.children) fn(node) --- .../exercises/tree/index.js | 48 ++++++++++++++++++- .../exercises/tree/test.js | 2 +- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/index.js index 0ef59b8..f69a05d 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/index.js @@ -10,8 +10,52 @@ // on the tree class. Each method should accept a // function that gets called with each element in the tree -class Node {} +class Node { + constructor(data){ + this.data = data; + this.children = []; + } -class Tree {} + add(data){ + // const node = new Node(data); + this.children.push(new Node(data)); + } + + remove(data){ + this.children = this.children.filter(node => { + return node.data != data; + }); + } + +} + +class Tree { + constructor(){ + this.root = null; + } + + traverseBF(fn){ + const arr = [this.root]; + while(arr.length){ + const node = arr.shift(); + + arr.push(...node.children); + fn(node); + // for(let child of node.children){ + // arr.push(child); + // } + } + } + + traverseDF(fn){ + const arr = [this.root]; + while(arr.length){ + const node = arr.shift(); + + arr.unshift(...node.children); + fn(node); + } + } +} module.exports = { Tree, Node }; diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/test.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/test.js index 1a103ed..69dab5d 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/test.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/tree/test.js @@ -29,7 +29,7 @@ describe('Node', () => { }); }); -describe.skip('Tree', () => { +describe('Tree', () => { test('starts empty', () => { const t = new Tree(); expect(t.root).toEqual(null); From a06b1ca0c9c63ddedaab47bdb0d93e199a687fb2 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Tue, 12 Mar 2024 21:41:59 -0400 Subject: [PATCH 38/46] levelwidth: call levelWidht(root) set arr to [root, 's'] set counters arr to [0] while(arr.length > 1) // avoids infinite loop w. stopper set node to arr.shift() if(node === 's'){} counters.push(0) // new level arr.push('s') // adds s back to checker arr else arr.push(...node.children) //children of current node increment counters[last elm] return counters --- .../exercises/levelwidth/index.js | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/index.js index 802cc4a..5bc0c06 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/levelwidth/index.js @@ -11,6 +11,24 @@ // 4 5 // Answer: [1, 3, 2] -function levelWidth(root) {} +function levelWidth(root) { + const arr = [root, 's'] + const counters = [0] + + while(arr.length > 1) { + const node = arr.shift(); + + if(node === 's'){ + counters.push(0); + arr.push('s'); + + } else { + arr.push(...node.children); + counters[counters.length - 1]++; + } + + } + return counters; +} module.exports = levelWidth; From 194aee61c5b764a81c11d65cf90dc11ac9983bd5 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Tue, 12 Mar 2024 22:19:05 -0400 Subject: [PATCH 39/46] bst: class Node constructor: pass in data this.data as data this.right as null this.left as null insert: pass in data handle less than current node w. left child this.left.insert(data) handles less than current node w.o left this.left = new Node(data) handle greater than current node w. right child this.right.insert(data) handle greater than current node w.o right this.right = new Node(data) contains: pass in data if(this.data equals data): return this if(this.data < data && this.right) return this.right.contains(data) else this.d greater than data and this.left return this.left.contains(data) return null --- .../exercises/bst/index.js | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/bst/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/bst/index.js index 25aabd6..ceec26c 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/bst/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/bst/index.js @@ -11,6 +11,42 @@ // class. Contains should accept a 'data' argument // and return the Node in the tree with the same value. -class Node {} +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + + insert(data){ + // handle less than current node w. left child + if(data < this.data && this.left){ + this.left.insert(data) + // handle less than current node w/o left + } else if (data < this.data) { + this.left = new Node(data) + + // handle greater than current node w. right child + }else if(data > this.data && this.right) { + this.right.insert(data); + // handle greater than current node w/o right + } else if(data > this.data){ + this.right = new Node(data) + } + } + + contains(data){ + if(this.data === data){ + return this; + } + + if (this.data < data && this.right){ + return this.right.contains(data); + } else if (this.data > data && this.left){ + return this.left.contains(data) + } + return null; + } +} module.exports = Node; From c13ac0ee0984581c92acc48febdd902f03436b90 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Tue, 12 Mar 2024 22:38:28 -0400 Subject: [PATCH 40/46] validate: validate(node, min as null, max as null) if max not null and node.data greater than max: rt false if min no null and node.data less than min: rt false if node.left and nt.validate(n.left, min, node.data: rt false if node.right and nt.validate(n.right, node.data, max: rt false return true --- .../exercises/validate/index.js | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/index.js index a5f99d6..e9c3fc9 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/validate/index.js @@ -5,6 +5,25 @@ // every node's right hand child is greater than // the parent -function validate(node, min = null, max = null) {} +function validate(node, min = null, max = null) { + + if(max !== null && node.data > max){ + return false; + } + + if(min !== null && node.data < min){ + return false; + } + + if(node.left && !validate(node.left, min, node.data)){ + return false; + } + + if(node.right && !validate(node.right, node.data, max)){ + return false; + } + + return true; +} module.exports = validate; From ac0f23c5809950ddc4c69170f88dbb4007db2c77 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Tue, 12 Mar 2024 22:56:10 -0400 Subject: [PATCH 41/46] events: constructor(): set this.events to empty object //register event handler on(eventName, callback): if eventName exists in this.events: push callback to events[eventName] else set events[eventName] to [callback] trigger(eventName): if eventName exists at this.events for callback of t.events[eName]{ callback() off(eventName){ delete eventName at t.events --- .../exercises/events/example.html | 7 +++++- .../exercises/events/index.js | 24 ++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/example.html b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/example.html index 3de3dae..f87a916 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/example.html +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/example.html @@ -5,6 +5,11 @@

Click the button

diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/index.js index 7d9b0dd..23352db 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/events/index.js @@ -5,15 +5,33 @@ class Events { // Register an event handler - on(eventName, callback) {} + constructor() { + this.events = {}; + } + // Register an event handler + on(eventName, callback) { + if (this.events[eventName]) { + this.events[eventName].push(callback); + } else { + this.events[eventName] = [callback]; + } + } // Trigger all callbacks associated // with a given eventName - trigger(eventName) {} + trigger(eventName) { + if (this.events[eventName]){ + for (let callback of this.events[eventName]){ + callback(); + } + } + } // Remove all event handlers associated // with the given eventName - off(eventName) {} + off(eventName) { + delete this.events[eventName]; + } } module.exports = Events; From 8898416bad147f09f9b2d661333635ffce55165d Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Wed, 13 Mar 2024 09:59:18 -0400 Subject: [PATCH 42/46] bubbleSort: iterate through arr as i iterate to lenght -i -1 as j compare arr at j to j plus one swap logic set temp as j plus one set element at j plus one as elm at j(greater) set elm at j to temp(lesser) return arr --- .../exercises/sorting/index.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js index acbaf3f..1203a6c 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js @@ -3,6 +3,17 @@ function bubbleSort(arr) { + for (let i = 0; i < arr.length; i++) { + for(let j =0; j < arr.length - i - 1; j++){ + + if(arr[j] > arr[j+1]){ + const lesser = arr[j+1]; + arr[j + 1] = arr[j]; + arr[j] = lesser; + } + } + } + return arr; } function selectionSort(arr) { From 19e983e3e1fcb26e6df739f8001e71ba978dd879 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Wed, 13 Mar 2024 10:17:27 -0400 Subject: [PATCH 43/46] selectionSort iterate through arr as i set indexOfMin to i iterate through arr as j starting at i plus one if elm at j is less than elm at indexOfMin set ndexOfMin to j if indexOfMin d.equal i swap arr at indexOfMin and I set temp to arr at indexOfMin set arr at indexOfMin to arr at i set arr at i to temp return arr --- .../exercises/sorting/index.js | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js index 1203a6c..57bcdea 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js @@ -7,9 +7,9 @@ function bubbleSort(arr) { for(let j =0; j < arr.length - i - 1; j++){ if(arr[j] > arr[j+1]){ - const lesser = arr[j+1]; + const temp = arr[j+1]; arr[j + 1] = arr[j]; - arr[j] = lesser; + arr[j] = temp; } } } @@ -18,6 +18,22 @@ function bubbleSort(arr) { function selectionSort(arr) { + for (let i = 0; i < arr.length; i++){ + let indexOfMin = i; + + for(let j = i + 1; j < arr.length; j++){ + if(arr[j] < arr[indexOfMin]){ + indexOfMin = j; + } + } + + if(indexOfMin !== i) { + let temp = arr[indexOfMin]; + arr[indexOfMin] = arr[i]; + arr[i] = temp; + } + } + return arr; } function mergeSort(arr) { From ff90b099b616738bed00294762ebbf81c6029566 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Wed, 13 Mar 2024 10:41:46 -0400 Subject: [PATCH 44/46] mergeSort: merge: pass in left, right cretate results arr as empty while left.length and right.length check if left at zero is less than right at zero push shifted item from left to results else: push shifted item from right to resutls return spread results, left, right mergeSort pass in arr if arr.length equals one: return arr create center as floor of lenght divided by two set left to slice of zero to center set right to slice of center return merge(mergeSort(left), mergeSort(right) --- .../exercises/sorting/index.js | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js index 57bcdea..efd32e0 100644 --- a/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js +++ b/Grider-Stephen-AlgoCasts-JS-Practice/exercises/sorting/index.js @@ -37,11 +37,32 @@ function selectionSort(arr) { } function mergeSort(arr) { + if(arr.length === 1){ + return arr; + } + + const center = Math.floor(arr.length / 2); + const left = arr.slice(0, center); + const right = arr.slice(center); + + return merge(mergeSort(left), mergeSort(right)); + + } function merge(left, right) { + const results = []; + + while(left.length && right.length) { + if(left[0] < right[0]){ + results.push(left.shift()); + }else { + results.push(right.shift()); + } + } + return [...results, ...left, ...right]; } module.exports = { bubbleSort, selectionSort, mergeSort, merge }; From 7fe0728e599343dce02118747805a370f7411240 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Wed, 20 Mar 2024 13:05:06 -0400 Subject: [PATCH 45/46] palindrome solution w. double pointers: clean string w. .toLowerCase().replace(/[^\w]/g. ) set left, right pointer while left less than right if s[left] !== s[right]: return false increment left, decrement right, return true --- Nguyen-Kevin-JS-Leet-Practice/palindrome.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Nguyen-Kevin-JS-Leet-Practice/palindrome.js diff --git a/Nguyen-Kevin-JS-Leet-Practice/palindrome.js b/Nguyen-Kevin-JS-Leet-Practice/palindrome.js new file mode 100644 index 0000000..a0f1fb3 --- /dev/null +++ b/Nguyen-Kevin-JS-Leet-Practice/palindrome.js @@ -0,0 +1,17 @@ + +function isParlindrome(s){ + s =s.toLowerCase().replace(/[^\w]/g, ""); + + let left = 0; + let right = s.length -1; + + while(left < right) { + if (s[left] !== s[right]){ + return false; + } + left++; + right--; + } + return true; +} + From b664521e0903b2eb8ac2f13e1c19f9728c544002 Mon Sep 17 00:00:00 2001 From: possibilitiesInTest Date: Thu, 21 Mar 2024 23:39:28 -0400 Subject: [PATCH 46/46] longestSubstring: -create empty hashMap for char|index -init start, max to zero iterate through input string check if curr Char in has and has index >= start set start to index for char found in hashmap + 1 set key|val on has to curr char | curr index if len of curr window greater than max set max to len of curr window return max len --- .../longestSubstring.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Nguyen-Kevin-JS-Leet-Practice/longestSubstring.js diff --git a/Nguyen-Kevin-JS-Leet-Practice/longestSubstring.js b/Nguyen-Kevin-JS-Leet-Practice/longestSubstring.js new file mode 100644 index 0000000..25e1840 --- /dev/null +++ b/Nguyen-Kevin-JS-Leet-Practice/longestSubstring.js @@ -0,0 +1,17 @@ +function lengthOfLongestSubstring(s) { + let windowCharsMap = {}; + let windowStart = 0; + let maxLength = 0; + + for (let i =0; i < s.length; i++) { + const endChar = s[i]; + + if(windowCharsMap[endChar] >= windowStart) { + windowStart = windowCharsMap[endChar] + 1; + } + + windowCharsMap[endChar] = i; + maxLength = Math.max(maxLength, i - windowStart + 1); + } + return maxLength; +} \ No newline at end of file