diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..9d31e80 --- /dev/null +++ b/.babelrc @@ -0,0 +1,5 @@ +{ + "presets":[ + "es2015", "react" + ] +} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..0c50d12 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,33 @@ +module.exports = { + "env": { + "browser": true, + "commonjs": true, + "es6": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaFeatures": { + "experimentalObjectRestSpread": true, + "jsx": true + }, + "sourceType": "module" + }, + "rules": { + "indent": [ + "error", + 2 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ] + } +}; diff --git a/.gcc-flags.json b/.gcc-flags.json new file mode 100644 index 0000000..9b4e212 --- /dev/null +++ b/.gcc-flags.json @@ -0,0 +1,8 @@ +{ + "execPath": "/usr/bin/g++", + "gccDefaultCFlags": "-Wall", + "gccDefaultCppFlags": "-Wall -std=c++11", + "gccErrorLimit": 15, + "gccIncludePaths": ".,./include,./path", + "gccSuppressWarnings": true +} diff --git a/.gitignore b/.gitignore index e43b0f9..66c7cfb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,22 @@ +# npm installs +/node_modules +*/node_modules + +# MongoDB +*/data + +# all logfiles and tempfiles. +/log/* +!/log/.keep +/tmp + +# Ignore vim +*~ +*.swp +*.swo + +# Ignore macOS .DS_Store + +# gcc +a.out diff --git a/allAnagrams/allAnagrams.js b/allAnagrams/allAnagrams.js deleted file mode 100644 index a214c6a..0000000 --- a/allAnagrams/allAnagrams.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Given a single input string, write a function that produces all possible anagrams - * of a string and outputs them as an array. At first, don't worry about - * repeated strings. What time complexity is your solution? - * - * Extra credit: Deduplicate your return array. - */ - -/** - * example usage: - * const anagrams = allAnagrams('abc'); - * console.log(anagrams); // [ 'abc', 'acb', 'bac', 'bca', 'cab', 'cba' ] - */ \ No newline at end of file diff --git a/array/array.js b/array/array.js deleted file mode 100644 index 7460fa2..0000000 --- a/array/array.js +++ /dev/null @@ -1,9 +0,0 @@ -/* Make a class called Array. - * It should have the methods push, pop, get(index), and delete(index). - * get and delete should accept an index and get or remove the item at that index. - * Make sure to shift the array items after deleting an item. - * In your implementation use a JS object to build the array. - * Do NOT use an array as the underlying data structure, that's cheating :) - * How do these operations compare to that of a linked list? - * How does the time complexity of insertion and deletion compare to that of a linked list? - */ diff --git a/binarySearch/binarySearch.js b/binarySearch/binarySearch.js deleted file mode 100644 index b7a345b..0000000 --- a/binarySearch/binarySearch.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Given a sorted array, find the index of the specified element - * using binary search. - * https://www.khanacademy.org/computing/computer-science/algorithms/binary-search/a/binary-search - * https://en.wikipedia.org/wiki/Binary_search_algorithm - * */ - -/** - * * const index = binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2); - * * console.log(index); // 1 -**/ - -const binarySearch = (nums, target) => { - -}; diff --git a/cc01longestString/longestString.js b/cc01longestString/longestString.js new file mode 100644 index 0000000..44a95be --- /dev/null +++ b/cc01longestString/longestString.js @@ -0,0 +1,35 @@ +/* + * Write a function that accepts an array of strings. + * Return the longest string in the array. + */ + +/* Take the first array item and put it in a "holding" array. + * Compare it to the next anArray, put the bigger of the two in the holding array. + */ +const bigString = function (anArr) { + const holdBig = [anArr[0]]; + const tie = ['There\'s a tie: ']; + + for (let i = 1; i < anArr.length; i++) { + if (holdBig[0].length < anArr[i].length) { + holdBig.pop(); + // console.log(anArr[i]); + holdBig.push(anArr[i]); + }; + // tie if length match but different string - NOPE + // if (holdBig[0].length === anArr[i].length) { + // tie.push(anArr[i]); + // return `${tie[0]} ${tie[1]}`; + // } + }; + return holdBig[0]; +}; + +testAnArray = ['fred', 'ted', 'bob', 'alice', 'joe', 'arnold', 'mary', 'jebedaiah', 'ed', 'zachahurres', 'mae', 'antidisestablishmentarianism'] +console.log(bigString(testAnArray)); // ---> antidisestablishmentarianism + +// Refactor to return an array of the equal length strings if there's a tie? √ +// testAnArrayTie = ['fred', 'ted', 'bob', 'antidisestablishmentarianism', 'alice', 'joe', 'arnold', 'mary', 'jebedaiah', 'ed', 'zachahurres', 'mae', 'antidisestablishmentarianism', 'manny'] +// console.log(bigString(testAnArrayTie)); + +// Refactor to handle non-Array arguments? diff --git a/cc01longestString/solution.js b/cc01longestString/solution.js new file mode 100644 index 0000000..87fa3c2 --- /dev/null +++ b/cc01longestString/solution.js @@ -0,0 +1,35 @@ +const longestString = (strArr) => { + let tempStr = ''; + strArr.forEach(str => { + if(str.length > tempStr.length) tempStr = str; + }); + return tempStr; +}; + +longestString(['abc', 'def', 'gasdfasf', 'asdf', 'e', 'agwoaiengpoing']); + +// Ryan's lecture video comments: +// https://youtu.be/juZvUpn4j5Y +const longestString = (strArr) => { + // tempStr variable to hold the string + let tempStr = ''; + // loop over strArr + strArr.forEach(str => { + // if current string in arry is bigger than tempStr, + // then update the variable tempStr + if(str.length > tempStr.length) tempStr = str; + }) + return tempStr; +}; + +console.log(`Ryan: ${longestString(['abc', 'def', 'gasdfasf', 'asdf', 'e', 'agwoaiengpoing', 'pp'])}`); + +// Jesh's solution using sort() +const longStr = (arr) => { + arr.sort((a, b) => { + return b.length - a.length; + }); + return arr[0]; +} + +console.log(`Jesh: ${longStr(['abc', 'def', 'gasdfasf', 'asdf', 'e', 'agwoaiengpoing', 'pp'])}`); diff --git a/cc02isUnique/isUnique.js b/cc02isUnique/isUnique.js new file mode 100755 index 0000000..f545315 --- /dev/null +++ b/cc02isUnique/isUnique.js @@ -0,0 +1,21 @@ +/* +* Implement an algorithm to determine if a string has all unique characters. +* Extra Credit - Answer this question - What if you cannot use additional data structures? +*/ +const isUnique = (str) => { + for (let i = 0; i < str.length; i++) { + for (let j = i + 1; j < str.length; j++) { + // console.log(`Q: does ${str[i]} === ${str[j]}? A: ${str[i] === str[j]}`) + if (str[i] === str[j]) { + return false; + } + } + } return true; +}; + +console.log(isUnique('abcdhijklmnopqrstuv')); // true +console.log(isUnique('abcdefghijklmnopqrstuvwyz')); // true +console.log(isUnique('abcdefga')); // false +console.log(isUnique('bcdgefga')); // false +console.log(isUnique([1, 2, 3, 4, 5, 6, 3])); // false +console.log(isUnique([0, 1, 2, 3, 4, 6, 7, 8, 9, 9])); // false diff --git a/isUnique/solution.js b/cc02isUnique/solution.js similarity index 100% rename from isUnique/solution.js rename to cc02isUnique/solution.js diff --git a/cc03reverseCase/pdk_reverseCase.js b/cc03reverseCase/pdk_reverseCase.js new file mode 100644 index 0000000..4cafa7f --- /dev/null +++ b/cc03reverseCase/pdk_reverseCase.js @@ -0,0 +1,53 @@ +// I don't know why this got merge/erased, but this is my work: + +/* + * Write a function that reverses the case of each letter in the strings that it receives. + * Example: 'Hello World' -> 'hELLO wORLD' + * Assume that each string will contain only spaces and letters. + */ + +const reverseCase = function (str) { + // declare an array to house individual string letters or spaces in word/sentence order + const letters = []; + // declare a variable which will be used to reconstructed string + let caseConvertedString; + + // examine each letter in the string + for (let i = 0; i < str.length; i++) { + // uppercase or lowercase or a space? + // if a space, push space into temp holding array (if not a space, it's a letter) + if (str[i] === ' ') { + letters.push(str[i]); + // if already Upper Case, push lower Case version of letter into holding array + } else if (str[i] === str[i].toUpperCase()) { + letters.push(str[i].toLowerCase()) + // if not space and not already Upper Case, push Upper Case version of letter to holding array + } else letters.push(str[i].toUpperCase()) + } + // zip up the array of letters and spaces into a string + caseConvertedString = letters.join(''); + return caseConvertedString; +} + +const testCase1 = 'Hello World' +console.log(reverseCase(testCase1)); // ---> hELLO wORLD +const testCase2 = 'Fsdfsdf ESDFSDFdfsdfsdfsdfdsf'; +console.log(reverseCase(testCase2)); // ---> fSDFSDF esdfsdfDFSDFSDFSDFDSF +// will it handle periods? +const testCase3 = 'The quick brown Mr. Fox jumped over the lazy Mr. Dog.'; +console.log(reverseCase(testCase3)); // ---> tHE QUICK BROWN mR. fOX JUMPED OVER THE LAZY mR. dOG. + +// // Latoyya's solution +// const reverseString = (str) => { +// let newString = ''; +// for (let i = 0; i < str.length; i++) { +// if (str.charCodeAt(i) >= 65 && str.charCodeAt(i) <= 90) { +// newString += str.charAt(i).toLowerCase(); +// } else { +// newString += str.charAt(i).toUpperCase(); +// } +// } +// return newString; +// }; +// console.log(reverseString('Hello World')); +// console.log(reverseString('Hello World My NamE is LAtoyYa SmitH')); diff --git a/reverseCase/reverseCase.js b/cc03reverseCase/reverseCase.js similarity index 100% rename from reverseCase/reverseCase.js rename to cc03reverseCase/reverseCase.js diff --git a/reverseCase/solution.js b/cc03reverseCase/solution.js similarity index 100% rename from reverseCase/solution.js rename to cc03reverseCase/solution.js diff --git a/cc04largestPrimePalindrome/findPrimePalindromes.js b/cc04largestPrimePalindrome/findPrimePalindromes.js new file mode 100644 index 0000000..d7365f6 --- /dev/null +++ b/cc04largestPrimePalindrome/findPrimePalindromes.js @@ -0,0 +1,104 @@ +// I: a sorted array of prime numbers, smallest to largest +// O: array of prime palindromes +const findPrimePals = function(primeArr) { + // console.log(primeArr); + const primePalsArr = [] + for (i = 0; i < primeArr.length; i++) { + if (isPalindrome(numToStr(primeArr[i]))) primePalsArr.push(numToStr(primeArr[i])) + } + return primePalsArr; +} + +// evaluates a range of natural numbers +// I: largest number in range (inclusive) +// O: an array of ALL prime #'s from range 0 thru INPUT integer +const findPrimes = function(bigNum) { + const primes = []; + // for number in range 0 thru *num + for (i = 0; i <=bigNum; i++) { + if (isPrime(i)) primes.push(i); + } + return primes; + } + +// I: any integer +// O: "true" if INPUT is a prime number +const isPrime = function(num) { + // return true if num is prime. + // otherwise return false + if (num < 2) {return false;} + else if (num === 2) {return true;} + else if (num % 2 === 0) {return false;} + else if (num >= 3) { + for (var i = 2; i < Math.sqrt(num + 1); i++) { // Maybe a ceiling would work better (but slower?)? + if (num % i === 0) { + return false; + } + } + } return true; +} + +// I: any string NOTE: does NOT handle integers +// O: "true" if INPUT is a palindrome +function isPalindrome(str) { + // return true if string is a palindrome. + // otherwise return false + for (let i = 0; i < str.length / 2; i++) { // <--- make sure divided by 2 handles odd and even length (floor vs. ceiling) + if (str[i] === str[str.length - 1 - i]) { + return true; + } else { + return false; + } + } +} + +// I: a NUMBER +// O: a STRING +const numToStr = function(num) { + return `${num}`; +} + +// // isPalindrome() TEST SUITE +// console.log(`Q: Is 'palindrome' a palindrome? A: ${isPalindrome('palindrome')}`) // <-- false +// console.log(`Q: Is ' ' a palindrome? A: ${isPalindrome(' ')}`) // <-- true +// console.log(`Q: Is 'a' a palindrome? A: ${isPalindrome('a')}`) // <-- true +// console.log(`Q: Is 'bb' a palindrome? A: ${isPalindrome('bb')}`) // <-- true +// console.log(`Q: Is 'cdc' a palindrome? A: ${isPalindrome('cdc')}`) // <-- true +// console.log(`Q: Is 'amanaplanacanalpanama' a palindrome? A: ${isPalindrome('amanaplanacanalpanama')}`) // <-- true +// console.log(`Q: Is an integer a palindrome? A: ${isPalindrome(5)}`) // <-- undefined + +// // numToStr() test +// console.log(numToStr(5)); // <--- '5' +// console.log(typeof numToStr(5)); // <--- string +// console.log(`Q: Is the integer converted to a string? A: ${isPalindrome(numToStr(5))}`) // <-- true + +// // isPrime TEST SUITE +// // 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, +// console.log(`Q: Is 0 prime? A: ${isPrime(0)}`) // <--- false +// console.log(`Q: Is 1 prime? A: ${isPrime(1)}`) // <--- false +// console.log(`Q: Is 2 prime? A: ${isPrime(2)}`) // <--- true +// console.log(`Q: Is 3 prime? A: ${isPrime(3)}`) // <--- true +// console.log(`Q: Is 4 prime? A: ${isPrime(4)}`) // <--- false +// console.log(`Q: Is 5 prime? A: ${isPrime(5)}`) // <--- true +// console.log(`Q: Is 6 prime? A: ${isPrime(6)}`) // <--- false +// console.log(`Q: Is 7 prime? A: ${isPrime(7)}`) // <--- true +// console.log(`Q: Is 8 prime? A: ${isPrime(8)}`) // <--- false +// console.log(`Q: Is 9 prime? A: ${isPrime(9)}`) // <--- false +// console.log(`Q: Is 10 prime? A: ${isPrime(10)}`) // <--- false +// console.log(`Q: Is 11 prime? A: ${isPrime(11)}`) // <--- true +// console.log(`Q: Is 12 prime? A: ${isPrime(12)}`) // <--- false +// console.log(`Q: Is 13 prime? A: ${isPrime(13)}`) // <--- true +// console.log(`Q: Is 121 prime? A: ${isPrime(121)}`) // <--- false (11 * 11 = 121) +// console.log(`Q: Is 104729 prime? A: ${isPrime(104729)}`)// <--- true (104,729 is the 10,000th prime number!) + +// // findPrimes TEST SUITE +// [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127] +console.log(`Q: what are the primes from 0 to 127?\nA: ${findPrimes(127)}`); +// console.log(`Q: what are the primes from 0 to 121?\nA: ${findPrimes(104729)}`); // <--- 10,000 prime numbers!!!! +console.log(findPrimes(104729).length); + +// findPrimePals TEST SUITE +// [11, 101, ...] +console.log(`Q: Is findPrimePals(findPrimes(127)) an instance of an array?\nA: ${findPrimePals(findPrimes(127)) instanceof Array}`); // <--- true +console.log(`Q: what are the prime palindromes from 0 to 127?\nA: ${findPrimePals(findPrimes(127))}`); // <--- 2,3,5,7,11,101 +console.log(`Q: what are the prime palindromes from 0 to 1000?\nA: ${findPrimePals(findPrimes(1000))}`); // <--- 2,3,5,7,11,101,131,151,181,191,313,353,373,383,727,757,787,797,919,929 diff --git a/cc04largestPrimePalindrome/findPrimes.js b/cc04largestPrimePalindrome/findPrimes.js new file mode 100644 index 0000000..60daad1 --- /dev/null +++ b/cc04largestPrimePalindrome/findPrimes.js @@ -0,0 +1,52 @@ +// evaluates a range of natural numbers +// I: largest number in range (inclusive) +// O: an array of ALL prime #'s from range 0 thru input integer +const findPrimes = function(bigNum) { + const primes = []; + // for number in range 0 thru bigNum + for (i = 0; i <=bigNum; i++) { + if (isPrime(i)) primes.push(i); + } + return primes; + } + +const isPrime = function(num) { + // return true if num is prime. + // otherwise return false + if (num < 2) {return false;} + else if (num === 2) {return true;} + else if (num % 2 === 0) {return false;} + else if (num >= 3) { + for (var i = 2; i < Math.sqrt(num + 1); i++) { // Maybe a ceiling would work better (but slower?)? + if (num % i === 0) { + return false; + } + } + } return true; +} + + +// isPrime TEST SUITE +// 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, +console.log(`Q: 0 is prime? A: ${isPrime(0)}`) // <--- false +console.log(`Q: 1 is prime? A: ${isPrime(1)}`) // <--- false +console.log(`Q: 2 is prime? A: ${isPrime(2)}`) // <--- true +console.log(`Q: 3 is prime? A: ${isPrime(3)}`) // <--- true +console.log(`Q: 4 is prime? A: ${isPrime(4)}`) // <--- false +console.log(`Q: 5 is prime? A: ${isPrime(5)}`) // <--- true +console.log(`Q: 6 is prime? A: ${isPrime(6)}`) // <--- false +console.log(`Q: 7 is prime? A: ${isPrime(7)}`) // <--- true +console.log(`Q: 8 is prime? A: ${isPrime(8)}`) // <--- false +console.log(`Q: 9 is prime? A: ${isPrime(9)}`) // <--- false +console.log(`Q: 10 is prime? A: ${isPrime(10)}`) // <--- false +console.log(`Q: 11 is prime? A: ${isPrime(11)}`) // <--- true +console.log(`Q: 12 is prime? A: ${isPrime(12)}`) // <--- false +console.log(`Q: 13 is prime? A: ${isPrime(13)}`) // <--- true +console.log(`Q: 121 is prime? A: ${isPrime(121)}`) // <--- false (11 * 11 = 121) +console.log(`Q: 104729 is prime? A: ${isPrime(104729)}`)// <--- true (104,729 is the 10,000th prime number!) + +// findPrimes TEST SUITE +// [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127] +console.log(`Q: what are the primes from 0 to 121?\nA: ${findPrimes(127)}`); +// console.log(`Q: what are the primes from 0 to 121?\nA: ${findPrimes(104729)}`); // <--- 10,000 prime numbers!!!! +console.log(findPrimes(104729).length); diff --git a/cc04largestPrimePalindrome/isPalindrome.js b/cc04largestPrimePalindrome/isPalindrome.js new file mode 100644 index 0000000..52ec4c5 --- /dev/null +++ b/cc04largestPrimePalindrome/isPalindrome.js @@ -0,0 +1,31 @@ +// I: any string NOTE: does NOT handle integers +// O: "true" if INPUT is a palindrome +function isPalindrome(str) { + // return true if string is a palindrome. + // otherwise return false + for (let i = 0; i < str.length / 2; i++) { // <--- make sure divided by 2 handles odd and even length (floor vs. ceiling) + if (str[i] === str[str.length - 1 - i]) { + return true; + } else { + return false; + } + } +} + +// I: a NUMBER +// O: a STRING +const numToStr = function(num) { + return `${num}`; +} + +// isPalindrome() TEST SUITE +console.log(`Q: Is 'palindrome' a palindrome? A: ${isPalindrome('palindrome')}`) // <-- false +console.log(`Q: Is ' ' a palindrome? A: ${isPalindrome(' ')}`) // <-- true +console.log(`Q: Is 'a' a palindrome? A: ${isPalindrome('a')}`) // <-- true +console.log(`Q: Is 'bb' a palindrome? A: ${isPalindrome('bb')}`) // <-- true +console.log(`Q: Is 'cdc' a palindrome? A: ${isPalindrome('cdc')}`) // <-- true +console.log(`Q: Is 'amanaplanacanalpanama' a palindrome? A: ${isPalindrome('amanaplanacanalpanama')}`) // <-- true +console.log(`Q: Is an integer a palindrome? A: ${isPalindrome(5)}`) // <-- undefined +// numToStr() test +console.log(`...might LOOK like a number: ${numToStr(5)} ...but it's a ${typeof numToStr(5)}`) // <--- '5' & string +console.log(`Q: Is the integer converted to a string? A: ${isPalindrome(numToStr(5))}`) // <-- true diff --git a/cc04largestPrimePalindrome/isPrime.js b/cc04largestPrimePalindrome/isPrime.js new file mode 100644 index 0000000..6b96d0d --- /dev/null +++ b/cc04largestPrimePalindrome/isPrime.js @@ -0,0 +1,35 @@ +// I: any integer +// O: "true" if INPUT is a prime number +const isPrime = function(num) { + // return true if num is prime. + // otherwise return false + if (num < 2) {return false;} + else if (num === 2) {return true;} + else if (num % 2 === 0) {return false;} + else if (num >= 3) { + for (var i = 2; i < Math.sqrt(num + 1); i++) { // Maybe a ceiling would work better (but slower?)? + if (num % i === 0) { + return false; + } + } + } return true; +} + +// isPrime TEST SUITE +// 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, +console.log(`Q: Is 0 prime? A: ${isPrime(0)}`) // <--- false +console.log(`Q: Is 1 prime? A: ${isPrime(1)}`) // <--- false +console.log(`Q: Is 2 prime? A: ${isPrime(2)}`) // <--- true +console.log(`Q: Is 3 prime? A: ${isPrime(3)}`) // <--- true +console.log(`Q: Is 4 prime? A: ${isPrime(4)}`) // <--- false +console.log(`Q: Is 5 prime? A: ${isPrime(5)}`) // <--- true +console.log(`Q: Is 6 prime? A: ${isPrime(6)}`) // <--- false +console.log(`Q: Is 7 prime? A: ${isPrime(7)}`) // <--- true +console.log(`Q: Is 8 prime? A: ${isPrime(8)}`) // <--- false +console.log(`Q: Is 9 prime? A: ${isPrime(9)}`) // <--- false +console.log(`Q: Is 10 prime? A: ${isPrime(10)}`) // <--- false +console.log(`Q: Is 11 prime? A: ${isPrime(11)}`) // <--- true +console.log(`Q: Is 12 prime? A: ${isPrime(12)}`) // <--- false +console.log(`Q: Is 13 prime? A: ${isPrime(13)}`) // <--- true +console.log(`Q: Is 121 prime? A: ${isPrime(121)}`) // <--- false (11 * 11 = 121) +console.log(`Q: Is 104729 prime? A: ${isPrime(104729)}`)// <--- true (104,729 is the 10,000th prime number!) diff --git a/cc04largestPrimePalindrome/largestPrimePalindrome.js b/cc04largestPrimePalindrome/largestPrimePalindrome.js new file mode 100644 index 0000000..b4fd5d1 --- /dev/null +++ b/cc04largestPrimePalindrome/largestPrimePalindrome.js @@ -0,0 +1,126 @@ +/* + * Create a function that returns the largest prime palindrome less than 1000. + * Hint: it's 929 + * You will first want to determine if the number is a palindrome and then determine if it is prime. + * A palindrome is a number that is the same forwards and backwards: 121, 323, 123454321, etc. + * Extra credit: Modify the function to look for the largest prime palindrome less than any provided number. + * Extra credit 2: How can you improve the time complexity? (Google: Sieve of Eratosthenes) + */ + +// returns largest prime palindrome +// I: end of range from 0 +// O: largest integer that is both prime and a palindrome +const largestPrimePalindrome = function(num) { + const x = findPrimePals(findPrimes(num)) + return x[x.length - 1]; +} + +// I: a sorted array of prime numbers, smallest to largest +// O: array of prime palindromes +const findPrimePals = function(primeArr) { + // console.log(primeArr); + const primePalsArr = [] + for (i = 0; i < primeArr.length; i++) { + if (isPalindrome(numToStr(primeArr[i]))) primePalsArr.push(numToStr(primeArr[i])) + } + return primePalsArr; +} + +// evaluates a range of natural numbers +// I: largest number in range (inclusive) +// O: an array of ALL prime #'s from range 0 thru INPUT integer +const findPrimes = function(bigNum) { + const primes = []; + // for number in range 0 thru *num + for (i = 0; i <=bigNum; i++) { + if (isPrime(i)) primes.push(i); + } + return primes; + } + +// I: any integer +// O: "true" if INPUT is a prime number +const isPrime = function(num) { + // return true if num is prime. + // otherwise return false + if (num < 2) {return false;} + else if (num === 2) {return true;} + else if (num % 2 === 0) {return false;} + else if (num >= 3) { + for (var i = 2; i < Math.sqrt(num + 1); i++) { // Maybe a ceiling would work better (but slower?)? + if (num % i === 0) { + return false; + } + } + } return true; +} + +// I: any string NOTE: does NOT handle integers +// O: "true" if INPUT is a palindrome +function isPalindrome(str) { + // return true if string is a palindrome. + // otherwise return false + for (let i = 0; i < str.length / 2; i++) { // <--- make sure divided by 2 handles odd and even length (floor vs. ceiling) + if (str[i] === str[str.length - 1 - i]) { + return true; + } else { + return false; + } + } +} + +// I: a NUMBER +// O: a STRING +const numToStr = function(num) { + return `${num}`; +} + +// // isPalindrome() TEST SUITE +// console.log(`Q: Is 'palindrome' a palindrome? A: ${isPalindrome('palindrome')}`) // <-- false +// console.log(`Q: Is ' ' a palindrome? A: ${isPalindrome(' ')}`) // <-- true +// console.log(`Q: Is 'a' a palindrome? A: ${isPalindrome('a')}`) // <-- true +// console.log(`Q: Is 'bb' a palindrome? A: ${isPalindrome('bb')}`) // <-- true +// console.log(`Q: Is 'cdc' a palindrome? A: ${isPalindrome('cdc')}`) // <-- true +// console.log(`Q: Is 'amanaplanacanalpanama' a palindrome? A: ${isPalindrome('amanaplanacanalpanama')}`) // <-- true +// console.log(`Q: Is an integer a palindrome? A: ${isPalindrome(5)}`) // <-- undefined + +// // numToStr() test +// console.log(numToStr(5)); // <--- '5' +// console.log(typeof numToStr(5)); // <--- string +// console.log(`Q: Is the integer converted to a string? A: ${isPalindrome(numToStr(5))}`) // <-- true + +// // isPrime TEST SUITE +// // 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, +// console.log(`Q: Is 0 prime? A: ${isPrime(0)}`) // <--- false +// console.log(`Q: Is 1 prime? A: ${isPrime(1)}`) // <--- false +// console.log(`Q: Is 2 prime? A: ${isPrime(2)}`) // <--- true +// console.log(`Q: Is 3 prime? A: ${isPrime(3)}`) // <--- true +// console.log(`Q: Is 4 prime? A: ${isPrime(4)}`) // <--- false +// console.log(`Q: Is 5 prime? A: ${isPrime(5)}`) // <--- true +// console.log(`Q: Is 6 prime? A: ${isPrime(6)}`) // <--- false +// console.log(`Q: Is 7 prime? A: ${isPrime(7)}`) // <--- true +// console.log(`Q: Is 8 prime? A: ${isPrime(8)}`) // <--- false +// console.log(`Q: Is 9 prime? A: ${isPrime(9)}`) // <--- false +// console.log(`Q: Is 10 prime? A: ${isPrime(10)}`) // <--- false +// console.log(`Q: Is 11 prime? A: ${isPrime(11)}`) // <--- true +// console.log(`Q: Is 12 prime? A: ${isPrime(12)}`) // <--- false +// console.log(`Q: Is 13 prime? A: ${isPrime(13)}`) // <--- true +// console.log(`Q: Is 121 prime? A: ${isPrime(121)}`) // <--- false (11 * 11 = 121) +// console.log(`Q: Is 104729 prime? A: ${isPrime(104729)}`)// <--- true (104,729 is the 10,000th prime number!) + +// // findPrimes TEST SUITE +// [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127] +// console.log(`Q: what are the primes from 0 to 127?\nA: ${findPrimes(127)}`); +// // console.log(`Q: what are the primes from 0 to 121?\nA: ${findPrimes(104729)}`); // <--- 10,000 prime numbers!!!! +// console.log(`Q: How many prime numbers between zero and 104,729?\nA: ${findPrimes(104729).length}`); + +// // findPrimePals TEST SUITE +// // [11, 101, ...] +// console.log(`Q: Is findPrimePals(findPrimes(127)) an instance of an array?\nA: ${findPrimePals(findPrimes(127)) instanceof Array}`); // <--- true +// console.log(`Q: what are the prime palindromes from 0 to 127?\nA: ${findPrimePals(findPrimes(127))}`); // <--- 2,3,5,7,11,101 +// console.log(`Q: what are the prime palindromes from 0 to 1000?\nA: ${findPrimePals(findPrimes(1000))}`); // <--- 2,3,5,7,11,101,131,151,181,191,313,353,373,383,727,757,787,797,919,929 + +// largestPrimePalindrome TEST SUITE +console.log(`Q: What is the largest prime palindrome less than 1000?\nA: ${largestPrimePalindrome(1000)}`); + +// THIS COULD< OF COURSE< BE SIGNIFICANTLY REFACTORED... diff --git a/cc04largestPrimePalindrome/ryan_solution.js b/cc04largestPrimePalindrome/ryan_solution.js new file mode 100644 index 0000000..786d8a5 --- /dev/null +++ b/cc04largestPrimePalindrome/ryan_solution.js @@ -0,0 +1,27 @@ +// from the lecture video: https://youtu.be/F0y2sJHQzzs +const largestPrimePalindrome = (number) => { + + const palindromeChecker = (number) => { + const strNum = number.toString(); + const reversedStrNum = strNum.split('').reverse().join(''); + if (strNum == reversedStrNum) return true; // <--- NOTE THE USE OF "==" (NOT "==="): COERCION + // if (strNum === Number(reversedStrNum)) return true; + return false; + }; + + const primeChecker = (num) => { + const squareRoot = Math.sqrt(num); + if (num % 2 === 0) return false; + for(let i = 3; i <= squareRoot; i += 2) { + if (num % i === 0) return false; + } + return true; + }; + + // COUNTING DOWN FROM LARGEST IS MUCH MUCH MUCH FASTER + for (let num = 1000; num >= 11; num--) + if( palindromeChecker(num) && primeChecker(num) ) return num; + +}; + +console.log(largestPrimePalindrome()); diff --git a/cc05evenOccurences/evenOccurences.js b/cc05evenOccurences/evenOccurences.js new file mode 100644 index 0000000..d47be7a --- /dev/null +++ b/cc05evenOccurences/evenOccurences.js @@ -0,0 +1,113 @@ +/* +* Find the first item that occurs an even number of times in an array. + * Remember to handle multiple even-occurance items and return the first one. + * Return null if there are no even-occurance items. +* example usage: + * const onlyEven = evenOccurence([1, 7, 2, 4, 5, 1, 6, 8, 9, 6, 4, 1]); + * console.log(onlyEven); // 4 + */ + +// VERSION 2 √ ...from 50+ lines of code to 13 :) +const evenOccurence = (arr) => { + const unique = [...new Set(arr)]; // <---------- Will Set maintain list order????? Also, still not used to spread operator. + let count = 0; + for (i in unique) { + count = 0; + for (j in arr) { + if (unique[i] === arr[j]) { + count++; + } + } + if (count % 2 === 0) return unique[i]; + } + return null; +}; +// // VERSION 1 √ +// // I: array +// // F(): if isUnique is false, then return null, then check total number of times +// // item is in array, %2 === 0 dun, or check next until null +// // O: array item - first instance of item which occurs even # of times in array +// const evenOccurence = (arr) => { +// arr; +// +// // I: array +// // O: if (isUnique(anArray)) ? 1st unique array item : null +// const isUnique = (anArray) => { +// if (anArray === null) return null; +// for (let i = 0; i < anArray.length; i++) { +// for (let j = i + 1; j < anArray.length; j++) { +// if (anArray[i] === anArray[j]) { +// return anArray[i]; +// } +// } +// } return null; +// }; +// +// // I: array +// // O: 1st item that occurs an even number of times in an array +// const countNotUnique = (item, anArrayOfItems) => { +// if (item === null) /* console.log(`That's some kinda ${item} item`); */ return null; +// if (anArrayOfItems === null) console.log(`That's some kinda ${anArrayOfItems} anArrayOfItems array there`); // return null; +// const hold = []; +// if (!isUnique(item)) { +// for (let i = 0; i < anArrayOfItems.length; i++) { +// if (anArrayOfItems[i] === item) { +// hold.push(item); +// } +// } +// } +// return hold; +// } +// +// const oddOrEven = (dupesArray) => { +// const minusOddDupe = []; +// if (dupesArray === null) return null; +// const count = dupesArray.length; +// if (count === 0) { +// return null; +// } else if (count % 2 !== 0) { +// for (let i = 0; i < arr.length; i++) { +// if (dupesArray[0] !== arr[i]) { +// minusOddDupe.push(arr[i]); +// } +// } +// return evenOccurence(minusOddDupe); // <--------- LOOK MA, RECURSION!!!!! +// } +// return dupesArray[0]; +// } +// +// return oddOrEven(countNotUnique(isUnique(arr), arr)); +// }; +// +// // evenOccurence TEST SUITE: +// // evenOccurence(); +// console.log(`Invoking evenOccurence([1, 7, 2, 4, 5, 1, 6, 8, 9, 6, 4, 1])} returns the repeated integer: ${evenOccurence([1, 7, 2, 4, 5, 1, 6, 8, 9, 6, 4, 1])}`); +// evenOccurence([5, 1, 1, 1, 1]); // <------------------------ 1 x4 >>> 1 +// evenOccurence([1, 2, 3]) // <------------------------------- null +// evenOccurence([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); // <----- null +// evenOccurence([5, 1, 1, 1, 6, 1, 1]); // <--------- 1 x5 >>> null +// evenOccurence([1, 7, 2, 4, 5, 1, 6, 8, 9, 6, 4, 1]); // <--- 4 x2 >>> 4 +// +// const onlyEven = evenOccurence([1, 7, 2, 4, 5, 1, 6, 8, 9, 6, 4, 1]); +// console.log(onlyEven); // <--- 4 +// const onlyEven2 = evenOccurence([ 1, 7, 2, 4, 5, 6, 8, 9 ]); +// console.log(onlyEven2); // <--- null +// const onlyEven3 = evenOccurence([ 1, 3, 3, 3, 5, 5, 5, 5, 5 ]); +// console.log(onlyEven3); // <--- null + +// // Tai's solution +// const evenOccurence = (arr) => { +// // Your code here. +// const obj = {}; +// let first; +// arr.forEach((item) => { +// if (obj[item] === undefined) return obj[item] = 1; +// if (obj[item] === 1) return obj[item] = 2; +// if (obj[item] === 2) return obj[item] = 1; +// }); +// arr.forEach((item) => { +// if(obj[item] === 2 && first === undefined) first = item; +// }); +// if (first) return first; +// return null; +// }; diff --git a/callbackPractice/callbackPractice.js b/cc06callbackPractice/callbackPractice.js similarity index 69% rename from callbackPractice/callbackPractice.js rename to cc06callbackPractice/callbackPractice.js index 931c19d..1d7b97e 100644 --- a/callbackPractice/callbackPractice.js +++ b/cc06callbackPractice/callbackPractice.js @@ -15,8 +15,21 @@ * */ - // Write a function called firstItem that passes the first item of the given array to the callback function +// version 1 √ +const firstItem = (array, cb) => { + cb(array[0]) +} + +// // version 2 √ +// const firstItem = (array, cb) => { +// x = array.shift(); // <--- degrades the array +// console.log(x); +// } +// version 3 √ +// const firstItem = (array, cb) => { +// console.log(array.shift()); // <--- degrades the array +// } const foods = ['pineapple', 'mango', 'ribeye', 'curry', 'tacos', 'ribeye', 'mango']; @@ -25,25 +38,40 @@ firstItem(foods, (firstItem) => { }); // Write a function called getLength that passes the length of the array into the callback +// version 1 √ +const getLength = (anArray, cb) => { + cb(anArray.length); +} getLength(foods, (length) => { console.log(`The length of the array is ${length}.`); }); // Write a function called last which passes the last item of the array into the callback +// version 1 √ +const last = (theArray, cb) => { + cb(theArray[theArray.length - 1]) +} last(foods, (lastItem) => { console.log(`The last item in the array is ${lastItem}.`); }); // Write a function called sumNums that adds two numbers and passes the result to the callback - +// version 1 √ +const sumNums = (x, y, cb) => { + cb(x + y); +} sumNums(5, 10, (sum) => { console.log(`The sum is ${sum}.`); }); // Write a function called multiplyNums that adds two numbers and passes the result to the callback +// version 1 √ +const multiplyNums = (x, y, cb) => { + cb( x * y); +} multiplyNums(5, 10, (product) => { console.log(`The product is ${product}.`); @@ -51,6 +79,10 @@ multiplyNums(5, 10, (product) => { // Write a function called contains that checks if an item is present inside of the given array. // Pass true to the callback if it is, otherwise pass false +// version 1 √ +const contains = (array, str, cb) => { + cb(array.includes(str)); +} contains(foods, 'ribeye', (result) => { console.log(result ? 'ribeye is in the array' : 'ribeye is not in the array'); @@ -58,12 +90,22 @@ contains(foods, 'ribeye', (result) => { // Write a function called removeDuplicates that removes all duplicate values from the given array. // Pass the array to the callback function. Do not mutate the original array. +// version 1 √ +const removeDuplicates = (array, cb) => { + cb(Array.from(new Set(array))); +} removeDuplicates(foods, (uniqueFoods) => { console.log(`foods with duplicates removed: ${uniqueFoods}`); }); // Write a function called forEach that iterates over the provided array and passes the value and index into the callback. +// version 1 √ +const forEach = (array, cb) => { + for (let i = 0; i < array.length; i++) { + cb(array[i], i); + } +} forEach(foods, (value, index) => { console.log(`${value} is at index ${index}.`); diff --git a/cc06callbackPractice/callbackPractice_Coding_Challenge_Review_Lecture_Notes.js b/cc06callbackPractice/callbackPractice_Coding_Challenge_Review_Lecture_Notes.js new file mode 100644 index 0000000..0499faf --- /dev/null +++ b/cc06callbackPractice/callbackPractice_Coding_Challenge_Review_Lecture_Notes.js @@ -0,0 +1,117 @@ +/* For today's coding challenge your job is to write functions + * so that each function call works. + * + * Example: + * + * greeting('Hey guys', (message) => { + * console.log(message); + * }); + * + * You would then define the greeting function to make the + * invocation work. + * + * const greeting = (str, cb) => { + * cb(str); + * }; + * +*/ + + +// Write a function called firstItem that passes the first item of the given +// array to the callback function + +const foods = ['pineapple', 'mango', 'ribeye', 'curry', 'tacos', 'ribeye', 'mango']; + +const firstItem = (arr, cb) => { + cb(arr[0]); +}; + +firstItem(foods, (firstItem) => { + console.log(`The first item is ${firstItem}.`); +}); + +// Write a function called getLength that passes the length of the array into +// the callback +const getLength = (arr, cb) => { + cb(arr.length); +}; + +getLength(foods, (length) => { + console.log(`The length of the array is ${length}.`); +}); + +// Write a function called last which passes the last item of the array into +// the callback +const last = (arr, cb) => { + cb(arr[arr.length - 1]); +}; + +last(foods, (lastItem) => { + console.log(`The last item in the array is ${lastItem}.`); +}); + +// Write a function called sumNums that adds two numbers and passes the result +// to the callback + +const sumNums = (x, y, cb) => { + cb(x + y); +}; + +sumNums(5, 10, (sum) => { + console.log(`The sum is ${sum}.`); +}); + +// Write a function called multiplyNums that adds two numbers and passes the +// result to the callback + +const multiplyNums = (x, y, cb) => { + cb(x * y); +}; + +multiplyNums(5, 10, (product) => { + console.log(`The product is ${product}.`); +}); + +// foods = ['pineapple', 'mango', 'ribeye', 'curry', 'tacos', 'ribeye', 'mango']; + +// Write a function called contains that checks if an item is present inside +// of the given array. Pass true to the callback if it is, otherwise pass false + +const contains = (arr, str, cb) => { + cb((arr.indexOf(str) >= 0)); +}; + +contains(foods, 'ribeye', (result) => { + console.log(result ? 'ribeye is in the array' : 'ribeye is not in the array'); +}); + +// Write a function called removeDuplicates that removes all duplicate values +// from the given array. Pass the array to the callback function. +// Do not mutate the original array. +const removeDuplicates = (arr, cb) => { + const obj = {}; + const newArr = []; + arr.forEach((item) => { + if (!obj[item]) { + obj[item] = true; + newArr.push(item); + } + }); + cb(newArr); +}; +removeDuplicates(foods, (uniqueFoods) => { + console.log(`foods with duplicates removed: ${uniqueFoods}`); +}); + +// Write a function called forEach that iterates over the provided array and +// passes the value and index into the callback. + +const forEach = (arr, cb) => { + for (let i = 0; i < arr.length; i++) { + cb(arr[i], i); + } +}; + +forEach(foods, (value, index) => { + console.log(`${value} is at index ${index}.`); +}); diff --git a/cc07forLoopTimeout/forLoopTimeout.js b/cc07forLoopTimeout/forLoopTimeout.js new file mode 100644 index 0000000..02dcb84 --- /dev/null +++ b/cc07forLoopTimeout/forLoopTimeout.js @@ -0,0 +1,33 @@ +// Explain what is wrong with this code and how you would fix this. + + /* As I understand it, `var` and `let` use different scoping. + I'm not sure why `var` returns 11 each time, but I am imagining + that the execution of the internal code block - the console.log() - + is executed AFTER the iteration, therefore, when the code is evaluated + the var value is set to the final pass through the iteration, === 11. + The `let` scoping, on the other hand, is constrained within the code block and + established per each iteration evaluating the console.log() contents. */ + +// With ES6 there is a very, very simple way to solve this. +// See if you can solve this with just ES5 JS. +// The output should be 1, 2, 3, .... 10. Right now it just prints 11. +// I've been asked this three times in separate interviews. + +// // ES6 solution √ +// for (let i = 1; i <= 10; i++) { +// setTimeout(function() { +// console.log(i); +// }, 0); +// } + +// ES5 solution √ +for (var i = 1; i <= 10; i++) { + var anonymousFunctionWrapper = function (x) { + return setTimeout(function() { console.log(x); }, 0); + } + anonymousFunctionWrapper(i); +} + +// for (var i = 1; i <= 10; i++) { +// console.log(i); +// } diff --git a/cc08binarySearch/binarySearch.js b/cc08binarySearch/binarySearch.js new file mode 100644 index 0000000..3113cef --- /dev/null +++ b/cc08binarySearch/binarySearch.js @@ -0,0 +1,58 @@ +/* + * Given a sorted array, find the index of the specified element + * using binary search. + * https://www.khanacademy.org/computing/computer-science/algorithms/binary-search/a/binary-search + * https://en.wikipedia.org/wiki/Binary_search_algorithm + * */ + +/** + * * const index = binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2); + * * console.log(index); // 1 +**/ + +// // version 1: indexOf (gets the job done, but misses the point entirely) +// const binarySearch = (nums, target) => { +// return nums.indexOf(target); +// }; + +// version 2: Divide and Conquer √ + +// I: A SORTED array (low to high) of integers AND a target number +// O: the array index of the target + // we are presuming the array actually contains target + +/* FUNCTION: + * We know the target is at one of the array indexes. Take the average of min & max range, divide by half + * If target number at that index, return index # + * Is the value at that index less than the target? Then increase the minimum to the guess index position + 1 + * Is the value at that index greater than the target? Then decrease the maximum to the guess index position - 1 +*/ + +const binarySearch = (nums, target) => { + if (nums.length < 1) return "Error001: empty array"; + if (nums.indexOf(target) === -1) return "Error002: target number not in array"; + let min = 0; + let max = nums.length - 1; + let guess; + while (min <= max) { + guess = Math.floor((min + max) / 2); + if (nums[guess] === target) { return guess } + else if (nums[guess] < target) { min = guess + 1 } + else { max = guess - 1 } + } +}; + +// // TEST SUITE +console.log(`\nErr Test: ${binarySearch([], 20)}\n`); // ---> Error001 +console.log(`Err Test: ${binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0)}\n`); // ---> Error002 +console.log(`Test #1: ${binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 1)}\n`); +console.log(`Test #2: ${binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2)}\n`); +console.log(`Test #3: ${binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3)}\n`); +console.log(`Test #4: ${binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 4)}\n`); +console.log(`Test #5: ${binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5)}\n`); +console.log(`Test #6: ${binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 6)}\n`); +console.log(`Test #7: ${binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 7)}\n`); +console.log(`Test #8: ${binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 8)}\n`); +console.log(`Test #9: ${binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 9)}\n`); +console.log(`Test #10:${binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10)}\n`); +console.log(`Err Test:${binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 11)}\n`); // ---> Error002 diff --git a/brainTeasers/waterJugs.md b/cc09brainTeasers/waterJugs.md similarity index 60% rename from brainTeasers/waterJugs.md rename to cc09brainTeasers/waterJugs.md index 5787394..c285c65 100644 --- a/brainTeasers/waterJugs.md +++ b/cc09brainTeasers/waterJugs.md @@ -1,3 +1,10 @@ You have a five-quart jug, a three-quart jug, and an unlimited supply of water (but no measuring cups). How would you come up with exactly four quarts of water? Note that the jugs are oddly shaped, such that filling up exactly "half" of the jug would be impossible. + +1. Fill the 5gb +2. Pour from 5gb into 3gb - remainder 2g in 5gb +3. Empty 3gb +4. pour the 2g in 5gb into 3gb +5. fill 5gb +6. pour 1g from 5gb into 3gb - remainder 4g in 5gb. diff --git a/cc10array/array.js b/cc10array/array.js new file mode 100644 index 0000000..6242284 --- /dev/null +++ b/cc10array/array.js @@ -0,0 +1,119 @@ +/* cc10 array + * Make a class called Array. + * It should have the methods push, pop, get(index), and delete(index). + * get and delete should accept an index and get or remove the item at that index. + * Make sure to shift the array items after deleting an item. + * In your implementation use a JS object to build the array. + * Do NOT use an array as the underlying data structure, that's cheating :) + * How do these operations compare to that of a linked list? + * How does the time complexity of insertion and deletion compare to that of a linked list? + */ + +/* class Array() to construct an object such that key: value pairs are arranged + { index: item, index: item, index: item, ... index: item }, e.g. + {0: 'first item', 1: 'second item', 2: 'third item', ... (n-1): 'last item' } +*/ + +class ObjArray { + // starts empty + // todo: set up Array class so it can take initializing value(s), e.g. `Array(...args)` + constructor() { + this.nextIndex = 0; + this.listObject = {}; + } + // CONVENTION: INCLUDE A LENGTH PROPERTY + + // todo: push(...args) + push(addItem) { + this.listObject[this.nextIndex] = addItem; + this.nextIndex++; + } + // CONVENTION: RETURN THE VALUE WHICH HAS BEEN DELETED + + // todo: pop(#) to invoke push() # of times or from a index to the end + pop() { + this.nextIndex--; + delete this.listObject[this.nextIndex]; + } + + // todo: get(...args) + get(isIndex) { + if (!this.listObject[isIndex]) return 'nope'; + return this.listObject[isIndex]; + } + + // delete value at Key# (i.e. array "index"), then replace Key[n] with value at Key[n+1] + // use current this.nextIndex (or last existing index?) to exit the shifting? + // set nextIndex to last Key# + // todo: delete(indexRange)? + delete(indexValue) { + this.listObject[indexValue] = ''; + while (indexValue < this.nextIndex) { + this.listObject[indexValue] = this.listObject[indexValue + 1]; + indexValue++; + } + this.nextIndex = indexValue - 1; + } + + // Helper functions + getAllValues() { + return Object.values(this.listObject); + } + getAllKeys() { + return Object.keys(this.listObject); + } + getAllKeysAndValues() { + return this.listObject; + } +} + +/* eslint no-console:0 */ +// TEST SUITE +const test = new ObjArray(); +console.log('TEST# 1 - ObjArray() instance contains:', test); +// console.log(`TEST#1A - Array() instance contains: ${test}`); // ---> :( +test.push('chzbrgr'); +console.log('TEST# 2 - ObjArray() instance contains:', test); +test.push('salad'); +console.log('TEST# 3 - ObjArray() instance contains:', test); +test.push('iced tea'); +console.log('TEST# 4 - ObjArray() instance contains:', test); +console.log(`TEST# 5: Q: to eat? A: ${test.get(0)}`); +console.log(`TEST# 6: Q: a side? A: ${test.get(1)}`); +console.log(`TEST# 7: Q: to drink? A: ${test.get(2)}`); +console.log(`TEST# 8: Q: want some sodaPOP? A: ${test.get(3)}`); +test.pop(); +console.log(`TEST# 9: Q: just water then? A: ${test.get(2)}`); +console.log(`TEST#10: Q: what's for dinner?\nA: ${test.getAllValues()}`); +test.push('this'); +test.push('that'); +test.push('the other thing'); +test.push('something'); +test.push('another thing'); +test.push('aaaaand another thing'); +console.log(`TEST#11: Q: what all's in there?\nA: ${test.getAllValues()}`); +console.log(`TEST#12: Q: what all's where in there?\nA: ${test.getAllKeys()}`); +console.log(`TEST#13: Q: which what all's where in there?\nA: ${test.getAllKeysAndValues()}`); // <---- how to get the object printed and not the type? JSON.stringify() +console.log(test.getAllKeysAndValues()); +test.delete(5); +console.log(`TEST#14: Q: did "something" get deleted?\nA: ${test.getAllKeysAndValues()}`); +console.log(test.getAllKeysAndValues()); +console.log(`TEST#15: Q: What's the index set to?\nA: The next index location is: ${test.nextIndex}`); +test.push('well lookie thar!'); +console.log(`TEST#16: Q: Did I add it to the right place?\nA: ${test.getAllKeysAndValues()}`); +console.log(test.getAllKeysAndValues()); +test.push('more stuff!'); +console.log(`TEST#17: Q: Wanna add some more stuff?\nA: ${test.getAllKeysAndValues()}`); +console.log(test.getAllKeysAndValues()); +test.delete(1); +test.delete(3); +test.delete(5); +console.log(`TEST#18: Q: What just happened???\nA: ${test.getAllKeysAndValues()}`); +console.log(test.getAllKeysAndValues()); +test.push('even more stuff!'); +test.push('so much stuff!'); +test.push('and even more stuff!'); +test.push('never ending stuff!!!'); +console.log(`TEST#17: Q: Wanna add some more stuff?\nA: ${test.getAllKeysAndValues()}`); +console.log(test.getAllKeysAndValues()); +console.log(`Q: easier to read?\nA: ${JSON.stringify(test.getAllKeysAndValues())}`); diff --git a/cc10array/sean_array.js b/cc10array/sean_array.js new file mode 100644 index 0000000..54d808e --- /dev/null +++ b/cc10array/sean_array.js @@ -0,0 +1,31 @@ +class ObjArray { + constructor() { + this.storage = {}; + this.length = 0; + } + + get(index) { + return this.storage[index]; + } + + delete(index) { + delete this.storage[index]; + for (let i = index; i <= this.length; i++) { + this.storage[i] = this.storage[i + 1]; + } + this.length--; + } + + push(element) { + this.storage[this.length] = element; + this.length++; + } + + pop() { + const lastIndex = this.length - 1; + const valueToReturn = this.storage[lastIndex]; + delete this.storage[lastIndex]; + this.length--; + return valueToReturn; + } +} diff --git a/cc11stringCompression/stringCompression.js b/cc11stringCompression/stringCompression.js new file mode 100644 index 0000000..1503c0b --- /dev/null +++ b/cc11stringCompression/stringCompression.js @@ -0,0 +1,41 @@ +// String Compression: Implement a method to perform basic string compression using +// the counts of repeated characters. +// For example, the string aabcccccaaa would become a2b1c5a3. +// If the "compressed" string would not become smaller than the original string, +// your method should return the original string. +// You can assume the string has only uppercase and lowercase letters (a - z). + +/* eslint no-console: 0 */ + +const compressor = function(str) { + // is there a simple check prevent the algorithm from running + // if it would make a longer string? Seems like not having to + // calculate the algorithm first to then evaluate if it + // made the string longer would make for a much better + // Order of Complexity...? + + // compression algorithm + const arr = []; + let count = 1; + for (let i = 0; i < str.length; i++) { + if (str[i] === str[i + 1]) { + count++; + } else if ((str[i] != str[i + 1])) { + arr.push(`${str[i]}${count}`); + count = 1; + } + } + const compressed = arr.join(''); + // // return original string if compressing made a longer string + // if (str.length <= compressed.length) return `inadequate algorithm`; + // return compressed; + // ternary + return str.length <= compressed.length ? str : compressed; +}; + +// TEST SUITE +const test = compressor('aabcccccaaa'); // ---> a2b1c5a3 +console.log(test); +console.log(compressor('abca')); // ---> abca: inadequate compression algorithm +console.log(compressor('aabbcc')); // ---> aabbcc: inadequate compression algorithm +console.log(compressor('aabbccc')); // ---> a2b2c3 diff --git a/cc12operators/Tai_solution.js b/cc12operators/Tai_solution.js new file mode 100644 index 0000000..6d0a7dd --- /dev/null +++ b/cc12operators/Tai_solution.js @@ -0,0 +1,51 @@ +/* + * Implement three functions called multiply, divide, and modulo. + * These functions should multiply, divide, or return the remainder of two arguments. + * Now for the tricky part: you can only use the + and - operators to implement these functions. + * For division just drop the remainder. + */ + +const multiply = (x, y) => { + const absX = x < 0 ? 0 - x: x; + const absY = y < 0 ? 0 - y: y; + let product = 0; + for (let i = 0; i < absX; i++) product += absY; + if (x < 0 && y < 0) return product; + if (x < 0 || y < 0) return 0 - product; + return product; +}; + +const divide = (x, y) => { + if (y === 0) return NaN; + let absX = x < 0 ? 0 - x: x; + let absY = y < 0 ? 0 - y: y; + let quotient = 0; + while (absX > 0) { + absX -= absY; + if (absX >= 0) quotient += 1; + } + if (x < 0 && y < 0) return quotient; + if (x < 0 || y < 0) return 0 - quotient; + return quotient; +}; + +const modulo = (x, y) => { + if (y === 0) return NaN; + let absX = x < 0 ? 0 - x: x; + let absY = y < 0 ? 0 - y: y; + while (absX >= absY) absX -= absY; + if (x < 0 || y < 0) return 0 - absX; + return absX; +}; + +console.log(multiply(15, 10)); // 150 +console.log(multiply(15, 0)); // 0 +console.log(multiply(-15, 10)); // -150 +console.log(multiply(-15, -10)); // 150 +console.log(divide(15, 5)); // 3 +console.log(divide(15, 0)); // NaN +console.log(modulo(15, 0)); // NaN +console.log(modulo(15, 7)); // 1 +console.log(modulo(15, -7)); // -1 +console.log(modulo(-15, 7)); // -1 +console.log(modulo(-15, -7)); // 1 diff --git a/cc12operators/operators.js b/cc12operators/operators.js new file mode 100644 index 0000000..67b7232 --- /dev/null +++ b/cc12operators/operators.js @@ -0,0 +1,110 @@ +/* + * Implement three functions called multiply, divide, and modulo. + * These functions should multiply, divide, or return the remainder of two arguments. + * Now for the tricky part: you can only use the + and - operators to implement these functions. + * For division just drop the remainder. + */ + +// Edge cases: multiply by zero +// divide by zero +// negative input numbers + +const multiply = function(a, b) { + const arr = new Array(b).fill(a); + console.log(arr); + const product = arr.reduce((a, b) => a + b); + // const product = arr.reduce((a, b) => a + b, 0); // 0 is an initial value + console.log(product); + return product; +}; + +const divide = function(x, y) { + let count = 0; + while (x - y >= 0) { + x -= y; + count++; + } + return `${count} remainder ${x}`; +}; + +const modulo = function(phi, psi) { + let count = 0; + while (phi - psi >= 0) { + phi -= psi; + count++; + } + return phi; +}; + + +// TEST SUITE +// multiplication +console.log(multiply(2, 10)); // ---> 20 +// console.log(multiply(1, 1)); // ---> 1 +// console.log(multiply(113, 17)); // ---> 1921 +// console.log(multiply(21, 0)); // --> 0 BUT .reduce needs and initial value +// console.log(multiply(-21, 1)); // --> -21 +// console.log(multiply(21, -1)); // --> error +// console.log(multiply(-21, -3)); // --> error + +// division +console.log(divide(121, 11)); // ---> 11 remainder 0 +console.log(divide(123, 11)); // ---> 11 remainder 2 + +// modulo +console.log(modulo(15000, 11)); // ---> 7 +console.log(modulo(123, 11)); // ---> 2 + + +// // Model solution +// function negCheck (num1, num2) { +// const arr = [0]; +// if (num1 < 0) { +// arr[0] += 1; +// arr.push(0 - num1); +// } else { +// arr.push(num1); +// } +// if (num2 < 0) { +// arr[0] += 1; +// arr.push(0 - num2); +// } else { +// arr.push(num2); +// } +// return arr; +// } +// +// console.log(negCheck(-3, -5)); +// +// +// function multiply(x, y) { +// const arr = negCheck(x, y); +// let answer = 0; +// for (var i = 0; i < arr[2]; i++) { +// answer += arr[1]; +// } +// if (arr[0] % 2 === 1) answer = 0 - answer; +// return answer; +// } +// +// function divide(x, y) { +// const arr = negCheck(x, y); +// let remainder = arr[1]; +// let answer = 0; +// while(remainder >= arr[2]) { +// answer += 1; +// remainder -= arr[2]; +// } +// if (arr[0] % 2 === 1) answer = 0 - answer; +// return answer; +// } +// +// function modulo(x, y) { +// const arr = negCheck(x, y); +// let remainder = arr[1]; +// while(remainder >= arr[2]) { +// remainder -= arr[2]; +// } +// if (x < 0) return (0 - remainder); +// return remainder; +// } diff --git a/cc13constructors/constructors.js b/cc13constructors/constructors.js new file mode 100644 index 0000000..ca50a47 --- /dev/null +++ b/cc13constructors/constructors.js @@ -0,0 +1,132 @@ + +/* Design several classes and their relationships for an RPG videogame. + * Classes: + * NPC -> Humanoid, Animal, Plant + * Humanoid -> Human, Elf, Orc + * Animal -> Bear, Wolf + * Plant -> FleshEatingDaisy + * + * Human -> Soldier, Peasant, Bandit + * + * NPC should be a general class for a non-player character in the game. + * This class will probably include general attributes like hp, strength, speed, etc. + * + * Humanoid, Animal, and Plant should all inherit from NPC. The classes + * shown to the right of the arrow are classes that will inherit + * from those classes. + * + * Soldier, Peasant, and Bandit should all inherit from Human. + * + * Create properties for these different classes that fit with the character. + * + * This is how you would structure the game objects in an actual game + * application in Unity or another similar framework. + */ + +class NPC { + constructor(props) { + this.state = { + name: props, + weapon: '', + health: '', + strength: '', + _level: 1, // <--- private? Only the DM can establish characters above level 1 + } + } +}; +// * NPC -> Humanoid, Animal, Plant +class Humanoid extends NPC { + constructor(props) { + super(props); + this.state.languages = []; + this.state.armor = ''; + this.state.numberOfShoes = 2; + } +}; +class Animal extends NPC { + constructor(props) { + super(props); + this.state.claws = true; + this.state.magic = false; + } +} +class Plant extends NPC { + constructor(props) { + super(props); + this.state.medicinal = true; + this.state.poisonous = true; + this.state.edible = false; + } +} +// * Humanoid -> Human, Elf, Orc +class Human extends Humanoid { // Human props relative to roll of dice + constructor(props) { + super(props); + this.state.health = Math.floor(Math.random() * 100); + this.state.strength = Math.floor(Math.random() * 100); + this.state.languages = ['common']; + } +} +class Elf extends Humanoid { + constructor(props) { + super(props); + this.state.languages.push('common', 'elvish'); // not sure which is a better way...? maybe an object instead w/fluent/literate/illiterate/rudimentary/etc? + } +} +class Orc extends Humanoid { + constructor(props) { + super(props); + this.state.languages = ['orcish']; + } +} +// * Animal -> Bear, Wolf +class Bear extends Animal { + constructor(props) { + super(props); + this.state.height = {feet: 6, inches: 6}; + } +} +class Wolf extends Animal { + constructor(props) { + super(props); + this.state.packStatus = {alpha: false, beta: true, omega: false}; + } +} +// * Plant -> FleshEatingDaisy +class FleshEatingDaisy extends Plant{ + constructor(props) { + super(props); + this.state.odor = {delightful: false, deadly: false, pernicious: true}; + } +} + +// TEST SUITE +const npc = new NPC('first'); +console.log(npc); + +const zarthonFleven = new Humanoid('Zarthon Fleven'); +console.log(zarthonFleven); + +const ladyBug = new Animal('Sir Ladybug'); +console.log(ladyBug); + +const sunFlower = new Plant('Sun Flower'); +console.log(sunFlower); + +const bob = new Human('Bob'); +console.log(bob); + +const velaria = new Elf('Velaria'); +console.log(velaria); + +const graarg = new Orc('Graarg'); +console.log(graarg); + +const paul = new Bear('Paul'); +console.log(paul); + +const simonLeBon = new Wolf('Simon Le Bon'); +console.log(simonLeBon); + +const foofie = new FleshEatingDaisy('Foofie the Flesh Eating Daisy'); +console.log(foofie); diff --git a/cc14queueStack/queueStack.js b/cc14queueStack/queueStack.js new file mode 100644 index 0000000..ab39e72 --- /dev/null +++ b/cc14queueStack/queueStack.js @@ -0,0 +1,86 @@ +/** + * Write a stack class. Once you're done, + * implement a queue using two stacks. + Stack=(Last In First Out) & Queue=(First In First Out) +*/ +class PhatStack { + constructor() { + this.storage = []; + } + get size() { return this.storage.length } + set add(anItem) { this.storage.push(anItem) } // <---------- USING THE SETTER + remove() { return this.storage.pop() } + get show() { return this.storage } +} + +class TwoStackQueueKungFu { + constructor() { + this.input = new PhatStack(); + this.output = new PhatStack(); + } + set enqueue(something) {this.input.add = something} + + dequeue() { + if (this.output.size === 0) { + while (this.input.size) { + this.output.storage.push(this.input.storage.pop()); // <---- THIS WORKS + // // WHY DOES CALLING THE PhatStack Setter Method NOT WORK? ////////// + // // Error msg: "this.output.add is not a function" + // this.output.add(this.input.remove()); // <--- Setter method syntax + } + } + console.log(testq.output.storage); + return this.output.storage.pop(); + }; + + get showOutput() { return this.output.storage } +} + +// // QUEUE W/2 STACKS TEST SUITE +// const testq = new TwoStackQueueKungFu(); +// console.log(testq); // ---> TwoStackQueueKungFu { storage: [] } +// testq.enqueue = 'not'; +// testq.enqueue = 'first'; +// testq.enqueue = 'in'; +// testq.enqueue = 'last'; +// testq.enqueue = 'out'; +// console.log(testq); // ---> [ 'not', 'first', 'in', 'last', 'out' ] +// // console.log(testq.show); +// console.log(testq.dequeue()); // ---> not +// console.log(testq.dequeue()); // ---> first +// console.log(testq.dequeue()); // ---> in +// console.log(testq.dequeue()); // ---> last +// console.log(testq.dequeue()); // ---> out +// console.log(testq); // ---> input and output: [] +// testq.enqueue = 'first'; +// testq.enqueue = 'in'; +// testq.enqueue = 'first'; +// testq.enqueue = 'out'; +// console.log(testq); // ---> [ 'first', 'in', 'first', 'out' ] +// console.log(testq.dequeue()); // ---> first +// console.log(testq.dequeue()); // ---> in +// console.log(testq.dequeue()); // ---> first +// console.log(testq.dequeue()); // ---> out +// console.log(testq); // ---> + + +// // STACK TEST SUITE +// const test = new PhatStack(); // a new instance of the class +// console.log(test); // ---> PhatStack { storage: [] } +// console.log(test.size); // ---> 0 ...or, without "get" ---> [Function: size] +// // console.log(test.size()); // ---> TypeError ...or, without "get" ---> 0 +// // test.add('stuff'); // add an item without setter +// test.add = 'stuff'; +// console.log(test.size); // ---> 1 +// console.log(test.show); // ---> [ 'stuff' ] +// console.log(test.storage); // ---> [ 'stuff' ] SAME +// console.log(test.remove()); // ---> stuff (returns the removed item) +// console.log(test.size); // ---> 0 +// console.log(test.show); // ---> [] +// console.log(test.remove()); // ---> undefined (nothing to remove from an empty storage array) +// console.log(test.size); // ---> 0 +// console.log(test.show); // ---> [] +// test.add = 'more stuff' +// test.add = 'even more stuff' +// test.add = 'some more AMAZING stuff' +// console.log(test.show); // ---> [ 'more stuff', 'even more stuff', 'some more AMAZING stuff' ] diff --git a/cc14queueStack/solution_Tai.js b/cc14queueStack/solution_Tai.js new file mode 100644 index 0000000..e31c9dd --- /dev/null +++ b/cc14queueStack/solution_Tai.js @@ -0,0 +1,55 @@ +/** + * Write a stack class. Once you're done, + * implement a queue using two stacks. + */ + +class Stack { + constructor() { + this.storage = []; + } + + add(item) { + this.storage.push(item); + } + + remove() { + if (this.storage.length === 0) return null; + return this.storage.pop(); + } + + get length() { + return this.storage.length; + } +} + +class Queue { + constructor() { + this.stack1 = new Stack(); + this.stack2 = new Stack(); + } + enqueue(item) { + this.stack1.add(item); + } + + dequeue() { + if (this.stack2.length === 0) { + const length = this.stack1.length; + for (let i = 0; i < length; i++) { + this.stack2.add(this.stack1.remove()); + } + } + return this.stack2.remove(); + } +} + +const queue = new Queue(); + +queue.enqueue(1); +queue.enqueue(2); +queue.enqueue(3); +const val1 = queue.dequeue(); +const val2 = queue.dequeue(); +queue.enqueue(4); +const val3 = queue.dequeue(); +const val4 = queue.dequeue(); +console.log(val1, val2, val3, val4); diff --git a/cc15bubbleSort/Tai_solution.js b/cc15bubbleSort/Tai_solution.js new file mode 100644 index 0000000..d61c58f --- /dev/null +++ b/cc15bubbleSort/Tai_solution.js @@ -0,0 +1,18 @@ +const bubbleSort = (arr) => { + let swappedValue; + do { + swappedValue = false; + for (let i = 0; i < arr.length; i++) { + console.log(arr); + if (arr[i] > arr[i + 1]) { // [2, 1, 3] + let temp = arr[i]; // temp = 2 + arr[i] = arr[i + 1]; // [1, 1, 3] temp = 2; + arr[i + 1] = temp; // [1, 2, 3]; + swappedValue = true; + } + } + } while (swappedValue); + return arr; +}; + +console.log(bubbleSort([5, 6, 7, 3, 2, 1])); // returns [1, 2, 3] diff --git a/cc15bubbleSort/bubbleSort.js b/cc15bubbleSort/bubbleSort.js new file mode 100644 index 0000000..becf809 --- /dev/null +++ b/cc15bubbleSort/bubbleSort.js @@ -0,0 +1,105 @@ +// Code Challenge # 15 + +// INPUT: array of numbers +// FUNCTION: sort from {array[0]: low} to {array[n-1]: high} +// OUTPUT: sorted array +const bubbleSort = (arr, count = 0) => { + // compare all (current/next) index pairs + for (let i = 0; i < arr.length; i++) { + // index pairs + let current = arr[i]; + let next = arr[i + 1]; + // counter to track sorting passes + let sorting = count; + + // IF current is greater than next, + // THEN swap index pairs & increment sorting counter. + // ELSE reset sorting counter to zero (to prevent recursive call) + if (current > next) { + arr[i] = next; + arr[i + 1] = current; + sorting++; + } else sorting = 0; + + // IF index pairs were swapped, + // THEN recursively call function until sorting count is 0 + if (sorting !== 0) { + // // UNCOMMENT TO CONSOLE.LOG() EACH PASS + // if (modify > 9) { + // console.log(`Sorting pass #${modify}: ${arr}`); + // } else { + // console.log(`Sorting pass #${modify}: ${arr}`); + // } + + bubbleSort(arr, sorting); + } + } + // return sorted array + return arr; +}; + +// TEST SUITE +// BASIC SORTING OF THE NATURAL NUMBERS +const test1 = [ 2, 1, 3 ]; +console.log(`TEST #1 UNSORTED: ${test1}`); +console.log(`TEST #1 SORTED: ${bubbleSort(test1)}\n`); +// ---> [ 1, 2, 3 ] + +const test2 = [ 3, 2, 1, 3, 1, 5, 4, 3 ]; +console.log(`TEST #2 UNSORTED: ${test2}`); +console.log(`TEST #2 SORTED: ${bubbleSort(test2)}\n`); +// ---> [ 1, 1, 2, 3, 3, 3, 4, 5 ] + +const test3 = [ 102345, 99, 34, 87, 135, 8, 3, 7, 99, 101, 3657, 2, 1, 5, 4, 3 ]; +console.log(`TEST #3 UNSORTED: ${test3}`); +console.log(`TEST #3 SORTED: ${bubbleSort(test3)}\n`); +// ---> [ 1, 2, 3, 3, 4, 5, 7, 8, 34, 87, 99, 99, 101, 135, 3657, 102345 ] + +// // EDGE CASE HANDLING? +// // NEGATIVE INTEGERS +// const test4 = [ 3, 2, 1, -1, 0 ] +// console.log(`TEST #4 UNSORTED: ${test4}`); +// console.log(`TEST #4 SORTED: ${bubbleSort(test4)}\n`); +// // ---> [ -1, 0, 1, 2, 3 ] +// +// // DECIMALS +// const test5 = [ 3.2, -2.5, 1, -1, 0.32 ] +// console.log(`TEST #5 UNSORTED: ${test5}`); +// console.log(`TEST #5 SORTED: ${bubbleSort(test5)}\n`); +// // ---> [ -2.5, -1, 0.32, 1, 3.2 ] +// +// // IRRATIONALS & EXPRESSIONS +// const test6 = [ Math.PI, -2.5, 1, ( Math.E - 1 ), 0.32 ] +// console.log(`TEST #6 UNSORTED: ${test6}`); +// console.log(`TEST #6 SORTED: ${bubbleSort(test6)}\n`); +// // ---> [ -2.5, 0.32, 1, 1.718281828459045, 3.141592653589793 ] + + + +/* + +ANALYSIS: +1. Order of complexity: Quadratic due to the recursive call to a for loop? + - O(n^2) +2. Other edge cases? + - `if (current > next)` should I and how would I check for the undefined value of array[n + 1]? +3. This algorithm modifies the original array. How to not alter the original? + - let sorting = arr.slice(0); + - Tried this and replacing subsequent arr variables, but it made an unending loop? + - slice makes a non destructive copy... WHY? OH, WHY?????? + ```console + $ node + > x = [1, 2, 3, 4] + [ 1, 2, 3, 4 ] + > y = x.slice(0) + [ 1, 2, 3, 4 ] + > y[1] = 99 + 99 + > x + [ 1, 2, 3, 4 ] + > y + [ 1, 99, 3, 4 ] + ``` + - splice made it so nothing returns... :\ + +*/ diff --git a/bubbleSort/bubbleSort.js b/cc15bubbleSort/readme.md similarity index 94% rename from bubbleSort/bubbleSort.js rename to cc15bubbleSort/readme.md index 69211d2..3da32ec 100644 --- a/bubbleSort/bubbleSort.js +++ b/cc15bubbleSort/readme.md @@ -20,7 +20,3 @@ * bubbleSort([2, 1, 3]); // returns [1, 2, 3] * */ - -const bubbleSort = (arr) => { - //code here -}; diff --git a/cc16allAnagrams/Seans_solution.js b/cc16allAnagrams/Seans_solution.js new file mode 100644 index 0000000..ab34642 --- /dev/null +++ b/cc16allAnagrams/Seans_solution.js @@ -0,0 +1,12 @@ +const allAnagrams = (str, start = '') => { + if (str.length === 1) return [start + str]; + const anagrams = []; + + for (let i = 0; i < str.length; i++) { + const result = allAnagrams(str.substr(0, i) + str.substr(i + 1), str[i]); + for (let j = 0; j < result.length; j++) { + anagrams.push(start + result[j]); + } + } + return anagrams; +}; diff --git a/cc16allAnagrams/Wesleys_solution.js b/cc16allAnagrams/Wesleys_solution.js new file mode 100644 index 0000000..49f0715 --- /dev/null +++ b/cc16allAnagrams/Wesleys_solution.js @@ -0,0 +1,39 @@ +class Anagram { + constructor(string, letter = null) { + this.string = string; + this.letter = letter; + this.children = []; + this.answer = []; + this.divide(); + this.produce(); + } + + divide() { + const arr = this.string.split(''); + arr.forEach(l => { + const rest = arr.filter(x => x !== l).join(''); + const anagram = new Anagram(rest, l); + this.children.push(anagram); + }); + } + + produce(a = this, b = null) { + if (a.letter) { + b = b ? b.concat(a.letter) : a.letter; + } + if (a.children.length) { + a.children.forEach(aa => { + return this.produce(aa, b ? b : null) + }); + return this.answer; + } + this.answer.push(b); + } +} + +function allAnagrams(s) { + return (new Anagram(s)).answer; +} + +const anagrams = allAnagrams('abcdefghi'); +console.log(anagrams); diff --git a/cc16allAnagrams/allAnagrams.js b/cc16allAnagrams/allAnagrams.js new file mode 100644 index 0000000..4315279 --- /dev/null +++ b/cc16allAnagrams/allAnagrams.js @@ -0,0 +1,94 @@ +// Code Challenge # 16 +/** + * Given a single input string, write a function that produces all possible anagrams + * of a string and outputs them as an array. At first, don't worry about + * repeated strings. What time complexity is your solution? + * + * Extra credit: Deduplicate your return array. + + * example usage: + * const anagrams = allAnagrams('abc'); + * console.log(anagrams); // [ 'abc', 'acb', 'bac', 'bca', 'cab', 'cba' ] + +// INPUT: a string +// FUNCTION: return all possible combinations of letterss +// OUTPUT: array of string permutations + +// SOLUTION: slice off the first letter, swap the next two letters, recombine the swapped letters with the first letter... Hmmm... + slice vs splice? slice doesn't change original, splice does. + +// After looking at brute solutions, it seems there is a factorial operation going on here such that a string of 5 characters would have 5! solutions... +// hmmm! +// get the first letter and use the length of the string to slice the remainder of the string, as the for loop continues + +// To deduplicate, just new Set(array of anagrams) +*/ + + + + +const allAnagrams = (str) => { + + if (str.length < 2) return str; + + const result = []; + + for (let i = 0; i < str.length; i++) { + let firstLetter = str[i]; + let restOfString = str.slice(0, i) + str.slice(i + 1, str.length); + + for (let sub of allAnagrams(restOfString)) { + result.push(firstLetter + sub); + } + } + return result; +} + +console.log(allAnagrams('abc')); + + + + + + + + +// const result = [], temp = []; +// +// allAnagrams = (str) => { +// const chars = str.split(''); +// +// for (let i = 0; i < chars.length; i++) { +// const subStr = chars.splice(i, 1); +// temp.push(subStr); +// if (chars.length == 0) +// result[result.length] = temp.join(''); +// allAnagrams(chars.join('')); +// chars.splice(i, 0, subStr); +// temp.pop(); +// } +// return result +// }; +// +// +// console.log(allAnagrams('abc')); + + + +// FACTORIAL +const nFactorial = (n) => { + // factorial example: !5 = 5 * 4 * 3 * 2 * 1 + // return the factorial of `n` + + // // version 1 √ + if (n === 1) return n; + return n * nFactorial(n - 1); + + // // version 2: ternary solution √ + // // declare variableName = ifCondition ? thenThis : otherwiseThat; + // const factorial = (n === 1) ? 1 : n * nFactorial(n - 1); + // return factorial; + + // // version 2.1 √ + // return (n === 1) ? n : n * nFactorial(n - 1); +}; diff --git a/insertionSort/insertionSort.js b/cc17insertionSort/Tais_solution.js similarity index 68% rename from insertionSort/insertionSort.js rename to cc17insertionSort/Tais_solution.js index d8b0db9..c1e78e7 100644 --- a/insertionSort/insertionSort.js +++ b/cc17insertionSort/Tais_solution.js @@ -12,5 +12,17 @@ const insertionSort = (array) => { // Your code goes here. Feel free to add helper functions if needed. + for (let i = 1; i < array.length; i++) { + let temp = array[i]; + let j; + for (j = i - 1; j >=0 && array[j] > temp; j--) { + array[j + 1] = array[j]; + } + array[j + 1] = temp; + } return array; -}; \ No newline at end of file +}; + +const val = insertionSort([2, 1, 3, 7, 4, 2, 9, 3, 8]); +// yields [1, 2, 2, 3, 3, 4, 7, 8, 9] +console.log(val); diff --git a/cc17insertionSort/insertionSort.js b/cc17insertionSort/insertionSort.js new file mode 100644 index 0000000..f694bb0 --- /dev/null +++ b/cc17insertionSort/insertionSort.js @@ -0,0 +1,38 @@ +/** + CODE CHALLENGE #17 + * Insertion sort is a basic sorting algorithm. Insertion sort + * iterates over an array, growing a sorted array behind the current location. + * It takes each element from the input and finds the spot, up to the current point, + * where that element belongs. It does this until it gets to the end of the array. + * https://en.wikipedia.org/wiki/Insertion_sort + - complexity O(n^2) + * https://www.khanacademy.org/computing/computer-science/algorithms#insertion-sort + **/ + +// Example usage: +// insertionSort([2, 1, 3, 7, 4, 2, 9, 3, 8]); // yields [1, 2, 2, 3, 3, 4, 7, 8, 9] + +const insertionSort = (array) => { + for(let i = 0; i < array.length; i++) { + let temp = array[i]; + console.log('temp ------------------------>', temp); + let j = i - 1; + console.log(' i | j array[i] =', array[i], ' array[j] =', array[j]) + console.log('for loop: ', i, '| ', array); + console.log('----------------------------------------------') + while (j >= 0 && array[j] > temp) { + console.log('while: ', i, '|', j, array); + array[j + 1] = array[j]; + j--; + } + console.log('----------------------------------------------') + array[j + 1] = temp; + console.log('end of for loop:', array, '\n\n'); + } + return array; +}; + + +// TEST SUITE +// console.log(insertionSort([2, 1, 3, 7, 4, 2, 9, 3, 8])); // yields [1, 2, 2, 3, 3, 4, 7, 8, 9] +console.log("Tada:", insertionSort([9, 8, 7, 6, 5, 4, 3, 2, 1, ])); // yields [1, 2, 2, 3, 3, 4, 7, 8, 9] diff --git a/cc18rotateImage/Tai_solution.js b/cc18rotateImage/Tai_solution.js new file mode 100644 index 0000000..d525402 --- /dev/null +++ b/cc18rotateImage/Tai_solution.js @@ -0,0 +1,35 @@ +// Given an image represented by an NxN matrix, where each pixel in the image is an integer from 0 - 9, +// write a method to rotate the image by 90 degrees. Can you do this in place? + +const rotateImage = (arr) => { + const len = arr.length; + for (let i = 0; i < len / 2; i++) { + for (let j = i; j < len - i - 1; j++) { + let bucket = arr[i][j]; + arr[i][j] = arr[j][len - i - 1]; + arr[j][len - i - 1] = arr[len - i - 1][len - j - 1]; + arr[len - i - 1][len - j - 1] = arr[len - j - 1][i]; + arr[len - j - 1][i] = bucket; + } + } + return arr; +}; + +const image = [ + [1, 2, 3, 4], + [5, 6, 7, 8], + [9, 0, 1, 2], + [3, 4, 5, 6], +]; +console.log(' '); +console.log(rotateImage(image)); +console.log(rotateImage(image)); +console.log(rotateImage(image)); +console.log(rotateImage(image)); +// create a holding variable +// using two for loops + +// [[4, 8, 2, 6], +// [3, 7, 1, 5], +// [2, 6, 0, 4], +// [1, 5, 9, 3]] diff --git a/cc18rotateImage/rotateImage.js b/cc18rotateImage/rotateImage.js new file mode 100644 index 0000000..d709b41 --- /dev/null +++ b/cc18rotateImage/rotateImage.js @@ -0,0 +1,113 @@ +// cc18 rotateImage + +// Given an image represented by an NxN matrix, where each pixel in the image is an integer from 0 - 9, +// write a method to rotate the image by 90 degrees. Can you do this in place? + +// for each row (array), take the column (index) and put each +// corresponding index value in an array, so row 1-9 col (index) 0 become an array, +// then row1-9 col (index) 1 and so on. + + +// this seems to only work for square matrixes +// no idea how I'd do it in place +const rotateImage = (arr) => { + const len = arr.length; + rotation = Array(len).fill().map(()=> []); + for (let col = 0; col < len; col++) { + for (let row = len - 1; row >= 0; row--) { + rotation[col].push(arr[row][col]); + } + } + return rotation; +} + + +// 10x10 array +// console.log(rotateImage([ +// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], +// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], +// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], +// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], +// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], +// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], +// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], +// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], +// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], +// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] +// ] +// )); + +// 4x4 array +console.log(rotateImage([ + [ 0, 1, 2, 3 ], + [ 4, 5, 6, 7 ], + [ 8, 9, 0, 1 ], + [ 2, 3, 4, 5 ] +] +)); + +[ + [ 2, 8, 4, 0 ], + [ 3, 9, 5, 1 ], + [ 4, 0, 6, 2 ], + [ 5, 1, 7, 3 ] ] + +[ +[ 2, 8, 4, 0 ], +[ 3, 9, 5, 1 ], +[ 4, 0, 6, 2 ], +[ 5, 1, 7, 3 ] ] + + +// Not quite +const rotateImageInPlace = (arr) => { + const len = arr.length; + // rotation = Array(len).fill().map(()=> []); + for (let col = 0; col < len; col++) { + for (let row = 0; row < len; row ++) { + arr[col].push(arr[row][col]); + } + } + return arr; +} + +// 4x4 array +// console.log(rotateImageInPlace([ +// [ 0, 1, 2, 3 ], +// [ 0, 1, 2, 3 ], +// [ 0, 1, 2, 3 ], +// [ 0, 1, 2, 3 ] +// ] +// )); + +/* +INPUT: (9x9 image matrix) +const exampleImageArray = [ + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], +] + +FUNCTION: 90 degree clockwise rotation + +OUTPUT: +[ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ], + [ 1, 1, 1, 1, 1, 1, 1, 1, 1 ], + [ 2, 2, 2, 2, 2, 2, 2, 2, 2 ], + [ 3, 3, 3, 3, 3, 3, 3, 3, 3 ], + [ 4, 4, 4, 4, 4, 4, 4, 4, 4 ], + [ 5, 5, 5, 5, 5, 5, 5, 5, 5 ], + [ 6, 6, 6, 6, 6, 6, 6, 6, 6 ], + [ 7, 7, 7, 7, 7, 7, 7, 7, 7 ], + [ 8, 8, 8, 8, 8, 8, 8, 8, 8 ], + [ 9, 9, 9, 9, 9, 9, 9, 9, 9 ], +] + +*/ diff --git a/cc19logicGates/CS6.js b/cc19logicGates/CS6.js new file mode 100644 index 0000000..5093695 --- /dev/null +++ b/cc19logicGates/CS6.js @@ -0,0 +1,147 @@ +// phi NAND psi +// T !&& T ---> F +// T !&& F ---> T +// F !&& T ---> T +// F !&& F ---> T +function NAND(x, y) { + // You can use whatever JS operators that you would like: &&, ||, ! + if ( !(x && y) ) { + return 1; + } return 0; +} +console.log('NAND'); +console.log(NAND(true, true)); // ---> 0 +console.log(NAND(true, false)); // ---> 1 +console.log(NAND(false, true)); // ---> 1 +console.log(NAND(false, false)); // ---> 1 + +// Not operator +// !T ---> F +// !F ---> T +function NOT(n) { + // Do not use !, &&, or || + return (NAND(n, n)); +} +console.log('NOT') +console.log(NOT(true)); // ---> 0 +console.log(NOT(false)); // ---> 1 + +// phi AND psi +// T && T ---> T +// T && F ---> F +// F && T ---> F +// F && F ---> F +function AND(x, y) { + // Do not use &&, ||, or ! + // You can use any of the functions that you have already written + if (NAND(x, y)) { + return 0; + } return 1; +} +console.log('AND'); +console.log(AND(true, true)); // ---> 1 +console.log(AND(true, false)); // ---> 0 +console.log(AND(false, true)); // ---> 0 +console.log(AND(false, false)); // ---> 0 + +// INclusive OR: phi OR psi +// T || T ---> T +// T || F ---> T +// F || T ---> T +// F || F ---> F +function OR(x, y) { + // Do not use ||, &&, or ! + // You can use any of the functions that you have already written + if (x) return 1; + if (y) return 1; + return 0; +} +console.log('OR'); +console.log(OR(true, true)); // ---> 1 +console.log(OR(true, false)); // ---> 1 +console.log(OR(false, true)); // ---> 1 +console.log(OR(false, false)); // ---> 0 + +// EXclusive OR: phi XOR psi +// T XOR T ---> F +// T XOR F ---> T +// F XOR T ---> T +// F XOR F ---> F +function XOR(x, y) { + // Do not use ||, &&, or ! + // You can use any of the functions that you have already written + if (x === y) return 0; + return 1; +} +console.log('XOR'); +console.log(XOR(true, true)); // ---> 0 +console.log(XOR(true, false)); // ---> 1 +console.log(XOR(false, true)); // ---> 1 +console.log(XOR(false, false)); // ---> 0 + + + +/////////// + +// Logic Gates using NAND +function NAND(x, y) { + return !(x && y) ? 1 : 0; +} +// function NAND(0, 0) { +// return !(not true && not true) ? 1 : 0; // ---—> 1/True. +// } +/********************/ +function NOT(n) { + return NAND(n, n); +} +// function NOT(0) { +// return NAND(0, 0); // ---—> 1/True. +// } +/********************/ +function AND(x, y) { + return NAND(NAND(x, y), NAND(x, y)); +} +// function AND(1, 1) { +// return NAND(NAND(1, 1), NAND(1, 1)); +// NAND(0, 0)); // ---—> True +// } +/********************/ +function OR(x, y) { + return NAND(NAND(x, x), NAND(y, y)); +} +// function OR(1, 0) { +// return NAND(NAND(1, 1), NAND(0, 0)); +// NAND(0, 1) // ---—> True; +// } +/********************/ +function XOR(x, y) { + return NAND(NAND(x, NAND(x, y)), NAND(NAND(x, y), y)); +} +// function XOR(1, 0) { +// return NAND(NAND(1, NAND(1, 0)), NAND(NAND(1, 0),0)); +// NAND(NAND(1, 1), NAND(1, 0)); +// NAND(0, 1); // ---—> True +// } + + +///////// Model solution + +function NAND(x, y) { + return ((!x || !y) ? 1 : 0); +} + +function NOT(n) { + return (NAND(n,n)); +} + +function AND(x, y) { + return (NAND(NAND(x, y), NAND(x, y))); +} + +function OR(x, y) { + return (NAND(NAND(x, x), NAND(y, y))); +} + +function XOR(x, y) { + return (NAND(NAND(x, NAND(x, y)), NAND(y, NAND(x, y)))); +} diff --git a/cc19logicGates/logicGates.js b/cc19logicGates/logicGates.js new file mode 100644 index 0000000..c719725 --- /dev/null +++ b/cc19logicGates/logicGates.js @@ -0,0 +1,105 @@ +/* cc19 logicGates + * For this coding challenge you will be recreating low level logic gates. + * You will first create the NAND function and then you will create + * NOT, OR, AND, and XOR all using the NAND function that you created. + * Implement NAND however you would like and then use NAND to implement the + * other logic gates. + * See the link below for the truth tables for these logic gates. + * https://en.wikipedia.org/wiki/NAND_logic#NAND + * All functions should return a 1 for true and a 0 for false. + */ + +/* TODO: + 1. refactor with ternary operator + 2. complete each with NAND +*/ + +// phi AND psi +// (T && T) ---> T +// (T && F) ---> F +// (F && T) ---> F +// (F && F) ---> F +// +// NOT (phi AND psi) operator +// !(T && T) ---> F +// !(T && F) ---> T +// !(F && T) ---> T +// !(F && F) ---> T +const NAND = (x, y) => { + // You can use whatever JS operators that you would like: &&, ||, ! + if ( !(x && y) ) { + return 1; + } return 0; +}; +console.log('NAND'); +console.log(NAND(true, true)); // ---> 0 +console.log(NAND(true, false)); // ---> 1 +console.log(NAND(false, true)); // ---> 1 +console.log(NAND(false, false)); // ---> 1 + + +// Not operator +// !T ---> F +// !F ---> T +const NOT = (n) => { + // Do not use !, &&, or || + return (NAND(n, n)); +}; +console.log('NOT') +console.log(NOT(true)); // ---> 0 +console.log(NOT(false)); // ---> 1 + +// phi AND psi +// T && T ---> T +// T && F ---> F +// F && T ---> F +// F && F ---> F +const AND = (x, y) => { + // Do not use &&, ||, or ! + // You can use any of the functions that you have already written + if (NAND(x, y)) { + return 0; + } return 1; +}; +console.log('AND'); +console.log(AND(true, true)); // ---> 1 +console.log(AND(true, false)); // ---> 0 +console.log(AND(false, true)); // ---> 0 +console.log(AND(false, false)); // ---> 0 + + +// INclusive OR: phi OR psi +// T || T ---> T +// T || F ---> T +// F || T ---> T +// F || F ---> F +const OR = (x, y) => { + // Do not use ||, &&, or ! + // You can use any of the functions that you have already written + if (x) return 1; + if (y) return 1; + return 0; +}; +console.log('OR'); +console.log(OR(true, true)); // ---> 1 +console.log(OR(true, false)); // ---> 1 +console.log(OR(false, true)); // ---> 1 +console.log(OR(false, false)); // ---> 0 + + +// EXclusive OR: phi XOR psi +// T XOR T ---> F +// T XOR F ---> T +// F XOR T ---> T +// F XOR F ---> F +const XOR = (x, y) => { + // Do not use ||, &&, or ! + // You can use any of the functions that you have already written + if (x === y) return 0; + return 1; +}; +console.log('XOR'); +console.log(XOR(true, true)); // ---> 0 +console.log(XOR(true, false)); // ---> 1 +console.log(XOR(false, true)); // ---> 1 +console.log(XOR(false, false)); // ---> 0 diff --git a/cc19logicGates/logicgates.pdf b/cc19logicGates/logicgates.pdf new file mode 100644 index 0000000..cd2aaae Binary files /dev/null and b/cc19logicGates/logicgates.pdf differ diff --git a/cc20parallel/Tais_Solution.js b/cc20parallel/Tais_Solution.js new file mode 100644 index 0000000..a894776 --- /dev/null +++ b/cc20parallel/Tais_Solution.js @@ -0,0 +1,97 @@ +// const parallel = (arrayOfFunctions, cb) => { +// // create a new array +// // get length of functionsArray +// // use forEach with arrow function param (func, i) +// // invoke each func with arrow function param (value) +// // subtract one from functionsArray length +// // if funArray.length === 0, cb(new array) +// +// const values = []; +// let remainingItems = arrayOfFunctions.length; +// arrayOfFunctions.forEach((func, i) => { +// func((value) => { +// values[i] = values; +// remainingItems--; +// if (remainingItems === 0) cb(values); +// }); +// }); +// }; + + +'use strict'; + +/* Implement the function parallel: + * + * Parallel has two parameters, an array of asynchronous functions (tasks) and a callback. + * Each of the tasks takes a callback and invokes that callback when complete. + * + * The callback passed to parallel is then performed on the results of the callbacks of the tasks. + * + * The order of these results should be the same as the order of the tasks. + * It is important to note that this is not the order in which the tasks return, + * but the order in which they are passed to parallel. + * + * Once all the callbacks of the tasks are returned, parallel should invoke the callback + * on the results array. + * + * + * Example: + * + * parallel([ + * function(callback){ + * setTimeout(function(){ + * callback('one'); + * }, 200); + * }, + * function(callback){ + * setTimeout(function(){ + * callback('two'); + * }, 100); + * } + * ], + * // optional callback + * (results) => { + * // the results array will equal ['one','two'] even though + * // the second function had a shorter timeout. + console.log(results); // ['one', 'two'] + * }); + * + * + */ + +const parallel = (functions, cb) => { + // create a new array + // get length of functionsArray + // use forEach with arrow function params (func, i) + // invoke each func with arrow function param (value) + // subtract one from functionsArrayLength + // if functionsArrayLength === 0, cb(newArray) + const values = []; + let remainingItems = functions.length; + functions.forEach((func, i) => { + func((value) => { + values[i] = value; + remainingItems--; + if (remainingItems === 0) cb(values); + }); + }); +}; + +const paraArr = [ + function(callback){ + setTimeout(function(){ + callback('one'); + }, 200); + }, + function(callback){ + setTimeout(function(){ + callback('two'); + }, 100); + } +]; +const cbFun = (results) => { + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. + console.log(results); // ['one', 'two'] +}; +parallel(paraArr, cbFun); diff --git a/cc20parallel/parallel.js b/cc20parallel/parallel.js new file mode 100644 index 0000000..0837b4f --- /dev/null +++ b/cc20parallel/parallel.js @@ -0,0 +1,85 @@ +// c20 parallel + +'use strict'; + +/* Implement the function parallel: + * + * Parallel has two parameters, an array of asynchronous functions (tasks) and a callback. - OKAY √ + * Each of the tasks takes a callback and invokes that callback when complete. - OKAY √ + * + * The callback passed to parallel is then performed on the results of the callbacks of the tasks. - Umm, okay? + * + * The order of these results should be the same as the order of the tasks. - Okay... + * It is important to note that this is not the order in which the tasks return, - I see the Timeout durations + * but the order in which they are passed to parallel. - Alright... + * + * Once all the callbacks of the tasks are returned, parallel should invoke the callback + * on the results array. - OKAY√ + * + * + * Example: + * + * parallel([ + * function(callback){ + * setTimeout(function(){ + * callback('one'); + * }, 200); + * }, + * function(callback){ + * setTimeout(function(){ + * callback('two'); + * }, 100); + * } + * ], + * // optional callback + * (results) => { + * // the results array will equal ['one','two'] even though + * // the second function had a shorter timeout. + * console.log(results); // ['one', 'two'] + * }); + * + * + */ + +// // uhh.... +// const parallel = (...args, cb) => { +// return (cb(args)); +// } + +// const parallel = (cb, ...args) => { +// return (cb(args)); +// } + +const parallel = (cb, ...args) => { + return (args(cb)); +} + + +// parallel( +// // PARAMETER 1 +// [ function(callback){ +// setTimeout(function() { callback('one'); }, 200); +// }, +// function(callback){ +// setTimeout(function() { callback('two'); }, 100); +// }], +// // PARAMETER 2 - optional callback +// // the results array will equal ['one','two'] even though +// // the second function had a shorter timeout. +// (results) => { console.log(results); } // ~~> ['one', 'two'] +// ); + +parallel( + // PARAMETER 2 - optional callback + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. + (results) => { console.log(results); } // ~~> ['one', 'two'] + , + // PARAMETER 1 + [ function(callback){ + setTimeout(function() { callback('one'); }, 200); + }, + function(callback){ + setTimeout(function() { callback('two'); }, 100); + }] + ); diff --git a/cc21rockPaperScissor/Tai_solution.js b/cc21rockPaperScissor/Tai_solution.js new file mode 100644 index 0000000..07efa52 --- /dev/null +++ b/cc21rockPaperScissor/Tai_solution.js @@ -0,0 +1,60 @@ +// triple for loop vs recursion + +/* + * * Write a function that generates every sequence of throws a single + * * player could throw over a three-round game of rock-paper-scissors. + * * + * * Your output should look something like: + * * [["rock", "rock", "rock"], + * * ["rock", "rock", "paper"], + * * ["rock", "rock", "scissor"], + * * ["rock", "paper", "rock"], + * ...etc... + * */ + +const rockPaperScissorsLoop = () => { + // TODO: your solution here + // we need an answer container + // we need an array of strings r,p,s + // we need to iterate the first part of the array ['scissors',] + // inside the for loop, we need to iterate the second part of the array[..., 'scissors',] + // inside the second for loop, we need to iterate the third part of the array [..., ..., 'scissors'] + // once we generate all three, then we need to push to answers + //after forloop tango, return array + // so when O(n^3) is written, n is arrayOfStrings.length + const answer = []; + const choice = ['rock', 'paper', 'scissors']; + for (let i = 0; i < choice.length; i++) { + for (let j = 0; j < choice.length; j++) { + for (let k = 0; k < choice.length; k++) { + answer.push([choice[i], choice[j], choice[k]]); + } + } + } + return answer; +}; + +console.log(rockPaperScissorsLoop()); + + + + +const rockPaperScissorsRecurse = (rounds) => { + const results = []; + const choices = ['scissors', 'rock', 'paper']; + const findChoices = (roundsLeft, roundsPlayed) => { + if (roundsLeft === 0) { + results.push(roundsPlayed); + return; + } + for (let i = 0; i < choices.length; i++) { + const choice = choices[i]; + findChoices(roundsLeft - 1, roundsPlayed.concat(choice)); + } + }; + findChoices(rounds, []); + + return results; +}; + +console.log(rockPaperScissorsRecurse(3)); diff --git a/cc21rockPaperScissor/rockPaperScissors.js b/cc21rockPaperScissor/rockPaperScissors.js new file mode 100644 index 0000000..a5fdcd8 --- /dev/null +++ b/cc21rockPaperScissor/rockPaperScissors.js @@ -0,0 +1,44 @@ +// cc21 rockPaperScissor + +/* + * * Write a function that generates every sequence of throws a single + * * player could throw over a three-round game of rock-paper-scissors. + * * + * * Your output should look something like: + * * [["rock", "rock", "rock"], + * * ["rock", "rock", "paper"], + * * ["rock", "rock", "scissor"], + * * ["rock", "paper", "rock"], + * ...etc... + * */ + +// const rockPaperScissors = () => { +// // TODO: your solution here +// // const hand = {0: 'rock', +// // 1: 'paper', +// // 2: 'scissor'} +// const hand = ['rock', 'paper', 'scissor'] // hand.length = 3 +// let rounds = 3 +// const totalPossibleCombos = hand.length ** rounds // 27 ~~~> (n terms)**3 +// +// }; + + +const test = (arr) => { + const result = []; + + for (let i = 0; i < arr.length; i++) { + // let firstElement = arr[i]; + let firstElement = []; + firstElement.push(arr[i]); + + let restOfArray = arr.slice(i + 1, arr.length); + + for (let sub of test(restOfArray)) { + result.push(firstElement, sub); + } + } + return result; +} + +console.log(test(['rock', 'paper', 'scissor'])); diff --git a/cc22quickSort/Tai_solution.js b/cc22quickSort/Tai_solution.js new file mode 100644 index 0000000..087c19a --- /dev/null +++ b/cc22quickSort/Tai_solution.js @@ -0,0 +1,35 @@ +// http://me.dt.in.th/page/Quicksort/ + +/* + * Implement the quick sort sorting algorithm. Assume the input is an array of integers. + * https://en.wikipedia.org/wiki/Quicksort + * https://www.khanacademy.org/computing/computer-science/algorithms#quick-sort + */ + +const quickSort = (arr) => { + // base case for recursion, if array.length is <= 1, return arr + // create lessthan array + // create gr8rthan array + // find a pivot + // for loop, sorting if arr[i] is > || <= pivot + // create answer array = [] + // return answerArray.concat(quicksort of lessthan, pivot, quicksort of greaterthan) + if (arr.length <= 1) return arr; + + const lessThan = []; + const greaterThan = []; + const pivot = arr.splice(Math.floor(Math.random() * arr.length - 1), 1); + console.log(pivot); + for (let i = arr.length - 1; i >= 0; i--) { + if (arr[i] < pivot) { + lessThan.push(arr[i]); + } else { + greaterThan.push(arr[i]); + } + } + + const c = []; + return c.concat(quickSort(lessThan), pivot, quickSort(greaterThan)); +}; + +console.log(quickSort([9, 8, 7, 6, 5, 4, 3, 2, 1])); diff --git a/cc22quickSort/quickSort.js b/cc22quickSort/quickSort.js new file mode 100644 index 0000000..d93cfc9 --- /dev/null +++ b/cc22quickSort/quickSort.js @@ -0,0 +1,34 @@ +// cc22 quickSort +/* + * Implement the quick sort sorting algorithm. Assume the input is an array of integers. + * https://en.wikipedia.org/wiki/Quicksort + * https://www.khanacademy.org/computing/computer-science/algorithms#quick-sort + */ +const quickSort = (nums) => { + // BASE CASE + if (nums.length < 2) { + return nums; + } /* v */ + const pivot = nums[0], + lessThan = [], + greaterThan = []; + /* v */ + for (let i = 1; i < nums.length; i++) { + if (nums[i] < pivot) { + lessThan.push(nums[i]); + } else greaterThan.push(nums[i]); + }; + // Binary tree recursion? BigO((n^2)^2) + return quickSort(lessThan).concat(pivot, quickSort(greaterThan)); +}; + + +// TEST SUITE + +// const x = [1,2,3], +// y = 4 +// z = [5,6,7]; +// console.log(x.concat(y, z)); // ~~~> [ 1, 2, 3, 4, 5, 6, 7 ] + +console.log(quickSort([ 9, 8, 7, 555, 632, 345, 4, 3, 2, 1])); +console.log(quickSort([ 4, 6, 5, 3, 2 ])); diff --git a/cc23selectionSort/selectionSort.js b/cc23selectionSort/selectionSort.js new file mode 100644 index 0000000..19ab67b --- /dev/null +++ b/cc23selectionSort/selectionSort.js @@ -0,0 +1,26 @@ +/* cc23 selectionSort + * Sort an array of numbers using selection sort. + * https://en.wikipedia.org/wiki/Selection_sort + * https://www.khanacademy.org/computing/computer-science/algorithms/sorting-algorithms/a/sorting + * + * [1, 6, 2, 5, 3, 4] -> [1, 2, 3, 4, 5, 6] + */ + +const selectionSort = (arr) => { + const sorted = Array.from(arr); + let minIndex, i, j; + for (i = 0; i < sorted.length; i++) { + minIndex = i; + for (j = i; j < sorted.length; j++) { + if (sorted[j] < sorted[minIndex]) { + minIndex = j; + } + } + [sorted[i], sorted[minIndex]] = [sorted[minIndex], sorted[i]]; + } + return sorted; +}; + + +// TEST SUITE +console.log(selectionSort([9, 7, 8, 5, 6, 4, 5, 2, 3, 1])); diff --git a/cc24rotatedArray/rotatedArray.js b/cc24rotatedArray/rotatedArray.js new file mode 100644 index 0000000..56dbc39 --- /dev/null +++ b/cc24rotatedArray/rotatedArray.js @@ -0,0 +1,74 @@ +/* cc24 rotatedArray + + * Given a sorted array that has been rotated some number of items right or + * left, i.e. [0, 1, 2, 3, 4, 5, 6, 7] might become [4, 5, 6, 7, 0, 1, 2, 3] + * how can you efficiently find an element? For simplicity, you can assume + * that there are no duplicate elements in the array. + * + * rotatedArraySearch should return the index of the element if it is in the + * array and should return null otherwise. + * + * For instance: + * rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 2) === 5 + * + * rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 100) === null + * + * Target time complexity: O(log(n)) + + 1) presuming a sorted & offset array + 2) search for the first index pair (arr[n] and arr[n+1]) where arr[n] > arr[n+1] + 3) arr[n] is the high value of the range + 4) arr[n+1] is the low value of the range + 5) query integer is outside range, return null + 5) index position of arr[n+1] is the offset where [n+1] minus offset = 0 + 6) not sure how to quickly return the index... +*/ + +/* eslint no-console: 0 */ + +const rotatedArraySearch = (arr, queryNum) => { + const len = arr.length; + let i, high, low, highIndex, lowIndex; + // search for the first pair where arr[n] > arr[n+1] + for (let i = 0; i < arr.length; i++) { + if (arr[i] > arr[i + 1]) { + [high, low, highIndex, lowIndex] = [arr[i], arr[i + 1], i, i + 1]; + } + }; + console.log(arr, queryNum) + console.log(`HI value: ${high}, is at index: ${highIndex}`) + console.log(`LO value: ${low}, is at index: ${lowIndex}`) + console.log(`TOTAL number of array elements: ${len}`); + if (!(queryNum >= low && high >= queryNum)) { + console.log(null); + console.log('\n'); + } else { + if ((len - queryNum) <= lowIndex) { + console.log(`${arr[lowIndex - (len - queryNum)]}\n`); + return arr[lowIndex - (len - queryNum)]; + } else { + console.log(`${arr[lowIndex + queryNum]}\n`); + return arr[len - queryNum]; + }; + }; +}; + +// // TEST SUITE +// rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], -1); +// rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 0); +// rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 1); +// rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 2); +// rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 3); +// rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 4); +// rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 5); +// rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 6); +// rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 7); + +rotatedArraySearch([4, 5, 6, 7, 2, 3], 1); +rotatedArraySearch([4, 5, 6, 7, 2, 3], 2); +rotatedArraySearch([4, 5, 6, 7, 2, 3], 3); +rotatedArraySearch([4, 5, 6, 7, 2, 3], 4); +rotatedArraySearch([4, 5, 6, 7, 2, 3], 5); +rotatedArraySearch([4, 5, 6, 7, 2, 3], 6); +rotatedArraySearch([4, 5, 6, 7, 2, 3], 7); +rotatedArraySearch([4, 5, 6, 7, 2, 3], 8); diff --git a/cc24rotatedArray/solution.js b/cc24rotatedArray/solution.js new file mode 100644 index 0000000..d8e2f0d --- /dev/null +++ b/cc24rotatedArray/solution.js @@ -0,0 +1,56 @@ +/* + * Given a sorted array that has been rotated some number of items right or + * left, i.e. [0, 1, 2, 3, 4, 5, 6, 7] might become [4, 5, 6, 7, 0, 1, 2, 3] + * how can you efficiently find an element? For simplicity, you can assume + * that there are no duplicate elements in the array. + * + * rotatedArraySearch should return the index of the element if it is in the + * array and should return null otherwise. + * + * For instance: + * rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 2) === 5 + * + * rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 100) === null + * + * Target time complexity: O(log(n)) + */ +/* eslint no-console: 0 */ + +const rotatedArraySearch = (arr, number) => { +/*// low = 0 + // high = arr.length - 1 + // while low <= high + // create middle to be initialized to avg of low + high + // check if arr[middle] === number, if so, return middle + // if array[low] <= array[middle] + // if array[low] <= number && number < array[middle] + // set high to middle - 1 + // else low = middle + 1 + // else + // if arr[middle] < number && number <= array[high] + // low = mid + 1; + // else high = middle - 1 + // return null; */ + let low = 0; + let high = arr.length - 1; + while (low <= high) { + const mid = Math.floor((low + high) / 2); + if (arr[mid] === number) return mid; + if (arr[low] <= arr[mid]) { + if (arr[low] <= number && number < arr[mid]) { + high = mid - 1; + } else { + low = mid + 1; + } + } else { + if (arr[mid] < number && number <= arr[high]) { + low = mid + 1; + } else { + high = mid - 1; + } + } + } + return null; +}; + +console.log(rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 2)); // === 5; diff --git a/linkedListCycle/linkedListCycle.js b/cc25linkedListCycle/linkedListCycle.js similarity index 97% rename from linkedListCycle/linkedListCycle.js rename to cc25linkedListCycle/linkedListCycle.js index 03864f1..a58d559 100644 --- a/linkedListCycle/linkedListCycle.js +++ b/cc25linkedListCycle/linkedListCycle.js @@ -1,4 +1,4 @@ -/* +/* cc25 linkedListCycles * Create a function that returns true if a linked list contains a cycle, or false if it terminates * * Usually we assume that a linked list will end with a null next pointer, for example: @@ -28,4 +28,4 @@ * Constraint 2: Do this in constant space * Constraint 3: Do not mutate the original nodes in any way * Hint: Search for Floyd's Tortoise and Hare algorithm. - */ \ No newline at end of file + */ diff --git a/cc25linkedListCycle/solution.js b/cc25linkedListCycle/solution.js new file mode 100644 index 0000000..04f40ef --- /dev/null +++ b/cc25linkedListCycle/solution.js @@ -0,0 +1,82 @@ +/* cc25 linkedListCycles - Tai's solution + * Create a function that returns true if a linked list contains a cycle, or false if it terminates + * + * Usually we assume that a linked list will end with a null next pointer, for example: + * + * A -> B -> C -> D -> E -> null + * + * A 'cycle' in a linked list is when traversing the list would result in visiting the same nodes over and over + * This is caused by pointing a node in the list to another node that already appeared earlier in the list. Example: + * + * A -> B -> C + * ^ | + * | v + * E <- D + * + * Example code: + * + * const nodeA = new Node('A'); + * const nodeB = nodeA.next = new Node('B'); + * const nodeC = nodeB.next = new Node('C'); + * const nodeD = nodeC.next = new Node('D'); + * const nodeE = nodeD.next = new Node('E'); + * hasCycle(nodeA); // => false + * nodeE.next = nodeB; + * hasCycle(nodeA); // => true + * + * Constraint 1: Do this in linear time + * Constraint 2: Do this in constant space + * Constraint 3: Do not mutate the original nodes in any way + * Hint: Search for Floyd's Tortoise and Hare algorithm. + */ + +// Define Node as a class + // constructor passing in node + // this.value = node + // this.next = null + +// define hasCycle as arrow function, that takes in a node + // let slow = head + // let fast = head + // do while loop + // if fast.next === null return false + // fast = fast.next + // if fast.next === null return false + // fast = fast.next + // slow = slow.next + // while slow !== fast + // return true + +class Node { + constructor(node) { + this.value = node; + this.next = null; + } +} + +const hasCycle = (head) => { + let slow = head; + let fast = head; + do { + if (fast.next === null) return false; + fast = fast.next; + if (fast.next === null) return false; + fast = fast.next; + slow = slow.next; + } while (slow !== fast); + return true; +} + +const nodeA = new Node('A'); +const nodeB = nodeA.next = new Node('B'); +const nodeC = nodeB.next = new Node('C'); +const nodeD = nodeC.next = new Node('D'); +const nodeE = nodeD.next = new Node('E'); +// A -> B -> C -> D -> E -> null +console.log(hasCycle(nodeA)); // false +nodeE.next = nodeB; +// A -> B -> C +// ^ | +// | v +// E <- D +console.log(hasCycle(nodeA)); // true diff --git a/blueSquares/blueSquares.md b/cc26blueSquares/blueSquares.md similarity index 82% rename from blueSquares/blueSquares.md rename to cc26blueSquares/blueSquares.md index f141e0b..6411e23 100644 --- a/blueSquares/blueSquares.md +++ b/cc26blueSquares/blueSquares.md @@ -1,3 +1,5 @@ +cc26 blueSquares + ### Getting back to our Front End roots #### The purpose here is to hit the brakes a bit and go back to Front End Development before moving onto more involved backend concepts. @@ -12,3 +14,10 @@ Use HTML/CSS (You can use flexbox) to display 12 red squares on the page. Use jQuery to make it so that when you click on one of the red boxes that box turns blue. + +??? + + + diff --git a/cc26blueSquares/index.html b/cc26blueSquares/index.html new file mode 100644 index 0000000..9a8a8f9 --- /dev/null +++ b/cc26blueSquares/index.html @@ -0,0 +1,26 @@ + + + + + + + cc26 Blue Squares + + + + + + + + + + +

HELLO, WORLD!

+ +
+ +
+ + + + diff --git a/cc26blueSquares/script.js b/cc26blueSquares/script.js new file mode 100644 index 0000000..b1ad919 --- /dev/null +++ b/cc26blueSquares/script.js @@ -0,0 +1,11 @@ +$(document).ready(function() { + + for (let i = 1; i <= 12; i++) { + $('.flex-container').append(`
  • ${i}
  • `); + }; + + $('.flex-item').click(function() { + $(this).toggleClass('blue'); + }); + +}); diff --git a/cc26blueSquares/styles.css b/cc26blueSquares/styles.css new file mode 100644 index 0000000..61ea1b6 --- /dev/null +++ b/cc26blueSquares/styles.css @@ -0,0 +1,37 @@ +body { + background: whitesmoke; + text-align: center; +} +.flex-container { + background: #CABA77; + padding: 0; + margin: 0; + list-style: none; + + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + + -webkit-flex-flow: row wrap; + justify-content: space-around; +} +.flex-item { + background: tomato; + padding: 5px; + width: 200px; + height: 150px; + margin-top: 10px; + + line-height: 150px; + color: white; + font-weight: bold; + font-size: 3em; + text-align: center; + + border-radius: 20%; +} +.blue { + background: #1280FF; +} diff --git a/cc27lruCache/LRUCache_Tests.js b/cc27lruCache/LRUCache_Tests.js new file mode 100644 index 0000000..186440a --- /dev/null +++ b/cc27lruCache/LRUCache_Tests.js @@ -0,0 +1,35 @@ +const LRUCache = require('./lruCache.js'); + +const cache = new LRUCache(3); +cache.set('item1', 'a'); +cache.set('item2', 'b'); +cache.set('item3', 'c'); +// cache.set('item2', 'd'); +// +// const item1 = cache.get('item1'); +// if (item1 !== 'a') { +// throw new Error(`expected item1 to be a, but got ${item1}`); +// } + +cache.set('item4', 'd'); + +const item3 = cache.get('item3'); +if (item3 !== 'c') { + throw new Error(`expected item3 to be c, but got ${item3}`); +} + +const item2 = cache.get('item2'); +if (item2 !== 'b') { + throw new Error(`expected item2 to be b, but got ${item2}`); +} + +const item1 = cache.get('item1'); +if (item1 !== null) { + throw new Error(`expected item1 to be null, but got ${item1}`); +} + +cache.set('item5', 'e'); +const item4 = cache.get('item4'); +if (item4 !== null) { + throw new Error(`expected item4 to be null, but got ${item1}`); +} diff --git a/cc27lruCache/LRU_CacheCode.js b/cc27lruCache/LRU_CacheCode.js new file mode 100644 index 0000000..727dc82 --- /dev/null +++ b/cc27lruCache/LRU_CacheCode.js @@ -0,0 +1,42 @@ +class LRUCache { + constructor(limit = 10) { + this.limit = limit; + this.size = 0; + this.list = new List(); + this.storage = {}; + } + + size() { + return this.size; + } + + get(key) { + const node = this.storage[key]; + if (node) { + this.list.moveToEnd(node); + return node.val.val; + } else { + return null; + } + } + + set(key, val) { + const node = this.storage[key]; + if (node) { + node.val.val = val; + this.list.moveToEnd(node); + return; + } + + if (this.size === this.limit) { + // already reached our limit + delete this.storage[this.list.head.val.key]; + this.list.shift(); + this.size--; + } + + this.list.push({ key, val }); + this.storage[key] = this.list.tail; + this.size++; + } +} diff --git a/lruCache/lruCache.js b/cc27lruCache/lruCache.js similarity index 99% rename from lruCache/lruCache.js rename to cc27lruCache/lruCache.js index 4f0eede..a64390a 100644 --- a/lruCache/lruCache.js +++ b/cc27lruCache/lruCache.js @@ -1,4 +1,4 @@ -/* +/* cc27 lruCache * Design and implement a LRU, or Least Recently Used, cache. * * An LRU cache gives O(1) get(key) and set(key, val) operations, @@ -39,7 +39,7 @@ class LRUCacheItem { class LRUCache { constructor(limit = 10) { - + } size() { @@ -177,4 +177,3 @@ class List { if (this.prev) this.prev.next = this.next; if (this.next) this.next.prev = this.prev; } - diff --git a/cc27lruCache/solution.js b/cc27lruCache/solution.js new file mode 100644 index 0000000..e6df07e --- /dev/null +++ b/cc27lruCache/solution.js @@ -0,0 +1,124 @@ +// cc27 lruCache Karthik's solution + +// Linked List Code + +class ListNode { + constructor(prev, val, next) { + this.prev = prev || null; + this.val = val; + this.next = next || null; + } + + // Insert a value right after the node. + insertAfter(val) { + const next = this.next; + this.next = new ListNode(this, val, next); + if (next) next.prev = this.next; + } + + // Insert a value right before the node. + insertBefore(val) { + const prev = this.prev; + this.prev = new ListNode(prev, val, this); + if (prev) prev.next = this.prev; + } + + delete() { + if (this.prev) this.prev.next = this.next; + if (this.next) this.next.prev = this.prev; + } +} + +class List { + constructor() { + this.head = null; + this.tail = null; + } + + // Insert at the front of the list + unshift(val) { + if (!this.head) { + this.head = new ListNode(null, val, this.tail); + } else if (!this.tail) { + this.tail = this.head; + this.head = new ListNode(null, val, this.tail); + this.tail.prev = this.head; + } else { + this.head = new ListNode(null, val, this.head); + this.head.next.prev = this.head; + } + } + + // Remove from the front of the list + shift() { + if (!this.head) { + if (!this.tail) return null; + return this.pop(); + } else { + const head = this.head; + this.head = this.head.next; + this.head.prev = null; + return head.val; + } + } + + // Insert at the end of the list. + push(val) { + if (!this.tail) { + this.tail = new ListNode(this.head, val, null); + } else if (!this.head) { + this.head = this.tail; + this.tail = new ListNode(this.head, val, null); + this.head.next = this.tail; + } else { + this.tail = new ListNode(this.tail, val, null); + this.tail.prev.next = this.tail; + } + } + + // Delete at the end of the list. + pop() { + if (!this.tail) { + if (!this.head) return null; + return this.shift(); + } else { + const tail = this.tail; + this.tail = this.tail.prev; + this.tail.next = null; + return tail.val; + } + } + + // Move a node to the front of the List + moveToFront(node) { + if (node === this.tail) { + this.pop(); + } else { + node.delete(); + } + this.unshift(node.val); + } + + // Move a node to the end of the List + moveToEnd (node) { + if (node === this.head) { + this.shift(); + } else { + node.delete(); + } + this.push(node.val); + } + + // Convert to an array + toArray() { + const next = this.head || this.tail; + const result = []; + while (next) { + result.push(next.val); + next = next.next; + } + return result; + } +} + +module.exports = LRUCache; diff --git a/cc28stackOfPlates/solution.js b/cc28stackOfPlates/solution.js new file mode 100644 index 0000000..57f9708 --- /dev/null +++ b/cc28stackOfPlates/solution.js @@ -0,0 +1,80 @@ +// cc28 stackOfPlates + +/* Stack of Plates: Imagine a (literal) stack of plates. If the stack gets too high, + * it might topple. + * Therefore, in real life, we would likely start a new stack when the previous stack + * exceeds some threshold. + * Implement a data structure SetOfStacks that mimics this. + * SetOfStacks should be composed of several stacks and should create a new stack + * once the previous one exceeds capacity. + * SetOfStacks.push() and SetOfStacks.pop() should behave identically to a single + * stack (that is, pop( ) should return the same values as it would if there were + * just a single stack). + */ +// [[1,2,3,4,5], [6,7,8,9,0], []] +class StackOfPlates { + // contructor, and needs to take in a number that we set as stack height + // make a _stack holder + // set _stackheight as given. + + // make push (value) + // if _topStack.length === _stackHeight + // _stack.push([value]) + // return length + // _topStack.push(value) + // return length + // make pop + // if _topStack.length === 0 && length > 1 + // _stacks.pop() + // return _topStack.pop() + // return _topStack.pop() + // get length + // (return _stacks.length - 1) * _stackHeight + _topStack.length; + // get _topStack + // return _stacks[_stacks.length - 1]; + + constructor(n = 5) { + this._stacks = [[]]; + this._limit = n; + } + + push(value) { + if (this._topStack.length === this._limit) { + this._stacks.push([value]); + return this.length; + } + this._topStack.push(value); + return this.length; + } + + pop() { + if (this._topStack.length === 0 && this._stacks.length > 1) { + this._stacks.pop(); +// return this._topStack.pop(); + } + return this._topStack.pop(); + } + + get length() { + return (this._stacks.length - 1) * this._limit + this._topStack.length; + } + + get _topStack() { + return this._stacks[this._stacks.length - 1]; + } +} + +const stack = new StackOfPlates(2); +stack.push('a'); +stack.push('b'); +stack.push('c'); +stack.push('d'); +stack.push('e'); +console.log(stack); +stack.pop(); +stack.pop(); +stack.pop(); +stack.pop(); +stack.pop(); +stack.pop(); +console.log(stack); diff --git a/cc28stackOfPlates/stackOfPlates.js b/cc28stackOfPlates/stackOfPlates.js new file mode 100644 index 0000000..bf85aec --- /dev/null +++ b/cc28stackOfPlates/stackOfPlates.js @@ -0,0 +1,69 @@ +/* cc28 stackOfPlates + * Stack of Plates: Imagine a (literal) stack of plates. + If the stack gets too high, it might topple. + Therefore, in real life, we would likely start a new stack + when the previous stack exceeds some threshold. + * 1) Implement a data structure SetOfStacks that mimics this. + * 2) SetOfStacks should be composed of several stacks and + should create a new stack once the previous one exceeds capacity. + * 3) SetOfStacks.push() and SetOfStacks.pop() should behave identically to a single stack + (that is, pop( ) should return the same values as it would if there were just a single stack). + */ + +class Stack { + constructor() { + this.storage = []; + } + get size() { + return this.storage.length; + } + add(anItem) { + return this.storage.push(anItem); + } + remove() { + if (this.storage.length === 0) return null; + return this.storage.pop(); + } +}; + +class SetOfStacks { + constructor(limit = 3) { + this.limit = limit; + this.storage = []; + this.size = 0; + // this.stack = new Stack(); + } + size() { + return this.size; + } + push(aStack) { + if (this.size === this.limit) { + return new SetOfStacks.push(aStack); // <~~~ Nope + } else { + this.size++; + return this.storage.push(aStack); + } + } + pop() { + if (this.storage.length === 0) { + return null; + } else { + this.size-- + return this.storage.pop(); + } + } +}; + +// TEST SUITE +pancake1 = new Stack(); +pancake2 = new Stack(); +pancake3 = new Stack(); +pancake4 = new Stack(); +pancakeSet = new SetOfStacks(); +console.log(pancake1); +console.log(pancakeSet); +pancakeSet.add(pancake1); +pancakeSet.add(pancake2); +pancakeSet.add(pancake3); +console.log(pancakeSet); +pancakeSet.add(pancake4); diff --git a/robotPaths/robotPaths.js b/cc29robotPaths/robotPaths.js similarity index 92% rename from robotPaths/robotPaths.js rename to cc29robotPaths/robotPaths.js index 7a05070..8cf4e7c 100644 --- a/robotPaths/robotPaths.js +++ b/cc29robotPaths/robotPaths.js @@ -1,4 +1,4 @@ -/* +/* cc29 robotPaths * * A robot located at the top left corner of a 5x5 grid is trying to reach the * bottom right corner. The robot can move either up, down, left, or right, @@ -29,4 +29,5 @@ const makeBoard = (n) => { return board; }; -// write your code here for t \ No newline at end of file +// write your code here for t +console.log(makeBoard(5)); diff --git a/cc29robotPaths/solution.js b/cc29robotPaths/solution.js new file mode 100644 index 0000000..5c1c0bf --- /dev/null +++ b/cc29robotPaths/solution.js @@ -0,0 +1,83 @@ +// cc29 robotPaths + +[ + [ true, false, false, false, false ], + [ false, false, false, false, false ], + [ false, false, false, false, false ], + [ false, false, false, false, false ], + [ false, false, false, false, "destination" ] +] + +/* + * + * A robot located at the top left corner of a 5x5 grid is trying to reach the + * bottom right corner. The robot can move either up, down, left, or right, + * but cannot visit the same spot twice. How many possible unique paths are + * there to the bottom right corner? + * + * EC: Make your solution work for a grid of any size. + * + */ + +const makeBoard = (n) => { + // this function will build a board nXn for your robot to traverse + let board = []; + for (let i = 0; i < n; i++) { + board.push([]); + for (let j = 0; j < n; j++) { + board[i].push(false); + } + } + board.toggle = (i, j) => { + // this function is given to help you toggle the board's square + board[i][j] = !board[i][j] + }; + board.hasBeenVisited = (i, j) => { + // this function is given to help you check to see if you've been at the square + return board[i][j] + }; + return board; +}; + +// write your code here for robotPaths + + +const robotPaths = (n) => { + // make a board size n + // keep a path counter. + // create a path tracking function that we can call recursively (takes in location) (i, j) + // basecase: check to see if function has arrived. if true, pathcounter++; + // check to see if its out of bounds i < 0, j < 0, i >= n, j >= n + // check to see if we've already been here. + // + // board.toggle(i, j) + // recurse(i, j + 1); + // recurse(i + 1, j); + // recurse(i, j - 1); + // recurse(i - 1, j); + // recurse(0, 0); + // return pathCounter; + const board = makeBoard(n); + let pathCounter = 0; + + const traverse = (i, j) => { + if (i === n - 1 && j === n - 1) { + pathCounter++; + return; + } + if (i < 0 || j < 0 || i >= n || j >= n) return; + if (board.hasBeenVisited(i, j)) return; + else { + board.toggle(i, j); + traverse(i, j + 1); + traverse(i + 1, j); + traverse(i, j - 1); + traverse(i - 1, j); + board.toggle(i, j); + } + }; + traverse(0, 0); + return pathCounter; +}; + +console.log(robotPaths(5)); diff --git a/cc30commonCharacters/commonCharacters.js b/cc30commonCharacters/commonCharacters.js new file mode 100644 index 0000000..f16b92a --- /dev/null +++ b/cc30commonCharacters/commonCharacters.js @@ -0,0 +1,64 @@ +/** cc30 commonCharacters + * Common Characters: + * Write a function that accepts two strings as arguments, and returns only the characters that are common to both strings. * + * Your function should return the common characters in the same order that they appear in the first argument. + * Do not return duplicate characters and ignore whitespace in your returned string. * + * Example: commonCharacters('acexivou', 'aegihobu') * + * Returns: 'aeiou' +*/ +/* INPUT: 2 strings + FUNCTION: split, remove white space, Set to make unique, compare if match, add to return + OUTPUT: 1 string +*/ + +// const commonCharacters = (str1, str2) => { +// const arr1 = str1.split(''); +// const arr2 = str2.split(''); +// const set1 = new Set(arr1); +// const set2 = new Set(arr2); +// console.log(arr1); +// console.log(arr2); +// console.log(set1); +// console.log(set2); +// const arr3 = arr1.concat(arr2); +// console.log(arr3); +// const set3 = new Set(arr3); +// console.log(set3); +// } + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has +const commonCharacters = (str1, str2) => { + // const str1 = str11.replace(' ', ''); + // console.log(str1); + // console.log(str1); + // const str2 = str22.replace(' ', ''); + const arr1 = str1.replace(' ', '').split(''); + const arr2 = str2.replace(' ', '').split(''); + console.log(arr1); + console.log(arr2); + const set1 = new Set(arr1); + console.log(set1); + const set2 = new Set(arr2); + console.log(set2); + const intersection = [...set1].filter(letter => set2.has(letter)); + const result = intersection.join(''); + return result; +}; + + +// console.log(commonCharacters('acexivou', 'aegihobu')); // ~~~> 'aeiou' +console.log(commonCharacters('ac e x i v o u', 'a e g i h o b u')); // ~~~> 'aeiou' + + +// Lois's solution +// const commonCharacters = (str1, str2) => { +// let tempSet = new Set(str2); +// let ansStr = ''; +// for (let i = 0; i < str1.length; i++) { +// if (tempSet.has(str1[i]) && str1[i] !== ' ') { +// ansStr += str1[i]; +// } +// } +// return ansStr; +// }; diff --git a/cc30commonCharacters/solution.js b/cc30commonCharacters/solution.js new file mode 100644 index 0000000..a001b23 --- /dev/null +++ b/cc30commonCharacters/solution.js @@ -0,0 +1,43 @@ +/** + * Common Characters: + * Write a function that accepts two strings as arguments, and returns only the characters that are common to both strings. * + * Your function should return the common characters in the same order that they appear in the first argument. + * Do not return duplicate characters and ignore whitespace in your returned string. * + * Example: commonCharacters('acexivou', 'aegihobu') * + * Returns: 'aeiou' +*/ + +const commonCharacters = (str1, str2) => { + // we need a dictionary (obj) preset " " to 3; + // let str = ""; + // iterate over the second string, for each + // if !object[char] object[char] = 1; + // iterate over the first string, for each + // if (object[char] === 1) + // object[char] = 2; + // str += char; + // return str; + const obj = {' ': 3}; + let str = ''; +// str2.forEach((char) => { +// if (!obj[char]) obj[char] = 1; +// }); + for (let i = 0; i < str2.length; i++) { + if (!obj[str2[i]]) obj[str2[i]] = 1; + } +// str1.forEach((char) => { +// if (obj[char] === 1) { +// obj[char] = 2; +// str += char; +// } +// }); + for (let i = 0; i < str1.length; i++) { + if (obj[str1[i]] === 1) { + obj[str1[i]] = 2; + str += str1[i]; + } + } + return str; +}; + +console.log(commonCharacters('acex ivou', 'ae gihobu')); diff --git a/cc31fizzBuzzTesting/.babelrc b/cc31fizzBuzzTesting/.babelrc new file mode 100644 index 0000000..bea32a4 --- /dev/null +++ b/cc31fizzBuzzTesting/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": [ "es2015" ] +} diff --git a/cc31fizzBuzzTesting/.eslintrc.json b/cc31fizzBuzzTesting/.eslintrc.json new file mode 100644 index 0000000..ca3b098 --- /dev/null +++ b/cc31fizzBuzzTesting/.eslintrc.json @@ -0,0 +1,24 @@ +{ + "extends": "airbnb-base", + "plugins": [ + "import" + ], + "consistent-return": 0, + "rules": { + "no-param-reassign": 0, + "max-len": 0, + "no-plusplus": 0, + "linebreak-style": 0, + "consistent-return": 0, + "no-useless-return": 0, + "no-return-assign": 0, + "comma-dangle": 0, + "arrow-body-style": 0, + "max-len": 0, + "no-unused-vars": 0, + "no-useless-constructor": 0, + "no-extend-native": 0, + "import/no-unresolved": 0, + "no-restricted-properties": 0 + } +} diff --git a/cc31fizzBuzzTesting/.gitignore b/cc31fizzBuzzTesting/.gitignore new file mode 100644 index 0000000..5e52727 --- /dev/null +++ b/cc31fizzBuzzTesting/.gitignore @@ -0,0 +1,2 @@ +/node_modules +package-lock.json diff --git a/cc31fizzBuzzTesting/package.json b/cc31fizzBuzzTesting/package.json new file mode 100644 index 0000000..dfa316b --- /dev/null +++ b/cc31fizzBuzzTesting/package.json @@ -0,0 +1,40 @@ +{ + "name": "fizzbuzztesting", + "version": "1.0.0", + "description": "fizz buzz fizzbuzz", + "main": "fizzBuzz.js", + "scripts": { + "test": "eslint tests/*.js && eslint src/*.js && mocha -R nyan", + "watch": "npm test -- --watch" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/mixelpixel/CS1-Code-Challenges.git" + }, + "keywords": [ + "fizz", + "buzz", + "fizzbuzz", + "testing" + ], + "author": "Patrick Kennedy", + "license": "ISC", + "devDependencies": { + "chai": "^4.1.1", + "eslint": "^3.17.1", + "eslint-config-airbnb-base": "^11.1.3", + "eslint-plugin-import": "^2.2.0", + "mocha": "^3.5.0", + "regenerator-runtime": "^0.10.3", + "sinon": "^3.0.0", + "sinon-chai": "^2.12.0" + }, + "dependencies": { + "babel-preset-es2015": "^6.24.0", + "eslint-config-airbnb": "^14.1.0" + }, + "bugs": { + "url": "https://github.com/mixelpixel/CS1-Code-Challenges/issues" + }, + "homepage": "https://github.com/mixelpixel/CS1-Code-Challenges#readme" +} diff --git a/cc31fizzBuzzTesting/solutionJest/.gitignore b/cc31fizzBuzzTesting/solutionJest/.gitignore new file mode 100644 index 0000000..07e6e47 --- /dev/null +++ b/cc31fizzBuzzTesting/solutionJest/.gitignore @@ -0,0 +1 @@ +/node_modules diff --git a/cc31fizzBuzzTesting/solutionJest/fizzBuzz.js b/cc31fizzBuzzTesting/solutionJest/fizzBuzz.js new file mode 100644 index 0000000..dea4457 --- /dev/null +++ b/cc31fizzBuzzTesting/solutionJest/fizzBuzz.js @@ -0,0 +1,67 @@ +/* + * Create the function fizzBuzz that takes a single integer as an argument. + * Return 'fizz' if num is divisible by 3 with no remainder. + * Return 'buzz' if num is divisible by 5 with no remainder. + * Return 'fizzbuzz' if num is divisible by both 3 and 5 with no remainder. + * If the number is not divisible by either 3 or 5 then return the number given as the argument. + * Before you write your function write automated tests to test this function. + * The main focus of this challenge is the testing aspect of it. + */ + +const fizzBuzz = (num) => { + if (num % 15 === 0) return 'fizzbuzz'; + if (num % 3 === 0) return 'fizz'; + if (num % 5 === 0) return 'buzz'; + return num; +}; + +module.exports = fizzBuzz; + +/* +$ npm init +This utility will walk you through creating a package.json file. +It only covers the most common items, and tries to guess sensible defaults. + +See `npm help json` for definitive documentation on these fields +and exactly what they do. + +Use `npm install ` afterwards to install a package and +save it as a dependency in the package.json file. + +Press ^C at any time to quit. +package name: (solutionjest) fizzbuzztesting +version: (1.0.0) +description: TDD +entry point: (fizzBuzz.js) +test command: jest --watch +git repository: +keywords: +author: pdk +license: (ISC) +About to write to /Users/mixelpix/Lambda-University/CS1-Code-Challenges/fizzBu +zzTesting/solutionJest/package.json: + +{ + + "name": "fizzbuzztesting", + "version": "1.0.0", + "description": "TDD", + "main": "fizzBuzz.js", + "scripts": { + "test": "jest --watch" + }, + "author": "pdk", + "license": "ISC" +} + + +Is this ok? (yes) +6 mixelpix Tue Aug 22 13:21:19$ npm i --save-dev jest +npm notice created a lockfile as package-lock.json. You should commit this fil +e. +npm WARN fizzbuzztesting@1.0.0 No repository field. + + ++ jest@20.0.4 +added 335 packages in 43.477s +*/ diff --git a/cc31fizzBuzzTesting/solutionJest/fizzBuzz.test.js b/cc31fizzBuzzTesting/solutionJest/fizzBuzz.test.js new file mode 100644 index 0000000..0090710 --- /dev/null +++ b/cc31fizzBuzzTesting/solutionJest/fizzBuzz.test.js @@ -0,0 +1,25 @@ +// cc31 fizzBuzzTesting +const fizzBuzz = require('../fizzBuzz'); + +/* global describe it expect */ +describe('fizzbuzz', () => { + it('should return fizzbuzz when the number is divisible by 3 and 5', () => { + expect(fizzBuzz(15)).toEqual('fizzbuzz'); + expect(fizzBuzz(30)).toEqual('fizzbuzz'); + }); + it('should return fizz when the number is divisible by 3 only', () => { + expect(fizzBuzz(3)).toEqual('fizz'); + expect(fizzBuzz(12)).toEqual('fizz'); + expect(fizzBuzz(24)).toEqual('fizz'); + }); + it('should return buzz when the number is divisible by 5 only', () => { + expect(fizzBuzz(20)).toEqual('buzz'); + expect(fizzBuzz(25)).toEqual('buzz'); + expect(fizzBuzz(40)).toEqual('buzz'); + }); + it('should return the number when the number is not divisible by 3 or 5', () => { + expect(fizzBuzz(22)).toEqual(22); + expect(fizzBuzz(26)).toEqual(26); + expect(fizzBuzz(41)).toEqual(41); + }); +}); diff --git a/cc31fizzBuzzTesting/solutionJest/package.json b/cc31fizzBuzzTesting/solutionJest/package.json new file mode 100644 index 0000000..53c9dd3 --- /dev/null +++ b/cc31fizzBuzzTesting/solutionJest/package.json @@ -0,0 +1,14 @@ +{ + "name": "fizzbuzztesting", + "version": "1.0.0", + "description": "TDD", + "main": "fizzBuzz.js", + "scripts": { + "test": "jest --watch" + }, + "author": "pdk", + "license": "ISC", + "devDependencies": { + "jest": "^20.0.4" + } +} diff --git a/cc31fizzBuzzTesting/src/fizzBuzz.js b/cc31fizzBuzzTesting/src/fizzBuzz.js new file mode 100644 index 0000000..854b172 --- /dev/null +++ b/cc31fizzBuzzTesting/src/fizzBuzz.js @@ -0,0 +1,32 @@ +/* cc31 fizzBuzzTesting + * Create the function fizzBuzz that takes a single integer as an argument. + * Return 'fizz' if num is divisible by 3 with no remainder. + * Return 'buzz' if num is divisible by 5 with no remainder. + * Return 'fizzbuzz' if num is divisible by both 3 and 5 with no remainder. + * If the number is not divisible by either 3 or 5 then return the number given as the argument. + * Before you write your function write automated tests to test this function. + * The main focus of this challenge is the testing aspect of it. + */ + +const fizzBuzz = (num) => { +// if num is divisible by 3 return 'fizz' +// if num is divisible by 5 return 'buzz' +// if num is divisible by 3 & 5 return 'fizzbuzz' +// otherwise return num + if (num % 3 === 0 && num % 5 === 0) { + return 'fizzbuzz'; + } else if (num % 5 === 0) { + return 'buzz'; + } else if (num % 3 === 0) { + return 'fizz'; + } return num; +}; + +// // TEST SUITE: +// /* eslint no-console: 0 */ +// console.log(fizzBuzz(6)); // ~~~> 'fizz' +// console.log(fizzBuzz(10)); // ~~~> 'buzz' +// console.log(fizzBuzz(15)); // ~~~> 'fizzbuzz' +// console.log(fizzBuzz(44)); // ~~~> '44' + +module.exports = { fizzBuzz }; diff --git a/cc31fizzBuzzTesting/test/fizzBuzz.test.js b/cc31fizzBuzzTesting/test/fizzBuzz.test.js new file mode 100644 index 0000000..a6e9ebf --- /dev/null +++ b/cc31fizzBuzzTesting/test/fizzBuzz.test.js @@ -0,0 +1,63 @@ +// cc31 fizzBuzzTesting +const fizzBuzzScript = require('../src/fizzbuzz'); +const assert = require('chai').assert; +const chai = require('chai'); +const sinon = require('sinon'); + +const expect = chai.expect; + +/* global describe it */ +describe('FizzBuzz Test', () => { + const fizzBuzz = fizzBuzzScript.fizzBuzz; + + describe('#1: fizzBuzz imports from the script file and ', () => { + it('should be a function', () => { + assert.typeOf(fizzBuzz, 'function'); + expect(fizzBuzz).to.be.a('function'); + }); + }); + + describe('#2: fizzBuzz returns correct value types,', () => { + it('should return a `String` when conditions are met', () => { + assert.typeOf(fizzBuzz(15), 'string'); + assert.typeOf(fizzBuzz(9), 'string'); + assert.typeOf(fizzBuzz(10), 'string'); + expect(fizzBuzz(15)).to.be.a('string'); + expect(fizzBuzz(9)).to.be.a('string'); + expect(fizzBuzz(10)).to.be.a('string'); + }); + it('should return a `Number` when conditions are not met', () => { + assert.typeOf(fizzBuzz(4), 'number'); + expect(fizzBuzz(4)).to.be.a('number'); + }); + it('should return the given argument when conditions are not met', () => { + assert.equal(fizzBuzz(44), 44); + assert.equal(fizzBuzz('x'), 'x'); + assert.equal(fizzBuzz(true), true); + expect(fizzBuzz(44)).equals(44); + expect(fizzBuzz('x')).equals('x'); + expect(fizzBuzz(true)).equals(true); + }); + }); + + describe('#3: fizz', () => { + it('should return `fizz` when the argument % 3 === 0', () => { + assert.equal(fizzBuzz(6), 'fizz'); + expect(fizzBuzz(9)).to.equal('fizz'); + }); + }); + + describe('#4: buzz', () => { + it('should return `buzz` when the argument % 5 === 0', () => { + assert.equal(fizzBuzz(10), 'buzz'); + expect(fizzBuzz(10)).to.equal('buzz'); + }); + }); + + describe('#5: fizzbuzz', () => { + it('should return `fizzbuzz` when the argument % 3 ===0 && % 5 === 0', () => { + assert.equal(fizzBuzz(15), 'fizzbuzz'); + expect(fizzBuzz(15)).to.equal('fizzbuzz'); + }); + }); +}); diff --git a/cc32longestRun/longestRun.js b/cc32longestRun/longestRun.js new file mode 100644 index 0000000..055b473 --- /dev/null +++ b/cc32longestRun/longestRun.js @@ -0,0 +1,86 @@ +/* cc32 longestRun +INPUT: string +FUNCTION: longest run of any identical character +OUTPUT: array containing start and end indices of longest run + (first if more than one, [ 0, 0 ] if none) +*/ + +const longestRun = (str) => { + let current = [0, 0]; + let longest = [0, 0]; + let i = 1; + const len = str.length; + + for (i; i < len; i++) { + if (str[i - 1] === str[i]) { + current[1] = i; + if (current[1] - current[0] > longest[1] - longest[0]) { + longest = current; + } + } else current = [i, i]; + } + return longest; +}; + + +// const longestRun = (str) => { +// const len = str.length; +// let count = 0; +// let highestCount = 0; +// let i = 0; +// let startIndex; +// let endIndex; +// let result = [ startIndex, endIndex ]; +// for (i; i < len; i++) { +// if (str[i] !== str[i + 1]) { +// count = 0; +// } else if (str[i] === str[i + 1] && count === 0) { +// startIndex = i; +// count++; +// } else if (str[i] === str[i + 1]) { +// count++; +// } else if (str[i] !== str[i + 1] && count !== 0) { +// endIndex = i; +// if (count > highestCount) { +// [ count, highestCount ] = [ 0, count ]; +// result = [ startIndex, endIndex ]; +// } +// } else { +// count = 0; +// } +// } +// return result; +// }; + +// TEST SUITE +console.log(longestRun('aaaaaabbbcc')); // ~~~> [ 0, 5 ] +console.log(longestRun('abbbcc')); // ~~~> [ 1, 3 ] +console.log(longestRun('mississippi')); // ~~~> [ 2, 3 ] +console.log(longestRun('abcdefgh')); // ~~~> [ 0, 0 ] +console.log(longestRun('aabbbcccc')); // ~~~> [ 5, 8 ] + + + + + + + + + + + + + + +/* +* Write a function that, given a string, finds the longest run of +* identical characters and returns an array containing the start +* and end indices of that run. +* If there are two runs of equal length, return the first one. +* Return [0,0] for no runs. +* Examples: +* Input: "abbbcc" Output: [ 1, 3 ] +* Input: "mississippi" Output: [ 2, 3 ] +* Input: "abcdefgh" Output: [ 0, 0 ] +* Input: "aabbbcccc" Output: [ 5, 8 ] +*/ diff --git a/breadthFirstSearch/breadthFirstSearch.js b/cc33breadthFirstSearch/breadthFirstSearch.js similarity index 93% rename from breadthFirstSearch/breadthFirstSearch.js rename to cc33breadthFirstSearch/breadthFirstSearch.js index 1bdb76d..03790bd 100644 --- a/breadthFirstSearch/breadthFirstSearch.js +++ b/cc33breadthFirstSearch/breadthFirstSearch.js @@ -1,4 +1,4 @@ -/* +/* cc33 breadthFirstSearch * Write a function that accepts a tree data structure and a value to search for. * Search for the value using a breadth-first search algorithm. * You can read about it here: https://en.wikipedia.org/wiki/Breadth-first_search @@ -14,4 +14,4 @@ * a: 2, * }; * breadthFirstSearch(tree, 2);// will return true before it recursively searches `z` - */ \ No newline at end of file + */ diff --git a/cc33breadthFirstSearch/solution.js b/cc33breadthFirstSearch/solution.js new file mode 100644 index 0000000..8a23605 --- /dev/null +++ b/cc33breadthFirstSearch/solution.js @@ -0,0 +1,28 @@ +/* eslint no-console: 0 */ + +const breadthFirstSearch = (tree, searchTerm) => { + let queue = Object.values(tree); + while (queue.length > 0) { + let value = queue.shift(); + if (value === searchTerm) return true; + if (typeof value === 'object' && value !== null && !Array.isArray(value)) { + queue = queue.concat(Object.values(value)); + } + } + return false; +}; + +// TEST SUITE +const tree = { + x: 1, + y: 1, + z: { + x: 1, + y: 1, + z: 1, + }, + a: 2, +}; + +console.log(Object.values(tree)); +console.log(breadthFirstSearch(tree, 2)); diff --git a/cc33breadthFirstSearch/steves_idea.js b/cc33breadthFirstSearch/steves_idea.js new file mode 100644 index 0000000..4194e5b --- /dev/null +++ b/cc33breadthFirstSearch/steves_idea.js @@ -0,0 +1,16 @@ +// Steve's idea: +const equalityCheck = (x, y) => { + if (x === y) return true; +} + +const breadthFirstSearch = (tree, searchTerm) => { + let queue = Object.values(tree); + while (queue.length > 0) { + value = queue.shift(); + if(equalityCheck(value, searchTerm)); + if (typeof value === 'object' && value !== null && !Array.isArray(value)) { + queue = queue.concat(Object.values(value)); + } + } + return false; +}; diff --git a/cc34vowelCount/solution.js b/cc34vowelCount/solution.js new file mode 100644 index 0000000..61879fa --- /dev/null +++ b/cc34vowelCount/solution.js @@ -0,0 +1 @@ +// Tai used .toLowerCase with the for-if loop diff --git a/cc34vowelCount/vowelCount.js b/cc34vowelCount/vowelCount.js new file mode 100644 index 0000000..ac50d6c --- /dev/null +++ b/cc34vowelCount/vowelCount.js @@ -0,0 +1,32 @@ +/* cc34 vowelCount + * Write a function that returns the count of the total number of vowels in a string. + * Example: 'Hello World!' -> 3 + */ + +// // version 1: O(n) but is it O(2 + n^2) because the if() condition is an array? +const vowelCount = (str) => { + let count = 0; + for (let i = 0; i < str.length; i++) { + // lowercase vowels only + if (str[i] === 'a' || str[i] === 'e' || str[i] === 'i' || str[i] === 'o' || str[i] === 'u') { + count++; + } + } + return count; +}; + +// // version 2: Big O? +// const vowelCount = str => Array.from(str) +// .filter(vowel => 'aeiouAEIOU'.includes(vowel)).length; + +// // version 3: Big O? +// // per: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions +// // g Global search. +// // i Case-insensitive search. +// const vowelCount = str => +// (str.match(/[aeiou]/gi) == null) ? 0 : str.match(/[aeiou]/gi).length; + +console.log(vowelCount('qwrtypsdfghjklzxcvbnm')) // ~~~> 0 +console.log(vowelCount('Hello World!')); // ~~~> 3 +console.log(vowelCount('The quick brown fox jumped over the lazy dog.')); // ~~~> 12 +console.log(vowelCount('Four score and twenty years ago... Our forefathers All In United')); // ~~~> 21 diff --git a/cc35meanMedianMode/meanMedianMode.js b/cc35meanMedianMode/meanMedianMode.js new file mode 100644 index 0000000..31dedbf --- /dev/null +++ b/cc35meanMedianMode/meanMedianMode.js @@ -0,0 +1,51 @@ +/* cc35 meanMedianMode + * Given an array of numbers calculate the mean, median, and mode. + * Return an object with properties for the mean, median, and mode. + */ + +const meanMedianMode = (arr) => { + // MEAN + // sum of nums in arr of nums + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce + const numOfNums = arr.length; + // let i = 0, + // sum = 0; + // for (i; i < numOfNums; i++) { + // sum += arr[i]; + // } + // console.log(sum); + // const mean = sum / numOfNums; + // return mean; + // console.log(mean); + const total = arr.reduce((accumulation, currentIndexValue) => accumulation + currentIndexValue, 0); + const mean = total / numOfNums; + + // MEDIAN + // https://www.mathsisfun.com/definitions/median.html + // of sorted arr of nums, middle term + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort + // if even number of terms, average of two middle terms + // if odd, middle term + const median = (arr) => { + const array = arr; + array.sort((a, b) => a - b); + console.log(array); + if (numOfNums %2 === 0) { + return (array[numOfNums / 2 - 1] + array[numOfNums / 2]) / 2; + } + return array[Math.floor(numOfNums / 2)]; + } + + // MODE + // item in array which appears the most times + // const mode = + return [`Number of numbers:${numOfNums}, Total: ${total}, Mean: ${mean}, Median: ${median(arr)}`]; + // return [`Number of numbers:${numOfNums}, Total: ${total}, Mean: ${mean}, Median: ${median}, Mode: ${mode}.`]; + // return { mean, median, mode }; +}; + +// TEST SUITE +console.log(meanMedianMode([ 0, 1, 2, 3, 4, 5 ])); +console.log(meanMedianMode([ 10, -11, 12, -13, 14, -15 ])); +console.log(meanMedianMode([ 8, 24, 9, 32, 1, 11 ])); +console.log(meanMedianMode([ 13, 23, 11, 16, 15, 10, 26 ])); diff --git a/cc35meanMedianMode/solution.js b/cc35meanMedianMode/solution.js new file mode 100644 index 0000000..711b177 --- /dev/null +++ b/cc35meanMedianMode/solution.js @@ -0,0 +1,68 @@ +// cc35 meanMedianMode +// https://repl.it/K3ka/4 + +/* + * Given an array of numbers calculate the mean, median, and mode. + * Return an object with properties for the mean, median, and mode. + */ + + const array = [3, 4, 4, 6, 12, 3, 4, 5, 13]; + + const findMMM = (arr) => { + // create three variables mean, median mode. + let mean = {}; + let median = {}; + let mode = {}; + // create an object to store mean, median and mode + let MMM = {}; + // initialize a sorted version of our given array. + const sortedArr = arr.sort((a, b) => { + return a - b; + }); + console.log("sorted", sortedArr); + // create a findMean func, to find the mean + const findMean = (newArr) => { + let newMean = 0; + // loop over our given array, addUp all values + newArr.forEach((num) => { + newMean += num; + }); + // divide by length of array. + newMean = newMean / newArr.length; + return Math.round(newMean); + } + + const findMedian = (arr) => { + const evenMedian = []; + let middle = Math.floor(arr.length / 2); + if (arr.length % 2 === 0) { + // take middle two nums and add them to evenMedian + evenMedian.push(arr[middle], array[middle-1]); + return findMean(evenMedian); + } + return arr[middle]; + } + + const findMode = (newArr) => { + const mapping = {}; + let count = 0; + let mode; + newArr.forEach((num) => { + mapping[num] = (mapping[num] || 0) + 1; + if (count < mapping[num]) { + count = mapping[num]; + mode = num; + } + }); + return mode; + } + mean = findMean(arr); + median = findMedian(sortedArr); + mode = findMode(sortedArr); + MMM.mean = mean; + MMM.median = median; + MMM.mode = mode; + return MMM; + } + + console.log(findMMM(array)); diff --git a/cc36sumOfDigits/solution.js b/cc36sumOfDigits/solution.js new file mode 100644 index 0000000..f3f5e3f --- /dev/null +++ b/cc36sumOfDigits/solution.js @@ -0,0 +1,5 @@ +function sumOfDigits(num) { + const digits = (num + '').split('').map(num => parseInt(num)); + const sum = digits.reduce((sum, n) => sum + n); + return sum; +} diff --git a/cc36sumOfDigits/sumOfDigits.js b/cc36sumOfDigits/sumOfDigits.js new file mode 100644 index 0000000..ba83d40 --- /dev/null +++ b/cc36sumOfDigits/sumOfDigits.js @@ -0,0 +1,42 @@ +/* cc36 sumOfDigits - https://repl.it/student/submissions/1448448 +Write a function called sumOfDigits that given a positive integer, returns the sum of its digits. +Assume all numbers will be positive. + +Input Sample: +23 +496 + +Output Sample: +5 +19 +*/ + +// function sumOfDigits (num) { +// const integers = ('' + num).split(''); +// const len = integers.length; +// // console.log(integers); +// let i = 0, +// sum = 0; +// for (i; i Number(num)); + // console.log(`integers: ${integers} are: ${typeof(integers[0])}`); + const sum = integers.reduce((sum, n) => sum + n, 0); + return sum; +} + +/* eslint no-console: 0 */ +// TEST SUITE +const x = 12345; +console.log(sumOfDigits(x)); // ~~~> 15 +console.log(sumOfDigits(23)); // ~~~> 5 +console.log(sumOfDigits(496)); // ~~~> 19 +console.log(typeof(sumOfDigits(496))); // ~~~> number diff --git a/cc37armstrongNumbers/armstrongNumbers.js b/cc37armstrongNumbers/armstrongNumbers.js new file mode 100644 index 0000000..a65c64b --- /dev/null +++ b/cc37armstrongNumbers/armstrongNumbers.js @@ -0,0 +1,49 @@ +/* cc37 armstrongNumbers https://repl.it/student/submissions/1454546 +An Armstrong number is an n-digit number that is equal to the sum of +the n'th powers of its digits. Determine if the input numbers are +Armstrong numbers. Return either true or false . + +For example with the number 153 there are 3 digits so you would +add together the cubed values of all the digits like this: +1^3 + 5^3 + 3^3 === 153 + +Input Sample: + +6 +153 +351 + +Output Sample: + +true +true +false +*/ + +function isArmstrongNumber(n) { + // number of terms in integer => exponential value + stringNum = String(n); // ~~~~> also toString() + // console.log(stringNum); + exponent = stringNum.length; + // console.log(exponent); + stringNumArray = stringNum.split(''); + // console.log(stringNumArray); + numArray = stringNumArray.map((x) => Number(x)); + // console.log(numArray); + // base case + if (exponent === 1) { + return true; + } + // for each term in integer + sumOfExponents = numArray.map((x) => Math.pow(x, exponent)).reduce((sum, value) => sum + value); + // console.log(sumOfExponents); + if (n === sumOfExponents) { + return true; + } + return false; +} + +// // TEST SUITE +// console.log(isArmstrongNumber(6)); // ~~~> true +// console.log(isArmstrongNumber(153)); // ~~~> true +// console.log(isArmstrongNumber(351)); // ~~~> false diff --git a/cc37armstrongNumbers/solution.js b/cc37armstrongNumbers/solution.js new file mode 100644 index 0000000..edf7546 --- /dev/null +++ b/cc37armstrongNumbers/solution.js @@ -0,0 +1,8 @@ +// https://repl.it/student/assignments/345340/model_solution?fromSubmissionId=1454546 + +function isArmstrongNumber(n) { + let nums = n.toString().split(''); + nums = nums.map(num => Math.pow(parseInt(num), nums.length)); + const sum = nums.reduce((num, total) => num + total); + return n === sum; +} diff --git a/cc38reverseNumber/reverseNumber.js b/cc38reverseNumber/reverseNumber.js new file mode 100644 index 0000000..b776554 --- /dev/null +++ b/cc38reverseNumber/reverseNumber.js @@ -0,0 +1,31 @@ +/* cc38 reverseNumber https://repl.it/student/submissions/1460542 +Write a function called reverseNumber that reverses a number. + +Input Example: +12345 +555 + +Output Example: +54321 +555 +*/ + +function reverseNumber (num) { + // console.log(num); + string = num.toString(); + // console.log(string); + // console.log(typeof(string)); + arr = string.split(''); + // console.log(arr); + reverse = arr.reverse(); + // console.log(reverse); + join = reverse.join('') + // console.log(join); + result = Number(join); + return result; +} + + +// TEST SUITE +// console.log(reverseNumber(12345)); // ~~> 54321 +// console.log(reverseNumber(555)); // ~~> 555 diff --git a/cc38reverseNumber/solution.js b/cc38reverseNumber/solution.js new file mode 100644 index 0000000..bf827a7 --- /dev/null +++ b/cc38reverseNumber/solution.js @@ -0,0 +1,5 @@ +// https://repl.it/student/assignments/347638/model_solution?fromSubmissionId=1460542 + +function reverseNumber(num) { + return parseInt(num.toString().split('').reverse().join('')); +} diff --git a/cc39sortString/solution.js b/cc39sortString/solution.js new file mode 100644 index 0000000..1b6df57 --- /dev/null +++ b/cc39sortString/solution.js @@ -0,0 +1,36 @@ +// https://repl.it/student/assignments/351153/model_solution?fromSubmissionId=1467240 + +// function sortString(str) { +// return str.split('').sort().join(''); +// } + +// Ivan's recursive bubble sort solution +// function sortString (string) { +// let sorted = true; +// let sortedString = string.split(''); +// +// for (let i = 1; i < sortedString.length; i++) { +// if (sortedString[i].toLowerCase() < sortedString[i - 1].toLowerCase()) { +// sortedString.splice(i - 1, 0, sortedString[i]); +// sortedString.splice(i + 1, 1); +// sorted = false; +// } +// } +// +// sortedString = sortedString.join(''); +// +// return sorted === true ? sortedString : sortString(sortedString); +// } +// +// sortString('dcBa') + +// preserving case +function sortString(str) { + // console.log(str.split('')); + // console.log(str.split('').sort((a, b) => a.toLowerCase < b.toLowerCase)); + // console.log(str.toLowerCase()); + return str.split('').sort((a, b) => a.toLowerCase() > b.toLowerCase()).join(''); +} + +// TEST SUITE +console.log(sortString('dcBa')); // ~~~> 'aBcd' diff --git a/cc39sortString/sortString.js b/cc39sortString/sortString.js new file mode 100644 index 0000000..0be4d80 --- /dev/null +++ b/cc39sortString/sortString.js @@ -0,0 +1,25 @@ +/* cc39 sortString https://repl.it/student/submissions/1467240 +Write a function called sortString that returns a passed string with letters in alphabetical order. + +Expected Input: + +'dcba' +'zycxbwa' + +Expected Output: + +'abcd' +'abcwxyz' +*/ + +function sortString(str) { + // arr = str.split(''); + // console.log(arr); + // sorted = arr.sort(); + // console.log(sorted); + return str.split('').sort().join(''); +} + +// // TEST SUITE +// console.log(sortString('dcba')); // ~~~> 'abcd' +// console.log(sortString('zycxbwa')); // ~~~> 'abcwxyz' diff --git a/cc40commonElements/commonElements.js b/cc40commonElements/commonElements.js new file mode 100644 index 0000000..c442244 --- /dev/null +++ b/cc40commonElements/commonElements.js @@ -0,0 +1,38 @@ +/* cc40 commonElements https://repl.it/student/submissions/1472701 +Write a function called commonElements that has parameters for two arrays. +Return an array of all items that are present in both arrays. +Do not modify the arrays that are passed in. + +Input Example: +[1, 2, 3, 4] [3, 4, 5, 6] +['a', 'b', 'c'] ['x', 'y', 'z', 'a'] +[1, 2, 3] [4, 5, 6] + +Output Example: +[3, 4] +['a'] +[] +*/ + +function commonElements(arr1, arr2) { + const common = []; + let i; + const len = arr1.length; + for (i = 0; i < len; i++) { + arr2.forEach((item) => { + if (arr1[i] === item) { + common.push(item); + } + }); + } + // edge case of duplicates + const unique = Array.from(new Set(common)); + return unique; + // return common; +} + +/* eslint no-console: 0 */ +// TEST SUITE +console.log(commonElements([1, 2, 3, 4], [3, 4, 5, 6])); // ~~~> [3, 4] +console.log(commonElements(['a', 'b', 'c'], ['x', 'y', 'z', 'a'])); // ~~~> ['a'] +console.log(commonElements([1, 2, 3], [4, 5, 6])); // ~~~> [] diff --git a/cc40commonElements/solution.js b/cc40commonElements/solution.js new file mode 100644 index 0000000..1d11fa8 --- /dev/null +++ b/cc40commonElements/solution.js @@ -0,0 +1,9 @@ +// https://repl.it/student/assignments/355661/model_solution?fromSubmissionId=1472701 + +function commonElements(arr1, arr2) { + const matches = []; + arr1.forEach((element) => { + if (arr2.includes(element)) matches.push(element); + }); + return matches; +} diff --git a/cc41reverseLinkedList/reverseLinkedList.js b/cc41reverseLinkedList/reverseLinkedList.js new file mode 100644 index 0000000..328215d --- /dev/null +++ b/cc41reverseLinkedList/reverseLinkedList.js @@ -0,0 +1,20 @@ +/* cc41 reverseLinkedList https://repl.it/student/submissions/1489170 +Write a function that will take the head of a singly-linked list, +and reverse it, such that the head is now the tail, and the node +that head pointed to now points to the old head (the new tail). +*/ + +function reverseList(node) { +// Not quite sure how to proceed without an example data structure +// Are all singly-linked lists the same? From the test: +// Expected null to be +// Node({ value: 'C', next: Node({ value: 'D', next: null }) }) + // swap head and tail + // [ node.head, node.tail ] = [ node.tail, node.head ]; + // then reverse pointers ... ??? + // walk through the list one item at a time and put it in an array + // e.g. [head, ..., tail] + // then pop off the array iems into the Linked List function... + // but I don't have a single linked list making function here...??? + +} diff --git a/cc41reverseLinkedList/solution.js b/cc41reverseLinkedList/solution.js new file mode 100644 index 0000000..122b2ac --- /dev/null +++ b/cc41reverseLinkedList/solution.js @@ -0,0 +1,30 @@ +function reverseList(node) { + if (node.next === null) return node; + let current = node; + let previous = null; + while (current) { + let floating = current.next; + current.next = previous; + previous = current; + current = floating; + } + return previous; +} + +// class Node { +// constructor(value) { +// this.value = value; +// this.next = null; +// } +// } +// +// const nodeA = new Node('A'); +// const nodeB = new Node('B'); +// const nodeC = new Node('C'); +// nodeD +// nodeE +// +// nodeA.next = nodeB; +// nodeB.next = nodeC; +// +// reverseList(nodeA); diff --git a/cc42collatzSequence/collatzSequence.js b/cc42collatzSequence/collatzSequence.js new file mode 100644 index 0000000..3bd1a1e --- /dev/null +++ b/cc42collatzSequence/collatzSequence.js @@ -0,0 +1,42 @@ +/* cc42 collatzSequence https://repl.it/student/submissions/1498763 +Given a positive integer number, the Collatz conjecture determines +the next term in the sequence by either +1) Halving n if n is even +2) Multiplying n by 3 and then adding one if n is odd + +Write a function that will take a number n, and return the Collatz chain. You will stop at one. + +An example chain looks like this: + +[23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1] (Bold signifies odd numbers). +*/ + +// edge cases (non-positive integer, non-integer, non-number) +// either odd or even + // even: divide by half, repeat until n === 1 + // odd: (n * 3) + 1, until n === 1 + +function collatzSequence(n) { + const arr = []; + arr.push(n); + const collatz = (num, array) => { + // BASE CASE + if (num === 1) { + return array; + } else if (num % 2 === 0) { + num /= 2; + array.push(num); + return collatz(num, array); + } + num = (num * 3) + 1; + array.push(num); + return collatz(num, array); + }; + collatz(n, arr); + return arr; +} + +// TEST SUITE +/* eslint no-console: 0 */ +console.log(collatzSequence(23)); +// <~~~ [23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1] diff --git a/cc42collatzSequence/solution.js b/cc42collatzSequence/solution.js new file mode 100644 index 0000000..fc89822 --- /dev/null +++ b/cc42collatzSequence/solution.js @@ -0,0 +1,38 @@ +// https://repl.it/student/assignments/351164/model_solution?fromSubmissionId=1498763 +// https://youtu.be/aW-KYfWrsMk + +function collatzSequence(n) { + let m = n; + const arr = [m]; + while (m !== 1) { + // m = m % 2 === 0 ? m / 2 : m * 3 + 1; + if (m % 2 === 0) { + m /= 2; + } else { + m = (m * 3) + 1; + } + arr.push(m); + } + return arr; +} + +/* +function collatzSequence(n) { + // create variable to hold n called o + // define recursive function that takes in (m, arr) + // base case of recursive solution => n === 1 + // if m % 2 === 0 m = m / 2 + // else m = m * 3 + 1 + // push to arr + // return recursive function (m, arr); + // return recursive function(o, [o]); + function recurse(m, arr) { + if (m === 1) return arr; + if (m % 2 === 0) m = m / 2; + else m = m * 3 + 1; + arr.push(m); + return recurse(m, arr); + } + return recurse(n, [n]); +} +*/ diff --git a/cc43routeBetweenNodes/routeBetweenNodes.js b/cc43routeBetweenNodes/routeBetweenNodes.js new file mode 100644 index 0000000..b40f080 --- /dev/null +++ b/cc43routeBetweenNodes/routeBetweenNodes.js @@ -0,0 +1,57 @@ +/* cc43 routeBetweenNodes https://repl.it/student/submissions/1510145 +Given a directed graph, design an algorithm to find out whether there is a route between two nodes. + +Google "directed graph" and look under images for visual examples. +(Bonus: Write both DFS and BFS methods. You'll have to comment one + +Here is a test graph: (please be sure to remove this dummy data before running tests) + + const graph = { + a: { + value: 'a', + edges: [] + }, + b: { + value: 'b', + edges: [] + }, + c: { + value: 'c', + edges: [] }, + d: { + value: 'd', + edges: [] + }, + e: { + value: 'e', + edges: [] + }, +}; + +graph.a.edges.push(graph.b, graph.d, graph.e); +graph.b.edges.push(graph.a, graph.e); +graph.d.edges.push(graph.e); +graph.e.edges.push(graph.c, graph.a); +console.log(routeBetweenNodes(graph.a, graph.c)); // true +console.log(routeBetweenNodes(graph.c, graph.a)); // false +*/ + +// Depth First Search + +// Breadth First Search +function routeBetweenNodes(node1, node2) { + const roadMap = {}; + const queue = [node1]; + + const toPath = (node) => { + if (roadMap[node.value]) return; + roadMap[node.value] = true; + node.edges.forEach(item => queue.push(item)); + }; + + while (queue.length) { + if (roadMap[node2.value]) return true; + toPath(queue.shift()); + } + return false; +} diff --git a/cc43routeBetweenNodes/solution.js b/cc43routeBetweenNodes/solution.js new file mode 100644 index 0000000..8931bc4 --- /dev/null +++ b/cc43routeBetweenNodes/solution.js @@ -0,0 +1,38 @@ +// https://repl.it/student/assignments/371414/model_solution?fromSubmissionId=1510620 +// https://youtu.be/LBq-BqqT_H8 + +// Depth First Search +function routeBetweenNodes(node1, node2) { + let routeExists = false; + const obj = {}; + const searchGraph = (node) => { // Recursive subroutine + // console.log(node); + if (obj[node.value] === true || routeExists === true) return; + obj[node.value] = true; + for (let i = 0; i < node.edges.length; i++) { + if (node.edges[i].value === node2.value) routeExists = true; + if (node.edges[i].edges.length > 0) searchGraph(node.edges[i]); + } + }; + searchGraph(node1); + return routeExists; +} + +/* eslint no-redeclare:0 */ +// Breadth First Search +function routeBetweenNodes(node1, node2) { + const roadMap = {}; + const queue = [node1]; + + const toPath = (node) => { + if (roadMap[node.value]) return; + roadMap[node.value] = true; + node.edges.forEach(item => queue.push(item)); + }; + + while (queue.length) { + if (roadMap[node2.value]) return true; + toPath(queue.shift()); + } + return false; +} diff --git a/cc44sumAndProduct/solution.js b/cc44sumAndProduct/solution.js new file mode 100644 index 0000000..38fa096 --- /dev/null +++ b/cc44sumAndProduct/solution.js @@ -0,0 +1,9 @@ +// https://repl.it/student/assignments/367850/model_solution?fromSubmissionId=1521337 +// https://youtu.be/fnf9Vm7BP-Y + +function sumAndProduct(sum, product) { + for (let i = 0; i <= sum / 2; i++) { + if (i * (sum - i) === product) return [i, (sum - i)]; + } + return null; +} diff --git a/cc44sumAndProduct/sumAndProduct.js b/cc44sumAndProduct/sumAndProduct.js new file mode 100644 index 0000000..6bc17a7 --- /dev/null +++ b/cc44sumAndProduct/sumAndProduct.js @@ -0,0 +1,30 @@ +/* cc44 sumAndProduct https://repl.it/student/submissions/1521337 +Given a sum and a product, find two integers x and y, where x + y === sum, and x * y === product. +You will return this in an array. + +For example, calling sumAndProduct(6, 9) should return [3, 3] because 3 + 3 === 6, and 3 * 3 === 9. + +Please make sure to return your array such that x <= y in the format [x, y]. +*/ + +function sumAndProduct(sum, product) { + const answer = []; + if (product === 0) { + answer.push(product, sum); + return answer; + } + for (let i = 1; i < sum; i++) { + if (i * (sum - i) === product) { + answer.push(i); + answer.push(sum - i); + return answer; + } + } + return null; +} + +/* eslint no-console: 0 */ +// TEST SUITE +console.log(sumAndProduct(6, 9)); // ~~~> [ 3, 3 ] +console.log(sumAndProduct(0, 50)); // ~~~> null +console.log(sumAndProduct(50, 0)); // ~~~> null diff --git a/cc45deepEquality/deepEquality.js b/cc45deepEquality/deepEquality.js new file mode 100644 index 0000000..ace7c0a --- /dev/null +++ b/cc45deepEquality/deepEquality.js @@ -0,0 +1,34 @@ +/* cc45 deepEquality https://repl.it/student/submissions/1538402 +Write a function that, given two objects, returns whether or not the two +are deeply equivalent--meaning the contents of the two objects are equal for all keys and sub-keys. +*/ + +function deepEquals(obj1, obj2) { + return JSON.stringify(obj1) === JSON.stringify(obj2); +} + +// Examples: +const johnA = { + name: 'John', + address: { + line1: '321 Anytown', + line2: 'Stoke-on-Trent' + } +}; +const johnB = { + name: 'John', + address: { + line1: '321 Anytown', + line2: 'Stoke-on-Trent' + } +}; +const johnC = { + name: 'John Charles', + address: { + line1: '321 Anytown', + line2: 'Stoke-on-Trent' + } +}; +/* eslint no-console: 0 */ +console.log(deepEquals(johnA, johnB)); // true +console.log(deepEquals(johnA, johnC)); // false; diff --git a/cc45deepEquality/solution.js b/cc45deepEquality/solution.js new file mode 100644 index 0000000..94adb90 --- /dev/null +++ b/cc45deepEquality/solution.js @@ -0,0 +1,32 @@ +// https://repl.it/student/assignments/385242/model_solution?fromSubmissionId=1539350 +// Solution lecture pt1: https://youtu.be/251rmsXo9lI +// Solution lecture pt2: https://youtu.be/aPBH-Vde8BU + +function deepEquals(obj1, obj2) { + return JSON.stringify(obj1) === JSON.stringify(obj2); +} + +// // Antonio's solution from SO +// // https://stackoverflow.com/questions/25456013/javascript-deepequal-comparison +// function deepEquals(arr1, arr2) { +// if ((typeof arr1 == "object" && arr1 != null) && (typeof arr2 == "object" && arr2 != null)) { +// if (Object.keys(arr1).length != Object.keys(arr2).length) +// return false; +// +// for (var prop in arr1) { +// if (arr2.hasOwnProperty(prop)) +// { +// if (! deepEquals(arr1[prop], arr2[prop])) +// return false; +// } +// else +// return false; +// } +// +// return true; +// } +// else if (arr1 !== arr2) +// return false; +// else +// return true; +// } diff --git a/cc46telephoneWords/solution.js b/cc46telephoneWords/solution.js new file mode 100644 index 0000000..998e9ca --- /dev/null +++ b/cc46telephoneWords/solution.js @@ -0,0 +1,35 @@ +// https://piazza.com/class/j63w1pdyopf7kj?cid=44 +// https://youtu.be/iI-h7_L7Lnc + +const phoneDigitsToLetters = { + 0: '0', + 1: '1', + 2: 'ABC', + 3: 'DEF', + 4: 'GHI', + 5: 'JKL', + 6: 'MNO', + 7: 'PQRS', + 8: 'TUV', + 9: 'WXYZ' +}; + +function telephoneWords(numberStr) { + const words = []; + function innerRecurse(currentWord, index) { + // base case + if (currentWord.length === numberStr.length) { + words.push(currentWord); + return; + } + // grab current letters for the current number we're looking at from number string + const currentLetters = phoneDigitsToLetters[numberStr[index]]; + for (let i = 0; i < currentLetters.length; i++) { + innerRecurse(currentWord + currentLetters[i], index++); + } + } + innerRecurse('', 0); + return words; +} + +console.log(telephoneWords(45)); diff --git a/cc46telephoneWords/telephoneWords.js b/cc46telephoneWords/telephoneWords.js new file mode 100644 index 0000000..93dd861 --- /dev/null +++ b/cc46telephoneWords/telephoneWords.js @@ -0,0 +1,77 @@ +/* cc46 telephoneWords https://repl.it/student/submissions/1548411 +https://repl.it/student/submissions/1550720 + +Each number key on a standard phone keypad has a set +of Latin letters written on it as well: http://en.wikipedia.org/wiki/File:Telephone-keypad2.svg +Businesses often try to come up with clever ways to +spell out their phone number in advertisements to make it more memorable. But there are a lot of combinations! +Write a function that takes up to four digits of a phone +number, and returns a list of all of the words that can +be written on the phone with that number. (You should +return all permutations, not only English words.) + +Example: +telephoneWords('2745'); + => ['APGJ', + 'APGK', + 'APGL', + ..., // many many more of these + 'CSIL'] + * Tips: + - Phone numbers are strings! (A phone number can start + with a zero.) + - The digits 0 and 1 do not have letters associated + with them, so they should be left as numbers. + - Don't return every combination of those digits + in any order, just the order given. + +*/ +const phoneDigitsToLetters = { + 0: '0', + 1: '1', + 2: 'ABC', + 3: 'DEF', + 4: 'GHI', + 5: 'JKL', + 6: 'MNO', + 7: 'PQRS', + 8: 'TUV', + 9: 'WXYZ' +}; + +const telephoneWords = function (str) { + const target = []; + let i; + let j; + const digitArr = str.split(''); + if (str) { + for (i = 0; i < digitArr.length; i++) { + target.push(phoneDigitsToLetters[str[i]]); + } + } + + function combinations(arr) { + const newArr = arr.slice(0); + if (newArr.length === 0) { + return []; + } + let res = []; + const top = newArr.shift(); + const ret = combinations(newArr); + if (ret.length === 0) { + res = top; + } else { + for (i = 0; i < top.length; i++) { + for (j = 0; j < ret.length; j++) { + res.push(top[i] + ret[j]); + } + } + } + return res; + } + return combinations(target); +}; + +/* eslint no-console: 0 */ +// console.log(telephoneWords('45')); +telephoneWords('45'); diff --git a/cc47isTwinPrime/isTwinPrime.js b/cc47isTwinPrime/isTwinPrime.js new file mode 100644 index 0000000..53c6d73 --- /dev/null +++ b/cc47isTwinPrime/isTwinPrime.js @@ -0,0 +1,48 @@ +/* cc47 isTwinPrime https://repl.it/student/submissions/1559885 +A twin prime is a prime number that differs from another prime number by two. +Write a function called isTwinPrime which takes an integer and returns true +if it is a twin prime, or false if it is not. + +Example: +5 is a prime, and 5 + 2 = 7, which is also a prime, so returns true. +9 is not a prime, and so does not need checking, so it returns false. +7 is a prime, but 7 + 2 = 9, which is not a prime. However, 7 - 2 = 5, which is a prime, so it returns true. +*/ + +function isPrime(num) { + if (num < 2) return false; + for (let i = 2; i <= Math.sqrt(num); i++) { + if (num % i === 0 && i !== num) { + return false; + } + } + return true; +} + +function isTwinPrime(n) { + if (n === 2) return false; + if (!isPrime(n)) return false; + const lowerTwin = n + 2; + const higherTwin = n - 2; + if (isPrime(lowerTwin) || isPrime(higherTwin)) return true; +} + + +// THIS FAILS ON 23 - RETURNS UNDEFINED. WHY???????????????????????????????????? + + +/* eslint no-console: 0 */ +// TEST SUITE +console.log(isPrime(0)); // ~~~> false +console.log(isPrime(2)); // ~~~> true +console.log(isPrime(4)); // ~~~> false +console.log(isPrime(104728)); // ~~~> false +console.log(isPrime(104729)); // ~~~> true +console.log(isPrime(5)); // ~~~> true +console.log(isPrime(7)); // ~~~> true +console.log(isPrime(9)); // ~~~> false +console.log('\n'); +console.log(isTwinPrime(2)); // ~~~> false +console.log(isTwinPrime(5)); // ~~~> true +console.log(isTwinPrime(7)); // ~~~> true +console.log(isTwinPrime(9)); // ~~~> false diff --git a/cc47isTwinPrime/primes.js b/cc47isTwinPrime/primes.js new file mode 100644 index 0000000..c05af0f --- /dev/null +++ b/cc47isTwinPrime/primes.js @@ -0,0 +1,33 @@ +// return true if num is prime. +// otherwise return false +// hint: a prime number is only evenly divisible by itself and 1 +// hint2: you can solve this using a for loop +// note: 0 and 1 are NOT considered prime numbers +function isPrime(num) { + if (num < 2) return false; + + else if (num === 2) return true; } + else if (num % 2 === 0) { return false; } + else if (num >= 3) { + for (var i = 2; i < (num * .5); i++) { + if (num % i === 0) { + return false; + } + } + } return true; +} + + +function isTwinPrime(n) { + function isPrime(num) { + for (let i = 2; i <= Math.sqrt(num); i++) { + console.log(`${num} % ${i} === not zero`); + if (num % i === 0) return false; + } + return num >= 2; + } + return (isPrime(n) && (isPrime(n - 2) || isPrime(n + 2))); +} + +console.log(`the sqaure root of 119 is ${Math.sqrt(119)}`); +console.log(isTwinPrime(119)); diff --git a/cc47isTwinPrime/solution.js b/cc47isTwinPrime/solution.js new file mode 100644 index 0000000..f09d32b --- /dev/null +++ b/cc47isTwinPrime/solution.js @@ -0,0 +1,16 @@ +// https://repl.it/student/assignments/395908/model_solution?fromSubmissionId=1559885 +// https://youtu.be/wNPKVuKBWxo + +function isTwinPrime(n) { + function isPrime(num) { + for (let i = 2; i <= Math.sqrt(num); i++) { + console.log(`${num} % ${i} === not zero`); + if (num % i === 0) return false; + } + return num >= 2; + } + return (isPrime(n) && (isPrime(n - 2) || isPrime(n + 2))); +} + +console.log(`the sqaure root of 119 is ${Math.sqrt(119)}`); +console.log(isTwinPrime(119)); diff --git a/cc48cssAnimation/cssAnimation.js b/cc48cssAnimation/cssAnimation.js new file mode 100644 index 0000000..af51cd5 --- /dev/null +++ b/cc48cssAnimation/cssAnimation.js @@ -0,0 +1,13 @@ +/* cc48 cssAnimation https://repl.it/student/submissions/1571861 +Head over to this link: https://codepen.io/sperrye/full/oGvoWB/ and follow the instructions. + +Once you're finished, you'll submit the URL to your pen as your answer. +https://codepen.io/mixelpix/pen/ZXYNxX?editors=1100 + +- http://cssreference.io/animations/ +- https://webdesign.tutsplus.com/tutorials/a-beginners-introduction-to-css-animation--cms-21068 +- https://developer.mozilla.org/en-US/docs/Web/CSS/animation +- https://cssanimation.rocks/portal/ +Jesh's solution: https://codepen.io/anon/pen/QqwXWg +Steve Ocampo: https://codepen.io/anon/pen/OxPYwV?editors=1100 +*/ diff --git a/cc48cssAnimation/solution.js b/cc48cssAnimation/solution.js new file mode 100644 index 0000000..be408da --- /dev/null +++ b/cc48cssAnimation/solution.js @@ -0,0 +1,2 @@ +// https://codepen.io/sperrye/pen/XeWEwm +// https://youtu.be/2M9caq3E8pM diff --git a/cc49romanNumeralEncoder/romanNumeralEncoder.js b/cc49romanNumeralEncoder/romanNumeralEncoder.js new file mode 100644 index 0000000..c169b17 --- /dev/null +++ b/cc49romanNumeralEncoder/romanNumeralEncoder.js @@ -0,0 +1,59 @@ +/* cc49 romanNumeralEncoder https://repl.it/student/submissions/1581604 +Define a function that takes in a positive integer, and returns the Roman Numeral representation of that number. + +Symbol Value + I 1 + V 5 + X 10 + L 50 + C 100 + D 500 + M 1,000 + +Example: romanNumeralize(1990) should return 'MCMXC'. +*/ + +const rome = [ + [1000, 'M'], + [900, 'CM'], + [500, 'D'], + [400, 'CD'], + [100, 'C'], + [90, 'XC'], + [50, 'L'], + [40, 'XL'], + [10, 'X'], + [9, 'IX'], + [5, 'V'], + [4, 'IV'], + [1, 'I'] +]; + +function romanNumeralize(number) { + if (number === 0) { + return ''; + } + for (let i = 0; i < rome.length; i++) { + if (number >= rome[i][0]) { + return rome[i][1] + romanNumeralize(number - rome[i][0]); + } + } +} + +/* eslint no-console: 0 */ +// TEST SUITE +console.log(romanNumeralize(0)); // ~~~> '' +console.log(romanNumeralize(1)); // ~~~> I +console.log(romanNumeralize(2)); // ~~~> II +console.log(romanNumeralize(3)); // ~~~> III +console.log(romanNumeralize(4)); // ~~~> IV +console.log(romanNumeralize(9)); // ~~~> IX +console.log(romanNumeralize(17)); // ~~~> XVII +console.log(romanNumeralize(49)); // ~~~> XLIX +console.log(romanNumeralize(51)); // ~~~> LI +console.log(romanNumeralize(99)); // ~~~> XCIX +console.log(romanNumeralize(101)); // ~~~> CI +console.log(romanNumeralize(499)); // ~~~> CDXCIX +console.log(romanNumeralize(501)); // ~~~> DI +console.log(romanNumeralize(1990)); // ~~~> MCMXC +console.log(romanNumeralize(1999)); // ~~~> MCMXCIX diff --git a/cc49romanNumeralEncoder/solution.js b/cc49romanNumeralEncoder/solution.js new file mode 100644 index 0000000..bb7457f --- /dev/null +++ b/cc49romanNumeralEncoder/solution.js @@ -0,0 +1,2 @@ +// https://repl.it/student/assignments/404208/model_solution?fromSubmissionId=1581604 +// https://youtu.be/BEIF6yT-I-8 diff --git a/cc50stackMachine/Screen Shot 2017-09-25 at 1.20.32 PM (2).png b/cc50stackMachine/Screen Shot 2017-09-25 at 1.20.32 PM (2).png new file mode 100644 index 0000000..7e023ea Binary files /dev/null and b/cc50stackMachine/Screen Shot 2017-09-25 at 1.20.32 PM (2).png differ diff --git a/cc50stackMachine/solution.js b/cc50stackMachine/solution.js new file mode 100644 index 0000000..b50441e --- /dev/null +++ b/cc50stackMachine/solution.js @@ -0,0 +1,37 @@ +// https://youtu.be/w-kcXRj0Tu4 +// https://piazza.com/class/j63w1pdyopf7kj?cid=54 + +function stackMachine(str) { + // create function to check that arr[arr.length - 1] and arr[arr.length - 2] are not undefined + // create an object with two keys + // '+' : (x, y) => (+x) + (+y), + // '*' : (x, y) => (+x) * (+y) + // create an array that I'll be using for stack + // let err = false + // for loop for i = 0; i < str.length + // if(!obj[str[i]]) arr.push(str[i]) + // else { + // check(); + // arr.push(obj[str[i]](arr.pop(), arr.pop())) + // } + // return err ? -1 : arr.splice(-1)[0]; + + const arr = []; + let err = false; + + function check() { + if (arr.length < 2) err = true; + } + const obj = { + '+': (x, y) => (+x) + (+y), + '*': (x, y) => (+x) * (+y) + }; + + for (let i = 0; i < str.length; i++) { + if (obj[str[i]]) { + check(); + arr.push(obj[str[i]](arr.pop(), arr.pop())); + } else arr.push(str[i]); + } + return err ? -1 : arr.splice(-1)[0]; +} diff --git a/cc50stackMachine/stackMachine.js b/cc50stackMachine/stackMachine.js new file mode 100644 index 0000000..9c00ff1 --- /dev/null +++ b/cc50stackMachine/stackMachine.js @@ -0,0 +1,42 @@ +/* cc50 stackMachine https://repl.it/student/submissions/1664305 +Stack Machine + +A stack machine is a simple system that performs arithmetic operations on an input string of numbers and operators. It contains a stack that can store an arbitrary number of 12-bit unsigned integers. Initially the stack is empty. The machine processes a string of characters in the following way: +the characters of the string are processed one by one; +if the current character is a digit [0-9], the machine pushes the value of that digit onto its stack; +if the current character is +, the machine pops the two topmost values from its stack, adds them and pushes the result onto the stack; +if the current character is *, the machine pops the two topmost values from its stack, multiplies them and pushes the result onto the stack; +after the machine has processed the whole string it returns the topmost value of its stack as the result; +the machine reports an error if any operation it performs (addition or multiplication) results in an overflow; +the machine reports an error if it tries to pop an element from its stack when the stack is empty, or if the stack is empty after the machine has processed the whole string. +For example, given the string "13+627+" the machine will perform the following operations: + +character | comment | stack + ----------------------------------------------- + | | [empty] + '1' | push 1 onto the stack | + | | 1 + '3' | push 3 onto the stack | + | | 1, 3 + '+' | perform addition | + | | 4 + '6' | push 6 onto the stack | + | | 4, 6 + '2' | push 2 onto the stack | + | | 4, 6, 2 + '*' | perform multiplication | + | | 4, 12 + '7' | push 7 onto the stack | + | | 4, 12, 7 + '+' | perform addition | + | | 4, 19 + '*' | perform multiplication | + | | 76 + + +The machine will return 76 as the result as it is the topmost element of its stack.Write a function that, given a string S consisting of N characters containing input for the stack machine, returns the result the machine would return if given this string. The function should return -1 if the machine would report an error when processing the string.For example, given String S = "13+62*7+*" the function should return 76, as explained in the example above. Given String S = "11++" the function should return -1. +Assume that: +the length of S is within the range [0..200,000]; +string S consists only of the following characters: "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+" and/or "*". +In your solution, focus on correctness. The performance of your solution will not be the focus of the assessment. +*/ diff --git a/cc51combineTwoStrings/combineTwoStrings.js b/cc51combineTwoStrings/combineTwoStrings.js new file mode 100644 index 0000000..3b716bc --- /dev/null +++ b/cc51combineTwoStrings/combineTwoStrings.js @@ -0,0 +1,39 @@ +/* cc51 combineTwoStrings https://repl.it/student/submissions/1677604 + +Given three strings, str1, str2, str3. +str3 is said to be a shuffle of str1 and str2 if it can be formed by +interleaving the characters of str1 and str2 in such a manner that +it maintains left to right ordering from each string. +Given str1 = 'abc' and str2 = 'def', str3 = 'dabecf' is a valid shuffle +since it preserves the character ordering of the two strings. + +So, given these three strings, write a function that detects +whether str3 is a valid shuffle of str1 and str2. +*/ + +function checkString(str1, str2, str3) { + // compare intersection of str1 str3 + // compare intersection of str2 str3 + // if both === true, else false + const arr1 = str1.split(''); + console.log('arr1', arr1); + const arr2 = str2.split(''); + console.log('arr2', arr2); + const arr3 = str3.split(''); + console.log('arr3', arr3); + const a = new Set(arr1); + const b = new Set(arr2); + const c = new Set(arr3); + const intersection1 = [...a].filter(x => c.has(x)); + console.log('1 ∩ 3', intersection1); + console.log(new Array(intersection1)); + const intersection2 = [...b].filter(x => c.has(x)); + console.log('2 ∩ 3', intersection2); + console.log(new Array(intersection2)); + // console.log(JSON.stringify(new Array(intersection2[0]))); + if (JSON.stringify(new Array(intersection1)) === JSON.stringify([arr1]) && JSON.stringify(new Array(intersection2[0])) === JSON.stringify([arr2])) return true; + return false; +} + +// TEST SUITE +console.log(checkString('abc', 'def', 'dabecf')); diff --git a/cc51combineTwoStrings/solution.js b/cc51combineTwoStrings/solution.js new file mode 100644 index 0000000..79148d0 --- /dev/null +++ b/cc51combineTwoStrings/solution.js @@ -0,0 +1,18 @@ +// https://youtu.be/lcTbfgMlNNE +// https://piazza.com/class/j63w1pdyopf7kj?cid=55 + +function checkString(str1, str2, str3) { + if (str3.length === 0) return true; + if ((str1.length + str2.length) !== str3.length) return false; + const shorterStr3 = str3.substr(1); + if (str1[0] === str3[0]) { + if (str2[0] === str3[0]) { + return checkString(str1.substr(1), str2, shorterStr3) || checkString(str1, str2.substr(1), shorterStr3); + } + return checkString(str1.substr(1), str2, shorterStr3); + } + if (str2[0] === str3[0]) { + return checkString(str1, str2.substr(1), shorterStr3); + } + return false; +} diff --git a/cc52sumDigitPower/solution.js b/cc52sumDigitPower/solution.js new file mode 100644 index 0000000..0fdd0fe --- /dev/null +++ b/cc52sumDigitPower/solution.js @@ -0,0 +1,18 @@ +// +// + +function sumDigPower(a, b) { + const arr = []; + function check(n) { + const str = n.toString(); + let ans = 0; + for (let i = 0; i < str.length; i++) { + ans += Math.pow(str[i], i + 1); + } + return ans === n; + } + for (let i = a; i <= b; i++) { + if (check(i)) arr.push(i); + } + return arr; +} diff --git a/cc52sumDigitPower/sumDigitPower.js b/cc52sumDigitPower/sumDigitPower.js new file mode 100644 index 0000000..fa8cfd9 --- /dev/null +++ b/cc52sumDigitPower/sumDigitPower.js @@ -0,0 +1,51 @@ +/* cc52 sumDigitPower https://repl.it/student/submissions/1684889 +The number 135 is particularly special in that if you take each digit, +from left to right, and you put them to the consecutive power. +135 = 1^1 + 3^2 + 5^3 +89 = 8^1 + 9^2 + +Write a function sumDigitPower that takes in a starting number, +and an ending number, and check every number in that range inclusive +(including both a and b - a will be greater than or equal to 0 and b greater than a). + +return an array of all numbers within the inclusive range which are the sum of their digits. +*/ + +const digitIndexPower = (num) => { + // does num equal sum of digits to consecutive power? + const strNum = JSON.stringify(num); + const digArr = strNum.split('').map((x) => { + return Number(x); + }); + digArr.unshift('zero'); // putting something at the zero index + let sum = 0; + for (let i = 1; i < digArr.length; i++) { + sum += Math.pow(digArr[i], i); + } + if (sum === num) return 'Tai gets soup!'; + return 'no soup for Tai!!!!'; +}; + +function sumDigPower(min, max) { + // make range of nums from min to max + const range = []; + for (let i = min; i <= max; i++) { + range.push(i); + } + const winners = []; + // for each num in range , check condition + // if match push into array + for (let i = 0; i < range.length; i++) { + if (digitIndexPower(range[i]) === 'Tai gets soup!') { + winners.push(range[i]); + } + } + return winners; +} + +// TEST SUITE +/* eslint no-console: 0 */ +console.log(digitIndexPower(123)); // ~~> no soup +console.log(digitIndexPower(135)); // ~~> soup +console.log(digitIndexPower(89)); // ~~> soup +console.log(sumDigPower(1, 1000)); // ~~~> [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 89, 135, 175, 518, 598 ] array of matching integers from 1 to 1000 diff --git a/cc53primeReduction/primeReduction.js b/cc53primeReduction/primeReduction.js new file mode 100644 index 0000000..f5e9667 --- /dev/null +++ b/cc53primeReduction/primeReduction.js @@ -0,0 +1,57 @@ +/* c53 primeReduction https://repl.it/student/submissions/1695186 +Consider the prime number 23. +If we sum the square of its digits we get: 2^2 + 3^2 = 13, +then for 13: 1^2 + 3^2 = 10, and finally for 10: 1^2 + 0^2 = 1. +Similarly, if we start with prime number 7, +the sequence is: 7-> 49-> 97-> 130-> 10-> 1. +Given a range, how many primes within that range have this property? +*/ + +function primeReduction(min, max) { + // primes + function isPrime(num) { + if (num < 2) return false; + for (let i = 2; i <= Math.sqrt(num); i++) { + if (num % i === 0 && i !== num) { + return false; + } + } + return true; + } + // make range of nums from min to max if they are primes + const rangeOfPrimes = []; + for (let i = min; i <= max; i++) { + if (isPrime(i)) { + rangeOfPrimes.push(i); + } + } + console.log(rangeOfPrimes); + // reduction + function reducer(num) { + const strNum = num.toString(); + const digArr = strNum.split('').map((x) => { + return Number(x); + }); + let sum = 0; + for (let i = 0; i < digArr.length; i++) { + sum += Math.pow(digArr[i], 2); + } + return sum; + } + // holding pen for numbers satisfying the prime reduction condition + const winners = []; + // recursion + for (let i = 0; i < rangeOfPrimes.length; i++) { + // base case + while (reducer(rangeOfPrimes[i]) !== 1) { + if (reducer(rangeOfPrimes[i]) === 1) { + winners.push(rangeOfPrimes[i]); + } + } + return winners; + } +} + +// TEST SUITE +console.log(primeReduction(1, 100)); +console.log(primeReduction(7, 23)); diff --git a/cc53primeReduction/solution.js b/cc53primeReduction/solution.js new file mode 100644 index 0000000..ccb2a42 --- /dev/null +++ b/cc53primeReduction/solution.js @@ -0,0 +1,66 @@ +// https://youtu.be/u3p5kZtAAHY +// https://piazza.com/class/j63w1pdyopf7kj?cid=57 + + +function primeReduction(a, b) { + // determine if n is prime (function) + // if (n < 2) return false + // for let i = 2; i <= Math.sqrt(n); i++ + // if (n % i === 0) return false; + // return true; + // + // create array to help determine below + // let arr = []; + // determine if number goes into a loop (function) + // if (arr.includes(n)) { + // arr.length = 0; + // return false; + // } + // if (n === 1) { + // arr.length = 0; + // return true; + // } + // arr.push(n); + // let hold = 0; + // let num = n; + // while num > 0 + // hold += Math.pow(num % 10, 2); + // num -= num % 10; + // num /= 10; + // return reduction(hold); + // + // let count = 0 + // for let i = a; i < b; i++ + // if isPrime(i) + // if reduction(i) + // count++ + // return count + function isPrime(n) { + if (n < 2) return false; + for (let i = 2; i <= Math.sqrt(n); i++) if (n % i === 0) return false; + return true; + } + const arr = []; + function reduction(n) { + if (arr.includes(n)) { + arr.length = 0; + return false; + } + if (n === 1) { + arr.length = 0; + return true; + } + arr.push(n); + let hold = 0; + let num = n; + while (num > 0) { + hold += Math.pow(num % 10, 2); + num -= num % 10; + num /= 10; + } + return reduction(hold); + } + let count = 0; + for (let i = a; i < b; i++) if (isPrime(i)) if (reduction(i)) count++; + return count; +} diff --git a/cc54fullAdder/fullAdder.js b/cc54fullAdder/fullAdder.js new file mode 100644 index 0000000..b57b62e --- /dev/null +++ b/cc54fullAdder/fullAdder.js @@ -0,0 +1,65 @@ +/* cc54 fullAdder https://repl.it/student/submissions/1721915 +Construct a four bit full adder. +You must use the provided NAND function to create any other logic gates +you require to make a 4 bit full adder. +x and y will come in array format where [true, true, true, true] === 1111 === 15. +The expected return is an array with length 5. + +Each index in the array is just a wire that can be on or off. +That will be represented by boolean true or false. + +I suggest writing a halfAdder first, then fullAdder, +but you will only be tested on the fullAdder4. + +Check this resource for more information: + +http://www.electronics-tutorials.ws/combination/comb_7.html +*/ + +let sum = 0; +let carry = 0; + +function NAND(x, y) { + return (!x || !y); +} + +// NOT = NAND(a, a) - test this + +function XOR(a, b) { + // if (x === y) return 0; + // return 1; + return NAND(NAND(NAND(a, b), a), NAND(NAND(a, b), b)); +} + +function halfAdder(a, b) { + sum = XOR(a, b); + carry = !NAND(a, b); + return [sum, carry]; +} + +// Full adder is two half adders with OR gate +// sum of 1st half adder goes into 2nd halfadder "a" +// carry in goes into 2nd half adder "b" +function fullAdder(a, b, carryIn = 0) { + const halfAdd1 = halfAdder(a, b); + const halfAdd2 = halfAdder(halfAdd1, carryIn); + // const carry = OR(first[1], second[1]); + const carry = halfAdd1[1] || halfAdd2[1]; + return [halfAdd2[0], carry]; +} + +function fullAdder4(a, b) { + +} + +/* eslint no-console: 0 */ +// TEST SUITE +console.log(halfAdder(true, true)); // ~~~> [ false, true ] +console.log(halfAdder(true, false)); // ~~~> [ true, false ] +console.log(halfAdder(false, true)); // ~~~> [ true, false ] +console.log(halfAdder(false, false)); // ~~~> [ false, false ] + +console.log(fullAdder(true, true)); // ~~~> [ true, true ] +console.log(fullAdder(true, false)); // ~~~> [ true, false ] +console.log(fullAdder(false, true)); // ~~~> [ true, false ] +console.log(fullAdder(false, false)); // ~~~> [ true, false ] diff --git a/cc54fullAdder/solution.js b/cc54fullAdder/solution.js new file mode 100644 index 0000000..39da3aa --- /dev/null +++ b/cc54fullAdder/solution.js @@ -0,0 +1,39 @@ +// https://youtu.be/9Rqk8aV8-SU +// https://piazza.com/class/j63w1pdyopf7kj?cid=59 +// http://isweb.redwoods.edu/instruct/calderwoodd/diglogic/full.htm +// http://www.electronics-tutorials.ws/combination/comb_7.html + +function NAND(x, y) { + return (!x || !y); +} + +function XOR(x, y) { + return (NAND(NAND(x, NAND(x, y)), NAND(y, NAND(x, y)))); +} + +function AND(x, y) { + return (NAND(NAND(x, y), NAND(x, y))); +} +function OR(x, y) { + return (NAND(NAND(x, x), NAND(y, y))); +} +function halfAdder(x, y) { + const sum = XOR(x, y); + const carry = AND(x, y); + return [sum, carry]; +} + +function fullAdder(x, y, c = false) { + const first = halfAdder(x, y); + const second = halfAdder(first[0], c); + const carry = OR(first[1], second[1]); + return [second[0], carry]; +} + +function fullAdder4(x, y) { + const fourth = fullAdder(x[3], y[3]); + const third = fullAdder(x[2], y[2], fourth[1]); + const second = fullAdder(x[1], y[1], third[1]); + const first = fullAdder(x[0], y[0], second[1]); + return [first[1], first[0], second[0], third[0], fourth[0]]; +} diff --git a/cc55overlappingRectangles/overlappingRectangles.js b/cc55overlappingRectangles/overlappingRectangles.js new file mode 100644 index 0000000..c5dbb62 --- /dev/null +++ b/cc55overlappingRectangles/overlappingRectangles.js @@ -0,0 +1,62 @@ +/* cc55 overlappingRectangles https://repl.it/student/submissions/1731362 +Write a function findOverlap to find the rectangular intersection of two given rectangles. + +They are defined as objects like this: + +const rectangle1 = { + leftX: 1, + bottomY: 5, + width: 10, + height: 4, +}; + +Your function should return an object in this format as well. +*/ + +function findOverlap(rect1, rect2) { + rect1.rightX = rect1.leftX + rect1.width; + leftRightOverlap = false + if (rect2.leftX >= rect1.leftX || rect2.leftX >= rect1.rightX) { + leftRightOverlap = true; + } + // convert into Tai's nomenclature & + // do the same for all four sides, e.g. + // function intersectRect(r1, r2) { + // return !(r2.left > r1.right || + // r2.right < r1.left || + // r2.top > r1.bottom || + // r2.bottom < r1.top); + // } + if (!intersectRect(rect1, rect2)) { + return {}; + } else { + return "overlap" + } + // if overlap = true + // calculate intersection object coordinates + // discerning relative geometric intersection???? + // return overlaping object coordinates + // { + // leftX: #, + // bottomY: #, + // width: #, + // height: #, + // } +} + +const rectangle1 = { + leftX: 1, + bottomY: 5, + width: 10, + height: 4, +}; + +const rectangle2 = { + leftX: 2, + bottomY: 6, + width: 10, + height: 4, +}; + +// TEST SUITE +console.log(findOverlap(rectangle1, rectangle2)); diff --git a/cc55overlappingRectangles/solution.c b/cc55overlappingRectangles/solution.c new file mode 100644 index 0000000..8d2f76b --- /dev/null +++ b/cc55overlappingRectangles/solution.c @@ -0,0 +1,56 @@ +// https://youtu.be/PS732Ig7Uow +// https://piazza.com/class/j63w1pdyopf7kj?cid=60 + +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +typedef struct { + int leftX; + int bottomY; + int width; + int height; +} Rectangle; + +typedef struct { + int startPoint; + int length; +} RangeOverlap; + +RangeOverlap findRangeOverlap(int point1, int length1, int point2, int length2) +{ + int highestStartPoint, lowestEndPoint; + RangeOverlap rangeOverlap = {0, 0}; + + highestStartPoint = MAX(point1, point2); + lowestEndPoint = MIN(point1 + length1, point2 + length2); + + if (highestStartPoint >= lowestEndPoint) { + return rangeOverlap; + } + + int overlapLength = lowestEndPoint - highestStartPoint; + rangeOverlap.startPoint = highestStartPoint; + rangeOverlap.length = overlapLength; + + return rangeOverlap; +} + +Rectangle findRectangularOverlap(Rectangle rect1, Rectangle rect2) +{ + RangeOverlap xOverlap, yOverlap; + Rectangle rectangle = {0, 0, 0, 0}; + + xOverlap = findRangeOverlap(rect1.leftX, rect1.width, rect2.leftX, rect2.width); + yOverlap = findRangeOverlap(rect1.bottomY, rect1.height, rect2.bottomY, rect2.height); + + if (xOverlap.length == 0 || yOverlap.length == 0) { + return rectangle; + } + + rectangle.leftX = xOverlap.startPoint; + rectangle.bottomY = yOverlap.startPoint; + rectangle.width = xOverlap.length; + rectangle.height = yOverlap.length; + + return rectangle; +} diff --git a/cc55overlappingRectangles/solution.js b/cc55overlappingRectangles/solution.js new file mode 100644 index 0000000..bdfe612 --- /dev/null +++ b/cc55overlappingRectangles/solution.js @@ -0,0 +1,36 @@ +// https://youtu.be/PS732Ig7Uow +// https://piazza.com/class/j63w1pdyopf7kj?cid=60 + +function findOverlap(point1, length1, point2, length2) { + const highestStartingPoint = Math.max(point1, point2); + const lowestEndPoint = Math.min(point1 + length1, point2 + length2); + + if (highestStartingPoint >= lowestEndPoint) { + return { startPoint: null, overlapLength: null }; + } + + const overlapLength = lowestEndPoint - highestStartingPoint; + + return { startPoint: highestStartingPoint, overlapLength: overlapLength }; +} + +function findRectangularOverlap(rectangle1, rectangle2) { + const xOverlap = findOverlap(rectangle1.leftX, rectangle1.width, rectangle2.leftX, rectangle2.width); + const yOverlap = findOverlap(rectangle1.bottomY, rectangle1.height, rectangle2.bottomY, rectangle2.height); + + if (!xOverlap.overlapLength || !yOverlap.overlapLength) { + return { + leftX: null, + bottomY: null, + width: null, + height: null, + }; + } + + return { + leftX: xOverlap.startPoint, + bottomY: yOverlap.startPoint, + width: xOverlap.overlapLength, + height: yOverlap.overlapLength, + }; +} diff --git a/cc56mergeSort/mergeSort.js b/cc56mergeSort/mergeSort.js new file mode 100644 index 0000000..52478f2 --- /dev/null +++ b/cc56mergeSort/mergeSort.js @@ -0,0 +1,64 @@ +/* cc56 mergeSort https://repl.it/student/submissions/1746465 +Reference https://en.wikipedia.org/wiki/Merge_sort for more detail about how this sorting algorithm works. +Sort an array of integers using the merge sort algorithm. +First divide the list into its smallest unit (arrays with a single item in them) +Then compare each element with the adjacent list and combine them in the proper order. +Repeat until the entire array is sorted. +Example: + - Input: [1, 6, 3, 2, 4, 7] + - Expected Output: [1, 2, 3, 4, 6, 7]; +[1, 6, 3, 2, 4, 7] -> [1, 2, 3, 4, 6, 7] +[1, 6, 3][2, 4, 7] +[1][6, 3][2][4, 7] +[1][6][3][2][4][7] +[1, 3][6][2][4][7] +[1, 3][6][2, 4][7] +[1, 3, 6][2, 4][7] +[1, 3, 6][2, 4, 7] +[1, 2, 3, 4, 6, 7] +*/ + +function mergeSort(arr) { + // any array of length > 1 is already "sorted" + if (arr.length < 2) + // BASE CASE + return arr; + // split point for the array (odd v even) + const middle = Math.floor(arr.length / 2); + // samesies: + // const middle = parseInt(arr.length / 2); + console.log('middle index: ', middle); + // SPLIT + const left = arr.slice(0, middle); + const right = arr.slice(middle, arr.length); + console.log('L/R: ', left, right); + // merge the recursive splitting + return merge(mergeSort(left), mergeSort(right)); +} + +function merge(left, right) { + const result = []; + // Compare two arrays when both arrays are length > 0 + while (left.length && right.length) { + if (left[0] <= right[0]) { + result.push(left.shift()); + } else { + result.push(right.shift()); + } + } + // When one of the two lists is empty shift the + // 0 index value of the non-empty array to result + while (left.length) + result.push(left.shift()); + while (right.length) + result.push(right.shift()); + console.log('Result: ', result); + return result; +} + +/* eslint no-console: 0 */ +// TEST SUITE +console.log(mergeSort([1, 6, 3, 2, 4, 7])); +// ~~~> [1, 2, 3, 4, 6, 7] EVEN # of terms +console.log(mergeSort([5, 1, 6, 3, 2, 4, 7])); +// ~~~> [1, 2, 3, 4, 5, 6, 7] ODD # of terms diff --git a/cc56mergeSort/solution.js b/cc56mergeSort/solution.js new file mode 100644 index 0000000..754d35b --- /dev/null +++ b/cc56mergeSort/solution.js @@ -0,0 +1,63 @@ +// https://repl.it/student/assignments/458240/model_solution?fromSubmissionId=1746465 +// https://youtu.be/oMlOBuyazv4 + +function mergeSort(arr) { + if (arr.length < 2) return arr; + const mid = Math.floor(arr.length / 2); //2 + const leftArray = arr.slice(0, mid); //[3, 2] + const rightArray = arr.slice(mid);//[1, 0, -1] + + const merge = (leftArray, rightArray) => { + const mergedArray = []; + let leftIndex = 0; + let rightIndex = 0; + + while (leftIndex < leftArray.length && rightIndex < rightArray.length) { + if (leftArray[leftIndex] < rightArray[rightIndex]) { + mergedArray.push(leftArray[leftIndex]); + leftIndex++; + continue; + } + mergedArray.push(rightArray[rightIndex]); + rightIndex++; + } + return mergedArray.concat(leftArray.slice(leftIndex)).concat(rightArray.slice(rightIndex)); + }; + + return merge(mergeSort(leftArray), mergeSort(rightArray)); +} + + +// Ryan's soloosh +function mergeSort(arr) { // [3, 2], [1, 0, -1] + // base case if length of arr < 2; return; + // break arr into halves Left & Right; + // Lsorted = mergeSort () + if (arr.length < 2) return arr; + const mid = Math.floor(arr.length / 2); + const leftArray = arr.slice(0, mid); + const rightArray = arr.slice(mid); + + const merge = (leftArray, rightArray) => { + const mergedArray = []; + let leftPointer = 0; + let rightPointer = 0; + + while (leftPointer < leftArray.length && rightPointer < rightArray.length) { + + if (leftArray[leftPointer] < rightArray[rightPointer]) { + mergedArray.push(leftArray[leftPointer]); + leftPointer ++; + continue; + } + mergedArray.push(rightArray[rightPointer]); + rightPointer ++; + } + + return mergedArray + .concat(leftArray.slice(leftPointer)) + .concat(rightArray.slice(rightPointer)); + }; + + return merge(mergeSort(leftArray), mergeSort(rightArray)); +} diff --git a/cc57rand7ToRand5/rand7ToRand5.js b/cc57rand7ToRand5/rand7ToRand5.js new file mode 100644 index 0000000..5e03e94 --- /dev/null +++ b/cc57rand7ToRand5/rand7ToRand5.js @@ -0,0 +1,78 @@ +/* cc57 rand7ToRand5 https://repl.it/student/submissions/1752932 +Given a function rand7 that generates a random number from 1 to 7, +how would you write a function that generates +a number with equal probability from 1 to 5? +*/ + +function rand7(){ + return 1 + Math.floor(Math.random() * 7); +} + +// // version one +function rand5() { + const probable = rand7(); + if (probable > 5) { + return rand5(); + } + return probable; +} + +// // version two - bunk +// function rand5() { +// return 1 + Math.floor((Math.random() * (7 / 5) * 5)); +// } + +// // Jesh +// function rand5() { +// let temp = rand7() + rand7() + rand7() + rand7() + rand7(); +// temp = temp % 5 + 1; +// return temp; +// } + +/* eslint no-console: 0 */ +// TEST SUITE +// console.log(rand7()); +// console.log(rand5()); + +/* TODO: + * the total distribution should be 1/7 the total rolls… + * # of rolls would be greater than the total # oftests, + * i.e. if 1 million tests, it should pan out to 1.4 million + * rolls where 6 and 7 have the same distribution as 1-5 (all around 200k) +*/ +function test5() { + const testRuns = 1000000; + let results = { + ones: 0, + twos: 0, + thre: 0, + four: 0, + fivs: 0, + }; + for (let i = 0; i < testRuns; i++) { + if (i < testRuns) { + switch(rand5()) { + case 1: + results.ones += 1; + break; + case 2: + results.twos += 1; + break; + case 3: + results.thre += 1; + break; + case 4: + results.four += 1; + break; + case 5: + results.fivs += 1; + break; + default: + console.log('you silly puppy!'); + break; + } + } + } + return results; +} +console.log(test5()); diff --git a/cc57rand7ToRand5/solution.js b/cc57rand7ToRand5/solution.js new file mode 100644 index 0000000..41eeff8 --- /dev/null +++ b/cc57rand7ToRand5/solution.js @@ -0,0 +1,29 @@ +// https://piazza.com/class/j63w1pdyopf7kj?cid=63 +// https://youtu.be/zRA4SxsAfDY + +// Code for `rand7` function: +function rand7() { + return Math.floor(Math.random() * 7) + 1; +} + +// Iterative solution: +function rand5() { + let result = 7; // some arbitrary number here; it will be overwritten + while (result > 5) { + result = rand7(); + } + return result; +} + +// Recursive solution: +function rand5() { + let roll = rand7(); + return roll <= 5 ? roll : rand5(); +} + +// Jesh's more math-y solution: +function rand5() { + let temp = rand7() + rand7() + rand7() + rand7() + rand7(); + temp = temp % 5 + 1; + return temp; +} diff --git a/cc58findTotalAverageAndPercentage/findTotalAverageAndPercentage.c b/cc58findTotalAverageAndPercentage/findTotalAverageAndPercentage.c new file mode 100644 index 0000000..3bd156e --- /dev/null +++ b/cc58findTotalAverageAndPercentage/findTotalAverageAndPercentage.c @@ -0,0 +1,45 @@ +/* cc58 findTotalAverageAndPercentage https://repl.it/student/submissions/1764702 +Write a C program that takes in exactly 5 floats and calculates the total, +average, and percentage of those five floats. +When your program is executed, it should look something like the following: +Example Input + Enter 5 floats: 95.2 76.6 85.4 90.0 89.1 +Output + Total = 436.30 + Average = 87.27 + Percentage = 87.26 % +*/ + +#include + +int main() { + + float a, b, c, d, e; + + printf("Enter 5 floats: "); + scanf("%f %f %f %f %f", &a, &b, &c, &d, &e); + + float total, average, percentage; + total = a + b + c + d + e; + printf("Total = %.02f\n", total); + average = total / 5; + printf("Average = %.02f\n", average); + percentage = average; + printf("Percentage = %.02f %%\n", percentage); + return 0; +} + +// #include +// #include + +// int main( int argc, char ** argv ) { +// float total, average, percentage; +// total = atof(argv[1]) + atof(argv[2]) + atof(argv[3]) + atof(argv[4]) + atof(argv[5]); +// int numOfArgs = argc - 1; +// printf("Total = %.02f\n", total); +// average = total / numOfArgs; +// printf("Average = %.02f\n", average); +// percentage = average / 100; +// printf("Percentage = %.02f %%\n", percentage); +// return 0; +// } diff --git a/cc58findTotalAverageAndPercentage/solution.c b/cc58findTotalAverageAndPercentage/solution.c new file mode 100644 index 0000000..1869b32 --- /dev/null +++ b/cc58findTotalAverageAndPercentage/solution.c @@ -0,0 +1,27 @@ +// https://repl.it/student/assignments/460928/model_solution?fromSubmissionId=1764702 +// https://piazza.com/class/j63w1pdyopf7kj?cid=64 +// https://youtu.be/7sBMwuVb0EI + +#include + +int main() +{ + float a, b, c, d, e; + float total, average, percentage; + + /* Input five floats */ + printf("Enter 5 floats: \n"); + scanf("%f%f%f%f%f", &a, &b, &c, &d, &e); + + /* Calculate total, average, and percentage */ + total = a + b + c + d + e; + average = total / 5.0; + percentage = (total / 500.0) * 100; + + /* Print all results */ + printf("Total = %.2f\n", total); + printf("Average = %.2f\n", average); + printf("Percentage = %.2f %\n", percentage); + + return 0; +} diff --git a/cc59nthFibonacci/nthFibonacci.c b/cc59nthFibonacci/nthFibonacci.c new file mode 100644 index 0000000..b2414af --- /dev/null +++ b/cc59nthFibonacci/nthFibonacci.c @@ -0,0 +1,40 @@ +/* cc59 nthFibonacci +write a program that reads an integer from stdin, +and uses that integer N to calculate the Nth Fibonacci number +*/ + +#include +#include +#include + +// // recursive +// int fib(int n) { +// if (n <= 1) +// return n; +// return fib(n - 1) + fib(n - 2); +// } + +// iterative +int fib(int n){ + if(n <= 1) { + return n; + } + int fibo = 1; + int fiboPrev = 1; + for(int i = 2; i < n; ++i) { + // this breaks when it gets to the 47th fibo number + // and returns -1323752223, the following nth #s are off :() + int temp = fibo; + fibo += fiboPrev; + fiboPrev = temp; + } + return fibo; +} + +int main(int argc, char* argv[]) { + int n; + printf("Enter an integer: "); + scanf("%d", &n); + printf("Nth Fibonacci number is %d\n", fib(n)); + return 0; +} diff --git a/cc59nthFibonacci/solution.c b/cc59nthFibonacci/solution.c new file mode 100644 index 0000000..00ff0e1 --- /dev/null +++ b/cc59nthFibonacci/solution.c @@ -0,0 +1,36 @@ +// https://repl.it/student/assignments/466973/model_solution?fromSubmissionId=1773343 +// https://youtu.be/5qLwPFzqZh8 +// https://piazza.com/class/j63w1pdyopf7kj?cid=67 + +#include +#include + +int main(int argc, char* argv[]) +{ + int n; + size_t i; + long long prevPrev, prev, current; + + printf("Enter an integer: \n"); + scanf("%d", &n); + + assert(n >= 0); + if (n == 0 || n == 1) { + printf("Nth Fibonacci number is %d\n", n); + return 0; + } + + prevPrev = 0; + prev = 1; + current = 0; + + for (i = 1; i < n; i++) { + current = prev + prevPrev; + prevPrev = prev; + prev = current; + } + + printf("Nth Fibonacci number is %lld\n", current); + + return 0; +} diff --git a/cc60linkedList/linkedList.c b/cc60linkedList/linkedList.c new file mode 100644 index 0000000..2cf2e2d --- /dev/null +++ b/cc60linkedList/linkedList.c @@ -0,0 +1,79 @@ +/* cc60 linkedList +It's finally time to implement a linked list in C! +To be slightly less mean, you won't be starting entirely from scratch. + +The node struct is provided for you, along with the `print_list`, and `pop` methods. + +You'll be implementing the `push` method, which wraps the input value +in a new node and adds the new node as the new head of the list. + +You'll also be implementing the `remove_by_value` method, which receives a +list node and a value as inputs, finds the node that contains the value in +the list, and removes it from the list. +*/ + +#include +#include + +typedef struct node { + int val; + struct node * next; +} node_t; + +void print_list(node_t * head) { + node_t * current = head; + + while (current != NULL) { + printf("%d\n", current->val); + current = current->next; + } +} + +int pop(node_t ** head) { + int retval = -1; + node_t * next_node = NULL; + + if (*head == NULL) { + return -1; + } + + next_node = (*head)->next; + retval = (*head)->val; + free(*head); + *head = next_node; + + return retval; +} + +void push(node_t ** head, int val) { + // Your code here + node_t *newNode; + newNode = malloc(sizeof(node_t)); + newNode->val = val; + newNode->next = *head; + *head = newNode; +} + +int remove_by_value(node_t ** head, int val) { + // Your code here +} + +int main() { + node_t * test_list = malloc(sizeof(node_t)); + test_list->val = 1; + test_list->next = malloc(sizeof(node_t)); + test_list->next->val = 2; + test_list->next->next = malloc(sizeof(node_t)); + test_list->next->next->val = 3; + test_list->next->next->next = malloc(sizeof(node_t)); + test_list->next->next->next->val = 4; + test_list->next->next->next->next = NULL; + + print_list(test_list); + + push(&test_list, -1); + print_list(test_list); + + remove_by_value(&test_list, 3); + print_list(test_list); +} diff --git a/cc60linkedList/solution.c b/cc60linkedList/solution.c new file mode 100644 index 0000000..f6fa20e --- /dev/null +++ b/cc60linkedList/solution.c @@ -0,0 +1,92 @@ +// https://piazza.com/class/j63w1pdyopf7kj?cid=69 +// + +// http://www.zentut.com/c-tutorial/c-linked-list/ +// https://www.learn-c.org/en/Linked_lists + +#include +#include + +typedef struct node { + int val; + struct node * next; +} node_t; + +void print_list(node_t * head) { + node_t * current = head; + + while (current != NULL) { + printf("%d\n", current->val); + current = current->next; + } +} + +int pop(node_t ** head) { + int retval = -1; + node_t * next_node = NULL; + + if (*head == NULL) { + return -1; + } + + next_node = (*head)->next; + retval = (*head)->val; + free(*head); + *head = next_node; + + return retval; +} + +void push(node_t ** head, int val) { + node_t * new_node; + new_node = malloc(sizeof(node_t)); + + new_node->val = val; + new_node->next = *head; + *head = new_node; +} + +int remove_by_value(node_t ** head, int val) { + node_t *previous, *current; + + if (*head == NULL) { + return -1; + } + + if ((*head)->val == val) { + return pop(head); + } + + previous = current = (*head)->next; + while (current) { + if (current->val == val) { + previous->next = current->next; + free(current); + return val; + } + + previous = current; + current = current->next; + } + return -1; +} + +int main() { + node_t * test_list = malloc(sizeof(node_t)); + test_list->val = 1; + test_list->next = malloc(sizeof(node_t)); + test_list->next->val = 2; + test_list->next->next = malloc(sizeof(node_t)); + test_list->next->next->val = 3; + test_list->next->next->next = malloc(sizeof(node_t)); + test_list->next->next->next->val = 4; + test_list->next->next->next->next = NULL; + + print_list(test_list); + + push(&test_list, -1); + print_list(test_list); + + remove_by_value(&test_list, 3); + print_list(test_list); +} diff --git a/cc61stack/solution.c b/cc61stack/solution.c new file mode 100644 index 0000000..a26d82d --- /dev/null +++ b/cc61stack/solution.c @@ -0,0 +1,74 @@ +// https://repl.it/student/assignments/470467/model_solution?fromSubmissionId=1789748 +// +// + +#include +#include + +struct Stack +{ + int top; + unsigned capacity; + int* array; +}; + +// Function to create a stack of given capacity. It initializes size of +// stack as 0 +struct Stack* createStack(unsigned capacity) +{ + struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack)); + stack->capacity = capacity; + stack->top = -1; + stack->array = (int*) malloc(stack->capacity * sizeof(int)); + return stack; +} + +// Stack is full when top is equal to the last index +int isFull(struct Stack* stack) +{ + return stack->top == stack->capacity - 1; +} + +// Stack is empty when top is equal to -1 +int isEmpty(struct Stack* stack) +{ + return stack->top == -1; +} + +// Function to add an item to stack. It increases top by 1 +void push(struct Stack* stack, int item) +{ + if (isFull(stack)) { + return; + } + stack->array[++stack->top] = item; + printf("%d pushed to stack\n", item); +} + +// Function to remove an item from stack. It decreases top by 1 +int pop(struct Stack* stack) +{ + if (isEmpty(stack)) { + return -1; + } + return stack->array[stack->top--]; +} + +// Program to test above functions +int main() +{ + struct Stack* stack = createStack(100); + + push(stack, 10); + push(stack, 20); + push(stack, 30); + + printf("%d popped from stack\n", pop(stack)); + printf("The stack is full: %d\n", isFull(stack)); + + printf("%d popped from stack\n", pop(stack)); + printf("%d popped from stack\n", pop(stack)); + printf("The stack is empty: %d\n", isEmpty(stack)); + + return 0; +} diff --git a/cc61stack/stack.c b/cc61stack/stack.c new file mode 100644 index 0000000..806903b --- /dev/null +++ b/cc61stack/stack.c @@ -0,0 +1,72 @@ +/* cc61 stack https://repl.it/student/submissions/1789748 +Implement a stack data structure. +You're provided with a struct representing the Stack, +the `createStack` method, and a `main` function. +Implement the methods `isFull`, `isEmpty`, `push`, and `pop` methods. +*/ + +#include +#include + +struct Stack { + int top; + unsigned capacity; + int* array; +}; + +// Function to create a stack of given capacity. It initializes size of +// stack as 0 +struct Stack* createStack(unsigned capacity) { + struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack)); + stack->capacity = capacity; + stack->top = -1; + stack->array = (int*) malloc(stack->capacity * sizeof(int)); + return stack; +} + +// Stack is full when top is equal to the last index +int isFull(struct Stack* stack) { + if (stack->top == stack->capacity) { + return 1; + } + return 0; +} + +// Stack is empty when top is equal to -1 +int isEmpty(struct Stack* stack) { + if (stack->top <= 0) { + return 1; + } + return 0; +} + +// Function to add an item to stack. It increases top by 1 +void push(struct Stack* stack, int item) { + ++stack->top; + stack->array[stack->top] = item; + printf("%d pushed to stack\n", item); +} + +// Function to remove an item from stack. It decreases top by 1 +int pop(struct Stack* stack) { + --stack->top; + return stack->array[stack->top + 1]; +} + +// Program to test above functions +int main() { + struct Stack* stack = createStack(100); + + push(stack, 10); + push(stack, 20); + push(stack, 30); + + printf("%d popped from stack\n", pop(stack)); + printf("The stack is full: %d\n", isFull(stack)); + + printf("%d popped from stack\n", pop(stack)); + printf("%d popped from stack\n", pop(stack)); + printf("The stack is empty: %d\n", isEmpty(stack)); + + return 0; +} diff --git a/cc62queueUsingStack/queueUsingStack.c b/cc62queueUsingStack/queueUsingStack.c new file mode 100644 index 0000000..bbbd385 --- /dev/null +++ b/cc62queueUsingStack/queueUsingStack.c @@ -0,0 +1,105 @@ +/* cc62 queueUsingStack https://repl.it/student/submissions/1797443 +You guys have seen the classic "create a queue using two stacks" problem. +So today, you're given the stack data structure you implemented for yesterday's code challenge. +Using that, implement a queue that exhibits First In First Out ordering with one stack. +Just one. You may not use any other data structures to implement your queue. + +This time, you'll be implementing all of the queue methods, +namely the Queue struct, `createQueue`, `enqueue`, and `dequeue`. +*/ + +#include +#include + +// The stack struct +struct Stack +{ + int top; + unsigned capacity; + int* array; +}; + +// Function to create a stack of given capacity. +// It initializes size of stack as 0. +struct Stack* createStack(unsigned capacity) +{ + struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack)); + stack->capacity = capacity; + stack->top = -1; + stack->array = (int*) malloc(stack->capacity * sizeof(int)); + return stack; +} + +// Stack is full when top is equal to the last index +int isFull(struct Stack* stack) +{ + return stack->top == stack->capacity - 1; +} + +// Stack is empty when top is equal to -1 +int isEmpty(struct Stack* stack) +{ + return stack->top == -1; +} + +// Function to add an item to the stack. Increases top by 1. +void push(struct Stack* stack, int item) +{ + if (isFull(stack)) { + return; + } + stack->array[++stack->top] = item; +} + +// Function to remove an item from the stack. Decreases top by 1. +int pop(struct Stack* stack) +{ + if (isEmpty(stack)) { + return -1; + } + return stack->array[stack->top--]; +} + +// The queue struct +struct Queue +{ + struct Stack *stack; +}; + +// Create a queue with the given capacity +struct Queue* createQueue(unsigned capacity) +{ + // struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack)); + struct Queue*queue->stack = createStack(capacity); +} + +// Add and item to the queue +void enqueue(struct Queue* queue, int item) +{ + // Your code here + push(queue->stack, item); + printf("%d enqueued onto queue\n", item); +} + +// Remove the queue element that was least-recently added +int dequeue(struct Queue* queue) +{ + // Your code here + +} + +// Program to test above functions +int main() +{ + struct Queue* queue = createQueue(100); + + enqueue(queue, 10); + enqueue(queue, 20); + enqueue(queue, 30); + + printf("%d dequeued from queue\n", dequeue(queue)); + printf("%d dequeued from queue\n", dequeue(queue)); + printf("%d dequeued from queue\n", dequeue(queue)); + + return 0; +} diff --git a/cc62queueUsingStack/solution.c b/cc62queueUsingStack/solution.c new file mode 100644 index 0000000..6ab6f29 --- /dev/null +++ b/cc62queueUsingStack/solution.c @@ -0,0 +1,113 @@ +// https://youtu.be/PRkNuAgkXww +// https://piazza.com/class/j63w1pdyopf7kj?cid=72 + +#include +#include + +// The stack struct +struct Stack +{ + int top; + unsigned capacity; + int* array; +}; + +// Function to create a stack of given capacity. +// It initializes size of stack as 0. +struct Stack* createStack(unsigned capacity) +{ + struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack)); + stack->capacity = capacity; + stack->top = -1; + stack->array = (int*) malloc(stack->capacity * sizeof(int)); + return stack; +} + +// Stack is full when top is equal to the last index +int isFull(struct Stack* stack) +{ + return stack->top == stack->capacity - 1; +} + +// Stack is empty when top is equal to -1 +int isEmpty(struct Stack* stack) +{ + return stack->top == -1; +} + +// Function to add an item to the stack. Increases top by 1. +void push(struct Stack* stack, int item) +{ + if (isFull(stack)) { + return; + } + stack->array[++stack->top] = item; +} + +// Function to remove an item from the stack. Decreases top by 1. +int pop(struct Stack* stack) +{ + if (isEmpty(stack)) { + return -1; + } + return stack->array[stack->top--]; +} + +// The queue struct +struct Queue +{ + // Your code here + struct Stack* stack; +}; + +// Create a queue with the given capacity +struct Queue* createQueue(unsigned capacity) +{ + // Your code here + struct Queue* queue = (struct Queue*) malloc(sizeof(struct Queue)); + queue->stack = createStack(capacity); + return queue; +} + +// Add and item to the queue +void enqueue(struct Queue* queue, int item) +{ + // Your code here + if (isFull(queue->stack)) { + return; + } + push(queue->stack, item); + printf("%d enqueued onto queue\n", item); +} + +// Remove the queue element that was least-recently added +int dequeue(struct Queue* queue) +{ + // Your code here + int top, result; + top = pop(queue->stack); + + if (isEmpty(queue->stack)) { + return top; + } else { + result = dequeue(queue); + push(queue->stack, top); + return result; + } +} + +// Program to test above functions +int main() +{ + struct Queue* queue = createQueue(100); + + enqueue(queue, 10); + enqueue(queue, 20); + enqueue(queue, 30); + + printf("%d dequeued from queue\n", dequeue(queue)); + printf("%d dequeued from queue\n", dequeue(queue)); + printf("%d dequeued from queue\n", dequeue(queue)); + + return 0; +} diff --git a/cc63binaryTreeSearch/binaryTreeSearch.c b/cc63binaryTreeSearch/binaryTreeSearch.c new file mode 100644 index 0000000..f2283a1 --- /dev/null +++ b/cc63binaryTreeSearch/binaryTreeSearch.c @@ -0,0 +1,62 @@ +/* cc63 binaryTreeSearch https://repl.it/student/submissions/1809823 +Implement a binary search tree with the following methods: + +- newNode: Creates a new binary search tree node +- insert: Inserts a new node in the binary search tree +- printInOrder: Given a root node, print the root node's value and + all of its children's values in ascending order. For example, given the tree + + 10 + / \ + 7 19 + / \ / \ + 6 9 11 20 + +printInOrder should print: 6 7 9 10 11 19 20 +*/ + +#include +#include + +struct node { + struct node* left; + struct node* right; + int data; +}; + +struct node* newNode(int item) +{ + node *new_node = (node*)malloc(sizeof(node)); + new_node->data = item; + new_node->left = NULL; + new_node->right = NULL; + return new_node; +} + +void printInOrder(struct node *root) +{ + +} + +struct node* insert(struct node* node, int item) +{ + if (node == NULL) { + + } +} + +int main(int argc, char* argv[]) +{ + struct node *root = NULL; + root = insert(root, 50); + insert(root, 30); + insert(root, 20); + insert(root, 40); + insert(root, 70); + insert(root, 60); + insert(root, 80); + + printInOrder(root); + + return 0; +} diff --git a/cc63binaryTreeSearch/solution.c b/cc63binaryTreeSearch/solution.c new file mode 100644 index 0000000..4b115ef --- /dev/null +++ b/cc63binaryTreeSearch/solution.c @@ -0,0 +1,61 @@ +// http://www.zentut.com/c-tutorial/c-binary-search-tree/ +// https://youtu.be/E2Wv-JXJFuM +// https://piazza.com/class/j63w1pdyopf7kj?cid=73 + +#include +#include + +struct node { + int value; + struct node *left; + struct node *right; +}; + +struct node* newNode(int item) +{ + struct node* bst_node = (struct node *) malloc(sizeof(struct node)); + bst_node->value = item; + bst_node->left = NULL; + bst_node->right = NULL; + return bst_node; +} + +void printInOrder(struct node *root) +{ + if (root != NULL) { + printInOrder(root->left); + printf("%d \n", root->value); + printInOrder(root->right); + } +} + +struct node* insert(struct node* node, int item) +{ + if (node == NULL) { + return newNode(item); + } + + if (item < node->value) { + node->left = insert(node->left, item); + } else { + node->right = insert(node->right, item); + } + + return node; +} + +int main(int argc, char* argv[]) +{ + struct node *root = NULL; + root = insert(root, 50); + insert(root, 30); + insert(root, 20); + insert(root, 40); + insert(root, 70); + insert(root, 60); + insert(root, 80); + + printInOrder(root); + + return 0; +} diff --git a/cc64quisksort/quicksort.c b/cc64quisksort/quicksort.c new file mode 100644 index 0000000..5613823 --- /dev/null +++ b/cc64quisksort/quicksort.c @@ -0,0 +1,63 @@ +/* +Implement the quick sort sorting algorithm. +Assume the input is an array of integers. + +If you need to refresh your memory on the quick sort algorithm, +feel free to reference your old JavaScript implementation, as well as the following links: + +https://en.wikipedia.org/wiki/Quicksort + +https://www.khanacademy.org/computing/computer-science/algorithms#quick-sort +*/ + +#include + +void swap(int* a, int* b) +{ + int t = *a; + *a = *b; + *b = t; +} + +int partition (int arr[], int low, int high) +{ + int pivot = arr[high]; + int i = (low - 1); + + for (int j = low; j <= high- 1; ++j) + { + if (arr[j] <= pivot) + { + ++i; + swap(&arr[i], &arr[j]); + } + } + swap(&arr[i + 1], &arr[high]); + return (i + 1); +} + +void quick_sort(int arr[], int low, int high) +{ + if (low < high) + { + int pi = partition(arr, low, high); + quick_sort(arr, low, pi - 1); + quick_sort(arr, pi + 1, high); + } +} + +void print_array(int arr[], int size) +{ + for (int i = 0; i < size; ++i) { + printf("%d\n", arr[i]); + } +} + +int main(int argc, char* argv[]) +{ + int arr[] = {100, 55, 4, 98, 10, 18, 90, 95, 43, 11, 47, 67, 89, 42, 49, 79}; + int n = sizeof(arr) / sizeof(arr[0]); + quick_sort(arr, 0, n - 1); + print_array(arr, n); + return 0; +} diff --git a/cc64quisksort/solution.c b/cc64quisksort/solution.c new file mode 100644 index 0000000..f703b2f --- /dev/null +++ b/cc64quisksort/solution.c @@ -0,0 +1,54 @@ +// https://youtu.be/krtTy-mRaNk +// https://repl.it/student/assignments/484784/model_solution?fromSubmissionId=1817075 +// http://www.geeksforgeeks.org/quick-sort/ + + +#include + +void swap(int* a, int* b) +{ + int temp = *a; + *a = *b; + *b = temp; +} + +int partition(int arr[], int low, int high) +{ + int pivot = arr[high]; + int i = low - 1; + + for (int j = low; j <= high - 1; j++) { + if (arr[j] <= pivot) { + i++; + swap(&arr[i], &arr[j]); + } + } + + swap(&arr[i+1], &arr[high]); + return i + 1; +} + +void quick_sort(int arr[], int low, int high) +{ + if (low < high) { + int index = partition(arr, low, high); + quick_sort(arr, low, index - 1); + quick_sort(arr, index + 1, high); + } +} + +void print_array(int arr[], int size) +{ + for (int i = 0; i < size; i++) { + printf("%d\n", arr[i]); + } +} + +int main(int argc, char* argv[]) +{ + int arr[] = {100, 55, 4, 98, 10, 18, 90, 95, 43, 11, 47, 67, 89, 42, 49, 79}; + int n = sizeof(arr) / sizeof(arr[0]); + quick_sort(arr, 0, n-1); + print_array(arr, n); + return 0; +} diff --git a/cc65mergeSort/mergeSort.c b/cc65mergeSort/mergeSort.c new file mode 100644 index 0000000..61af0ec --- /dev/null +++ b/cc65mergeSort/mergeSort.c @@ -0,0 +1,57 @@ +/* cc65 mergeSort https://repl.it/student/submissions/1824513 +Reference https://en.wikipedia.org/wiki/Merge_sort, as well as your own JavaScript +implementation of this sorting algorithm, for more details about how this sorting algorithm works. +Sort an array of integers using the merge sort algorithm. +First divide the list into its smallest unit (arrays with a single item in them). +Then compare each element with the adjacent list and combine them in the proper order. +Repeat until the entire array is sorted. + +Example: +- Input: [1, 6, 3, 2, 4, 7] +- Expected Output: [1, 2, 3, 4, 6, 7]; + +[1, 6, 3, 2, 4, 7] -> [1, 2, 3, 4, 6, 7] +[1, 6, 3][2, 4, 7] +[1][6, 3][2][4, 7] +[1][6][3][2][4][7] +[1, 3][6][2][4][7] +[1, 3][6][2, 4][7] +[1, 3, 6][2, 4][7] +[1, 3, 6][2, 4, 7] +[1, 2, 3, 4, 6, 7] +*/ + +#include +#include + +void merge(int arr[], int left, int mid, int right) +{ + +} + +void mergesort(int arr[], int left, int right) +{ + +} + +void print_array(int arr[], int size) +{ + for (int i = 0; i < size; i++) { + printf("%d\n", arr[i]); + } +} + +int main(int argc, char* argv[]) +{ + int arr[] = {90, 98, 14, 57, 30, 10, 59, 81, 12, 11, 13, 5, 69, 13, 6, 7}; + int arr_size = sizeof(arr)/sizeof(arr[0]); + + printf("Given array is \n"); + print_array(arr, arr_size); + + mergesort(arr, 0, arr_size - 1); + + printf("\nSorted array is \n"); + print_array(arr, arr_size); + return 0; +} diff --git a/cc65mergeSort/solution.c b/cc65mergeSort/solution.c new file mode 100644 index 0000000..8640415 --- /dev/null +++ b/cc65mergeSort/solution.c @@ -0,0 +1,81 @@ +// http://www.stoimen.com/blog/2010/07/02/friday-algorithms-javascript-merge-sort/ +// https://piazza.com/class/j63w1pdyopf7kj?cid=76 +// https://youtu.be/H4psSvw7DJQ + +#include +#include + +void merge(int arr[], int left, int mid, int right) +{ + int i, j, k; + int n1 = mid - left + 1; + int n2 = right - mid; + int L[n1], R[n2]; + + for (i = 0; i < n1; i++) { + L[i] = arr[left + i]; + } + for (j = 0; j < n2; j++) { + R[j] = arr[mid + 1 + j]; + } + + i = 0, j = 0, k = left; + + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k] = L[i]; + i++; + } else { + arr[k] = R[j]; + j++; + } + k++; + } + + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } +} + +void mergesort(int arr[], int left, int right) +{ + if (left < right) { + int mid = (left + right) / 2; + + mergesort(arr, left, mid); + mergesort(arr, mid + 1, right); + + merge(arr, left, mid, right); + } +} + +void print_array(int arr[], int size) +{ + for (int i = 0; i < size; i++) { + printf("%d\n", arr[i]); + } +} + +int main(int argc, char* argv[]) +{ + int arr[] = {90, 98, 14, 57, 30, 10, 59, 81, 12, 11, 13, 5, 69, 13, 6, 7}; + int arr_size = sizeof(arr)/sizeof(arr[0]); + + printf("Given array is \n"); + print_array(arr, arr_size); + + mergesort(arr, 0, arr_size - 1); + + printf("\nSorted array is \n"); + print_array(arr, arr_size); + + return 0; +} diff --git a/cc66insertionSort/insertionSort.c b/cc66insertionSort/insertionSort.c new file mode 100644 index 0000000..760f59b --- /dev/null +++ b/cc66insertionSort/insertionSort.c @@ -0,0 +1,52 @@ +/* cc66 https://repl.it/student/submissions/1831101 +Implement the insertion sort algorithm, which works by iterating over +an array and growing a sorted array behind the current location. +It takes each element from the input and finds its spot, up to the current point in the array. + +First, reference your old implementation in JavaScript, or, if you didn't +finish implementing insertion sort the first time you saw it, this article +walks you through a JS implementation: +http://blog.benoitvallon.com/sorting-algorithms-in-javascript/the-insertion-sort-algorithm/ + +As you read through the JavaScript implementation, figure out the steps, +in pseudocode or plain english, that the algorithm takes in order to achieve +its goal of sorting the input. Once you've specified just the algorithmic +steps of insertion sort, now figure out how to perform each step in C. + +At the very least, submit your pseudocode for how insertion sort works +if you can't get started on a C implementation. +*/ + +#include + +void insertionSort(int arr[], int n) +{ + int i, j; + for (i = 0; i < n; ++i) { + int temp = arr[i]; + j = i - 1; + while (j >= 0 & arr[j] > temp) { + arr[j + 1] = arr[j]; + --j; + } + arr[j + 1] = temp; + } +} + +void printArray(int arr[], int n) +{ + for (int i = 0; i < n; i++) { + printf("%d\n", arr[i]); + } +} + +int main(int argc, char* argv[]) +{ + int arr[] = {100, 55, 4, 98, 10, 18, 90, 95, 43, 11, 47, 67, 89, 42, 49, 79}; + int n = sizeof(arr)/sizeof(arr[0]); + + insertionSort(arr, n); + printArray(arr, n); + + return 0; +} diff --git a/cc66insertionSort/solution.c b/cc66insertionSort/solution.c new file mode 100644 index 0000000..5081227 --- /dev/null +++ b/cc66insertionSort/solution.c @@ -0,0 +1,39 @@ +// https://repl.it/student/assignments/490756/model_solution?fromSubmissionId=1831101 +// + +#include +// #include + +void insertionSort(int arr[], int n) +{ + int i, j, key; + + for (i = 1; i < n; i++) { + key = arr[i]; + j = i - 1; + + while (j >= 0 && arr[j] > key) { + arr[j + 1] = arr[j]; + j--; + } + arr[j + 1] = key; + } +} + +void printArray(int arr[], int n) +{ + for (int i = 0; i < n; i++) { + printf("%d\n", arr[i]); + } +} + +int main(int argc, char* argv[]) +{ + int arr[] = {100, 55, 4, 98, 10, 18, 90, 95, 43, 11, 47, 67, 89, 42, 49, 79}; + int n = sizeof(arr)/sizeof(arr[0]); + + insertionSort(arr, n); + printArray(arr, n); + + return 0; +} diff --git a/cc67highestProductOfThree/highestProductOfThree.c b/cc67highestProductOfThree/highestProductOfThree.c new file mode 100644 index 0000000..7e35866 --- /dev/null +++ b/cc67highestProductOfThree/highestProductOfThree.c @@ -0,0 +1,85 @@ +/* cc67 highestProductOfThree https://repl.it/student/submissions/1837298 + +Given an array of integers, write a function that finds the highest product of +three from amongst any three integers in the array. You can assume any input +arrays have at least three integers. + +You'll need to take into account the fact that it is possible for the highest +product of three from a given array to be the product of two negative numbers +and a positive number. + +For example, given the array [-90, -15, 6, 9, 10], the highest product of any +three numbers from this array is -90 * -15 * 10 which yields 13,500. + +Remember to start off by thinking through and coming up with an algorithm that +will solve this problem regardless of what programming language you use. Once +you have an algorithm, implement it. In the case of this problem, the C +implementation should be very similar to the JavaScript implementation in terms +of code syntax and structure. +*/ + +#include +#include +#include + +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define SIZE(arr) (sizeof(arr) / sizeof(arr[0])) + +void insertionSort(int arr[], int n) +{ + int i, j; + for (i = 0; i < n; ++i) { + int temp = arr[i]; + j = i - 1; + while (j >= 0 & arr[j] > temp) { + arr[j + 1] = arr[j]; + --j; + } + arr[j + 1] = temp; + } +} + +void printArray(int arr[], int n) +{ + for (int i = 0; i < n; i++) { + printf("%d\n", arr[i]); + } +} + +int highestProductOf3(int arr[], int length) +{ + printf("Before sorting the list is: \n"); + printArray(arr, length); + // sort the array high to low ( -n ... 0 ... n+ ) + // qsort(arr, SIZE(arr), sizeof(arr[0]), MIN(arr[])); + insertionSort(arr, length); + printf("Sorted array: \n"); + printArray(arr, length); + + // if two lowest negatives and highest positive are greater than the three highest positives + if (arr[0] * arr[1] * arr[length] > arr[length - 3] * arr[length - 2] * arr[length - 1]) { + puts("What the frog?"); + return arr[0] * arr[1] * arr[length]; + // else return three highest positives + } else { + puts("Frog the what?"); + return arr[length - 2] * arr[length - 1] * arr[length]; + } + +} + +int main(int argc, char** argv) +{ + int arr1[] = {-10, -10, 1, 3, 2}; // ~~~> 300 + int arr2[] = {1, 10, -5, 1, -100}; // ~~~> 5000 + int arr3[] = {5, -20, 19, 16, 4}; // ~~~> 1520 + int arr4[] = {-20, -2, 3, 4, 10}; // ~~~> 400 + + printf("Highest product of arr1 is: %d\n", highestProductOf3(arr1, SIZE(arr1))); + printf("Highest product of arr2 is: %d\n", highestProductOf3(arr2, SIZE(arr2))); + printf("Highest product of arr3 is: %d\n", highestProductOf3(arr3, SIZE(arr3))); + printf("Highest product of arr4 is: %d\n", highestProductOf3(arr4, SIZE(arr4))); + + return 0; +} diff --git a/cc67highestProductOfThree/solution.c b/cc67highestProductOfThree/solution.c new file mode 100644 index 0000000..77d69de --- /dev/null +++ b/cc67highestProductOfThree/solution.c @@ -0,0 +1,73 @@ +// https://piazza.com/class/j63w1pdyopf7kj?cid=78 +// https://youtu.be/DfFBYylXx5U + +#include +#include +#include + +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define SIZE(arr) (sizeof(arr) / sizeof(arr[0])) + +int highestProductOf3(int arr[], int length) +{ + int i; + int highest, lowest; + int highestProductOf2, lowestProductOf2, highestProductOf3; + + assert(length >= 3); + + // we're going to start at the 3rd item (at index 2) + // so pre-populate highests and lowests based on the first 2 items. + highest = MAX(arr[0], arr[1]); + lowest = MIN(arr[0], arr[1]); + + highestProductOf2 = arr[0] * arr[1]; + lowestProductOf2 = arr[0] * arr[1]; + + // except this one--we pre-populate it for the first *3* items. + // this means in our first pass it'll check against itself, which is fine. + highestProductOf3 = arr[0] * arr[1] * arr[2]; + + // walk through items, starting at index 2 + for (i = 2; i < length; i++) { + int temp; + int current = arr[i]; + + // do we have a new highest product of 3? + // it's either the current highest, + // or the current times the highest product of two + // or the current times the lowest product of two + temp = MAX(highestProductOf3, current * highestProductOf2); + highestProductOf3 = MAX(temp, current * lowestProductOf2); + + // do we have a new highest product of two? + temp = MAX(highestProductOf2, current * highest); + highestProductOf2 = MAX(temp, current * lowest); + + // do we have a new lowest product of two? + temp = MIN(lowestProductOf2, current * highest); + lowestProductOf2 = MIN(temp, current * lowest); + + // do we have a new highest? + highest = MAX(highest, current); + + // do we have a new lowest? + lowest = MIN(lowest, current); + } + + return highestProductOf3; +} + +int main(int argc, char* argv) +{ + int arr1[] = {-10, -10, 1, 3, 2}; + int arr2[] = {1, 10, -5, 1, -100}; + int arr3[] = {5, -20, 19, 16, 4}; + + printf("Highest product of arr1 is: %d\n", highestProductOf3(arr1, SIZE(arr1))); + printf("Highest product of arr2 is: %d\n", highestProductOf3(arr2, SIZE(arr2))); + printf("Highest product of arr3 is: %d\n", highestProductOf3(arr3, SIZE(arr3))); + + return 0; +} diff --git a/cc68pythonCrashCourse/pythonCrashCourse.py b/cc68pythonCrashCourse/pythonCrashCourse.py new file mode 100644 index 0000000..ea6057d --- /dev/null +++ b/cc68pythonCrashCourse/pythonCrashCourse.py @@ -0,0 +1,254 @@ +# cc68 pythonCrashCourse +# https://repl.it/student/submissions/1847090 + +''' +Let's walk through the basic language constructs of Python. +This will be a bit of a whirlwind through a bunch of basic Python features. +Don't stress about not remembering all of these details at the end of this, +you definitely won't remember it all, so just accept that fact right now :) + +Remember, we're delving into other programming languages in an attempt to +broaden your breadth, and to continually practice decoupling the way you think +about problems from how you implement problems. + +Follow along the instructions and try out the exercises whenever you're prompted. +Little exercises strewn throughout the assignment are prefaced with EXERCISE, so look out for those. + +Here's a link to a pretty thorough Python manual that much of this material was drawn from: +http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html +''' + +# Comments in Python use the '#' symbol + +''' Multi-line comments are denoted via three single or three double quotes +And are ended with the matching set of three single or double quotes ''' + +''' Let's start off by defining some variables +In Python, there's no `let`, `const`, or `var` keyword to declare variables +Python is also not statically typed, so you don't declare the variable type when assigning a variable +Variables assigned outside the scope of any functions have global scope ''' + +a = 1 +b = 2 + +# Also note that expressions don't end with semicolons +# EXERCISE: Define a global variable PI and have it store as many digits of pi as you can muster +PI = 3.14159 + + + +# FUNCTIONS + +# Functions in Python are defined via the `def` keyword +# Also, there are no braces in Python; whitespace actually matters! + +''' After closing the parentheses where function parameters go, +instead of an opening curly brace, a colon is used: ''' + +def example_function(new_input_to_append, a_list=None): + # Same thing with if statements; end them with a colon + if a_list == None: + a_list = [] + a_list.append(new_input_to_append) + return a_list + +# A function body is closed by a new line + +''' Functions are invoked the same way as in JavaScript and C, with parens +Here, we're invoking our example function with the variable `c` you +defined earlier and nothing as the second argument, meaning the function +will utilize the default parameter that was given in the function definition ''' + +print("Our example function returns: ", example_function(PI)) + + + +# LOOPS + +''' For loops in Python do not follow the C-style loops you are used to writing in +both JavaScript and C. Python opts for a much cleaner syntax with regards to loops. ''' + +# We iterate a specified number of times using the `range` function +for x in range(5): + print(x, end="") +print() + +# The body of the loop is denoted by indentation, so you need to delineate your whitespace correctly + +# Given a list (arrays are called lists in Python), we iterate through it like so +fibonacci = [1, 1, 2, 3, 5, 8, 13] +for number in fibonacci: + print(number, end="") +print() + +# You can loop over an element along with its index using the `enumerate` function like so: +for index, number in enumerate(fibonacci): + print(index, number) + +# While loops work exactly the way you're used to working with them in JS and C +# Note however that ++ and -- are not valid ways of incrementing and decrementing in Python +count = 0 +while count < 5: + print(count) + count += 1 + +''' EXERCISE: Loop through and print out all the even numbers from the numbers list given +below. Ensure that the numbers are printed in the same order in which they appear in the +numbers list. Don't print any numbers that come after 237 in the sequence. ''' +numbers = [ + 951, 402, 984, 651, 360, 69, 408, 319, 601, 485, 980, 507, 725, 547, 544, + 615, 83, 165, 141, 501, 263, 617, 865, 575, 219, 390, 984, 592, 236, 105, 942, 941, + 386, 462, 47, 418, 907, 344, 236, 375, 823, 566, 597, 978, 328, 615, 953, 345, + 399, 162, 758, 219, 918, 237, 412, 566, 826, 248, 866, 950, 626, 949, 687, 217, + 815, 67, 104, 58, 512, 24, 892, 894, 767, 553, 81, 379, 843, 831, 445, 742, 717, + 958, 609, 842, 451, 688, 753, 854, 685, 93, 857, 440, 380, 126, 721, 328, 753, 470, + 743, 527 +] + +# Your code here: +for n in numbers: + if n < 237: + if n % 2 == 0: + print(n) + + + + +# STRINGS + +# Given a list of strings, we want to join them all together into one large string +colors = ['red', 'blue', 'green', 'yellow'] + +# DON'T do this: +result = '' +for s in colors: + result += s + +# This is extremely inefficient because strings in Python are immutable, unlike in JS and C +# We can't just mutate them willy-nilly +# Instead, join them using the built-in string `.join` method like so: +result = ''.join(colors) +print("Result of calling .join on colors list: ", result) + +# If you want spaces between your substrings, you can do this: +result = ' '.join(colors) +print("Result of calling .join on colors list with spaces: ", result) + +# Or if you want your substrings separated via commans: +result = ', '.join(colors) +print("Result of calling .join on colors list with commas: ", result) + +# EXERCISE: Write a function to reverse an input string; feel free to look this up +def reverse_string(s): + # Your code here + return s[::-1] + +print("reverse_string function returns: ", reverse_string('hello world')) + + + +# STRING FORMATTING +''' Python's `%` operator works like C's `sprintf` function. If you don't know what that does, +let's illustrate with an example: ''' +name = 'David' +messages = 3 +text = ('Hello %s, you have %i messages' %(name, messages)) +print(text) + +''' The `%s` means "insert a string here", and the `%i` means "convert an integer into a string and +insert here". ''' + + + +# DICTIONARIES +''' JavaScript objects are called dictionaries in Python, but they're both just implementations +of hash tables. You work with them exactly as how you work with JS objects. The one exception is +that using dot notation to access a dict value is not a thing in Python. Bracket notation must +be used. ''' + +''' Here's a neat little example of building a dict from two lists, one a list of keys, +the other a list of values, using the `zip` function to conglomerate these two lists ''' +first_names = ['John', 'Eric', 'Terry', 'Michael'] +last_names = ['Cleese', 'Idle', 'Gilliam', 'Pallor'] + +full_names = dict(zip(first_names, last_names)) +print("full_names dict: ", full_names) + +# full_names.John doesn't work; use full_names['John'] instead +print(full_names['John']) #<~~ 'Cleese' + +# Dicts come with the `.keys` and `.values` methods you're used to on JS objects +print("full_names dict keys: ", full_names.keys()) +print("full_names dict values: ", full_names.values()) + + + +# LISTS +''' Python lists, akin to JS arrays, pretty much also work as you're used to. +Not much to say here, except the way you find the length of a list is by using +the `len()` function instead of accessing a property on the list''' + +print("The length of this list is: ", len([4,6,8,4,1,4,6,7,5,4,3,2,2,8,10])) + + + +# COMPREHENSIONS +''' Comprehensions are one of the coolest features of Python. Most of the time you'll +use them with lists, so let's illustrate that first. ''' + +# We have the following code: +squares = [] +for x in range(10): + squares.append(x**2) +print(squares) + +''' Looks fine. Does what you'd expect it to. In Python, though, this can be very +concisely one-lined via a list comprehension: ''' +squares = [x**2 for x in range(10)] +print("Squares list comprehension returns: ", squares) + +''' A list comprehension consists of brackets containing an expression followed by a +`for` clause, then zero or more `for` or `if` clauses. The result will be a new list +resulting from evaluating the expression in the context of the `for` and `if` clauses +which follow it. Another example: ''' +stuff = [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y] +print("Stuff list comprehension returns: ", stuff) + +''' The above list comprehension combines the elements of two lists into a new list if +elements at matching indexes do not match ''' + +# Comprehensions aren't only limited to lists; they work with dicts as well! +# The following comprehension builds a dict where value is indexed by its square root: +squares_dict = {x: x**2 for x in range(10)} +print("squares_dict list comprehension returns: ", squares_dict) + +''' EXERCISE: Write a dict comprehension to populate a dict with all the letters of +the alphabet as values with their keys being their index in the alphabet: ''' +from string import ascii_lowercase +# Your code here + +alphabet_dict = {num: alpha for num, alpha in enumerate(ascii_lowercase)} +print("alphabet_dict list comprehension returns: ", alphabet_dict) + + + +# LAMBDA FUNCTIONS +'''Anonymous functions in Python are called lambdas. They are denoted by the `lambda` keyword. +Here's a simple example: ''' +f = lambda x, y : x + y +print("Lambda function `f` returns: ", f(1, 1)) + +''' Lambdas are most effective when passed to functions such as `map`, `filter`, and `reduce`. +Just like how these three functions accept callbacks that specify how you want each function +to behave, in Python, lambdas do the same thing as callbacks in this case. +Here's an example using the `filter` function which filters out the non-even fibonacci numbers: ''' +fib = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55] +result = list(filter(lambda x: x % 2 == 0, fib)) +print("Result of filtering out non-even fib numbers: ", result) + +''' EXERCISE: Use `reduce` to find the maximum value in the given `ints` list. +But first, we need to import `reduce` from the `functools` module: ''' +from functools import reduce +ints = [47, 11, 42, 102, 13] +result = reduce(lambda x, y: x if x > y else y, ints) +print("Result of reducing a list to find the max: ", result) diff --git a/cc68pythonCrashCourse/solution.py b/cc68pythonCrashCourse/solution.py new file mode 100644 index 0000000..d9ffe43 --- /dev/null +++ b/cc68pythonCrashCourse/solution.py @@ -0,0 +1,231 @@ +# https://piazza.com/class/j63w1pdyopf7kj?cid=80 +# https://youtu.be/qUmJVVOSFyY + +# Comments in Python use the '#' symbol + +''' Multi-line comments are denoted via three single or three double quotes +And are ended with the matching set of three single or double quotes ''' + +''' Let's start off by defining some variables +In Python, there's no `let`, `const`, or `var` keyword to declare variables +Python is also not statically typed, so you don't declare the variable type when assigning a variable +Variables assigned outside the scope of any functions have global scope ''' + +a = 1 +b = 2 + +# Also note that expressions don't end with semicolons +# EXERCISE: Define a global variable PI and have it store as many digits of pi as you can muster +PI = 3.14 + + + +# FUNCTIONS + +# Functions in Python are defined via the `def` keyword +# Also, there are no braces in Python; whitespace actually matters! + +''' After closing the parentheses where function parameters go, +instead of an opening curly brace, a colon is used; ''' + +def example_function(new_input_to_append, a_list=None): + # Same thing with if statements; end them with a colon + if a_list == None: + a_list = [] + a_list.append(new_input_to_append) + return a_list + +# A function body is closed by a new line + +''' Functions are invoked the same way as in JavaScript and C, with parens +Here, we're invoking our example function with the variable `c` you +defined earlier and nothing as the second argument, meaning the function +will utilize the default parameter that was given in the function definition ''' +print("Our example function returns: ", example_function(PI)) + + + +# LOOPS + +''' For loops in Python do not follow the C-style loops you are used to writing in +both JavaScript and C. Python opts for a much cleaner syntax with regards to loops. ''' + +# We iterate a specified number of times using the `range` function +for x in range(5): + print(x) + +# The body of the loop is denoted by indentation, so you need to delineate your whitespace correctly + +# Given an list (arrays are called lists in Python), we iterate through it like so +fibonacci = [1, 1, 2, 3, 5, 8, 13] +for number in fibonacci: + print(number) + +# You can loop over an element along with its index using the `enumerate` function like so: +for index, number in enumerate(fibonacci): + print(index, number) + +# While loops work exactly the way you're used to working with them in JS and C +# Note however that ++ and -- are not valid ways of incrementing and decrementing in Python +count = 0 +while count < 5: + print(count) + count += 1 + +''' EXERCISE: Loop through and print out all the even numbers from the numbers list given +below. Ensure that the numbers are printed in the same order in which they appear in the +numbers list. Don't print any numbers that come after 237 in the sequence. ''' +numbers = [ + 951, 402, 984, 651, 360, 69, 408, 319, 601, 485, 980, 507, 725, 547, 544, + 615, 83, 165, 141, 501, 263, 617, 865, 575, 219, 390, 984, 592, 236, 105, 942, 941, + 386, 462, 47, 418, 907, 344, 236, 375, 823, 566, 597, 978, 328, 615, 953, 345, + 399, 162, 758, 219, 918, 237, 412, 566, 826, 248, 866, 950, 626, 949, 687, 217, + 815, 67, 104, 58, 512, 24, 892, 894, 767, 553, 81, 379, 843, 831, 445, 742, 717, + 958, 609, 842, 451, 688, 753, 854, 685, 93, 857, 440, 380, 126, 721, 328, 753, 470, + 743, 527 +] + +# Your code here: +for n in numbers: + if n % 2 == 0: + print(n) + if x == 237: + break + + + +# STRINGS + +# Given a list of strings, we want to join them all together into one large string +colors = ['red', 'blue', 'green', 'yellow'] + +# DON'T do this: +result = '' +for s in colors: + result += s + +# This is extremely inefficient because strings in Python are immutable, unlike in JS and C +# We can't just mutate them willy-nilly +# Instead, join them using the built-in string `.join` method like so: +result = ''.join(colors) +print("Result of calling .join on colors list: ", result) + +# If you want spaces between your substrings, you can do this: +result = ' '.join(colors) +print("Result of calling .join on colors list with spaces: ", result) + +# Or if you want your substrings separated via commans: +result = ', '.join(colors) +print("Result of calling .join on colors list with commas: ", result) + +# EXERCISE: Write a function to reverse an input string; feel free to look this up +def reverse_string(s): + # Your code here + return s[::-1] + +print("reverse_string function returns: ", reverse_string('hello world')) + + + +# STRING FORMATTING +''' Python's `%` operator works like C's `sprintf` function. If you don't know what that does, +let's illustrate with an example: ''' +name = 'David' +messages = 3 +text = ('Hello %s, you have %i messages' %(name, messages)) +print(text) + +''' The `%s` means "insert a string here", and the `%i` means "convert an integer into a string and +insert here". ''' + + + +# DICTIONARIES +''' JavaScript objects are called dictionaries in Python, but they're both just implementations +of hash tables. You work with them exactly as how you work with JS objects. The one exception is +that using dot notation to access a dict value is not a thing in Python. Bracket notation must +be used. ''' + +''' Here's a neat little example of building a dict from two lists, one a list of keys, +the other a list of values, using the `zip` function to conglomerate these two lists ''' +first_names = ['John', 'Eric', 'Terry', 'Michael'] +last_names = ['Cleese', 'Idle', 'Gilliam', 'Pallor'] + +full_names = dict(zip(first_names, last_names)) +print("full_names dict: ", full_names) + +# full_names.John doesn't work; use full_names['John'] instead + +# Dicts come with the `.keys` and `.values` methods you're used to on JS objects +print("full_names dict keys: ", full_names.keys()) +print("full_names dict values: ", full_names.values()) + + + +# LISTS +''' Python lists, akin to JS arrays, pretty much also work as you're used to. +Not much to say here, except the way you find the length of a list is by using +the `len()` function instead of accessing a property on the list''' +print("The length of this list is: ", len([4,6,8,4,1,4,6,7,5,4,3,2,2,8,10])) + + + + +# COMPREHENSIONS +''' Comprehensions are one of the coolest features of Python. Most of the time you'll +use them with lists, so let's illustrate that first. ''' + +# We have the following code: +squares = [] +for x in range(10): + squares.append(x**2) + +''' Looks fine. Does what you'd expect it to. In Python, though, this can be very +concisely one-lined via a list comprehension: ''' +squares = [x**2 for x in range(10)] +print("Squares list comprehension returns: ", squares) + +''' A list comprehension consists of brackets containing an expression followed by a +`for` clause, then zero or more `for` or `if` clauses. The result will be a new list +resulting from evaluating the expression in the context of the `for` and `if` clauses +which follow it. Another example: ''' +stuff = [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y] +print("Stuff list comprehension returns: ", stuff) + +''' The above list comprehension combines the elements of two lists into a new list if +elements at matching indexes do not match ''' + +# Comprehensions are only limited to lists; they work with dicts as well! +# The following comprehension builds a dict where value is indexed by its square root: +squares_dict = {x: x**2 for x in range(10)} +print("squares_dict list comprehension returns: ", squares_dict) + +''' EXERCISE: Write a dict comprehension to populate a dict with all the letters of +the alphabet as values with their keys being their index in the alphabet: ''' +from string import ascii_lowercase +# Your code here +alphabet_dict = { x: ascii_lowercase[x] for x in range(26) } +print("alphabet_dict list comprehension returns: ", alphabet_dict) + + + +# LAMBDA FUNCTIONS +'''Anonymous functions in Python are called lambdas. They are denoted by the `lambda` keyword. +Here's a simple example: ''' +f = lambda x, y : x + y +print("Lambda function `f` returns: ", f(1, 1)) + +''' Lambdas are most effective when passed to functions such as `map`, `filter`, and `reduce`. +Just like how these three functions accept callbacks that specify how you want each function +to behave, in Python, lambdas do the same thing as callbacks in this case. +Here's an example using the `filter` function which filters out the non-even fibonacci numbers: ''' +fib = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55] +result = list(filter(lambda x: x % 2 == 0, fib)) +print("Result of filtering out non-even fib numbers: ", result) + +''' EXERCISE: Use `reduce` to find the maximum value in the given `ints` list. +But first, we need to import `reduce` from the `functools` module: ''' +from functools import reduce +ints = [47, 11, 42, 102, 13] +result = reduce(lambda x, y: x if (x > y) else y, ints) +print("Result of reducing a list to find the max: ", result) diff --git a/cc69strings/solution.py b/cc69strings/solution.py new file mode 100644 index 0000000..969d1f3 --- /dev/null +++ b/cc69strings/solution.py @@ -0,0 +1,57 @@ +# https://repl.it/student/assignments/493753/model_solution?fromSubmissionId=1855286 +# https://piazza.com/class/j63w1pdyopf7kj?cid=81 +# https://youtu.be/VC52108omBI + +# 1. Donuts +# Given an int count of a number of donuts, return a string +# of the form 'Number of donuts: ', where is the number +# passed in. However, if the count is 10 or more, then use the word 'many' +# instead of the actual count. +# So donuts(5) returns 'Number of donuts: 5' +# and donuts(23) returns 'Number of donuts: many' +def donuts(count): + # Your code here + return 'Number of donuts: ' + str(count if count < 10 else 'many') + + +# 2. both_ends +# Given a string s, return a string made of the first 2 +# and the last 2 chars of the original string, +# so 'spring' yields 'spng'. However, if the string length +# is less than 2, return instead the empty string. +def both_ends(s): + # Your code here + if len(s) < 2: + return '' + return s[0:2] + s[-2:] + + +# 3. fix_start +# Given a string s, return a string +# where all occurences of its first char have +# been changed to '*', except do not change +# the first char itself. +# e.g. 'babble' yields 'ba**le' +# Assume that the string is length 1 or more. +# Hint: s.replace(stra, strb) returns a version of string s +# where all instances of stra have been replaced by strb. +def fix_start(s): + # Your code here + first = s[0] + rest_of_string = s[1:] + updated_string = rest_of_string.replace(first, '*') + return first + updated_string + + +# 4. mix_up +# Given strings a and b, return a single string with a and b separated +# by a space ' ', except swap the first 2 chars of each string. +# e.g. +# 'mix', pod' -> 'pox mid' +# 'dog', 'dinner' -> 'dig donner' +# Assume a and b are length 2 or more. +def mix_up(a, b): + # Your code here + a_swapped = b[:2] + a[2:] + b_swapped = a[:2] + b[2:] + return a_swapped + ' ' + b_swapped diff --git a/cc69strings/strings.py b/cc69strings/strings.py new file mode 100644 index 0000000..7638607 --- /dev/null +++ b/cc69strings/strings.py @@ -0,0 +1,83 @@ +# cc69 strings +# https://repl.it/student/submissions/1855286 +# https://developers.google.com/edu/python/ +# http://pythoncentral.io/cutting-and-slicing-strings-in-python/ + +''' +For this challenge, you'll be writing some basic string functions. +Simply follow along with each exercise's prompt. + +You may find the following article helpful with regards to +how to perform string slicing in Python: +http://pythoncentral.io/cutting-and-slicing-strings-in-python/ +''' + +# 1. Donuts +# Given an int count of a number of donuts, return a string +# of the form 'Number of donuts: ', where is the number +# passed in. However, if the count is 10 or more, then use the word 'many' +# instead of the actual count. +# So donuts(5) returns 'Number of donuts: 5' +# and donuts(23) returns 'Number of donuts: many' +def donuts(count): + # Your code here + if count < 10: + reply = str(count) + else: + reply = 'many' + # print("Number of donuts: ", count if count < 10 else 'many') + return "Number of donuts: " + reply + +print(donuts(5)) +print(donuts(23)) +print(donuts(4)) + + +# 2. both_ends +# Given a string s, return a string made of the first 2 +# and the last 2 chars of the original string, +# so 'spring' yields 'spng'. However, if the string length +# is less than 2, return instead the empty string. +def both_ends(s): + # Your code here + if len(s) < 2: + return '' + return s[0:2] + s[-2:] + +print(both_ends("Scooby Snacks")) +print(both_ends("Jesh doesn't share his candy")) + +# 3. fix_start +# Given a string s, return a string +# where all occurences of its first char have +# been changed to '*', except do not change +# the first char itself. +# e.g. 'babble' yields 'ba**le' +# Assume that the string is length 1 or more. +# Hint: s.replace(stra, strb) returns a version of string s +# where all instances of stra have been replaced by strb. +def fix_start(s): + letter = s[0] + s = s.replace(letter, '*') + starring = letter + s[1:] + + return starring + +print(fix_start("well, why weren't we welcome?")) +print(fix_start("Scooby Snacks Sound Simply Scrumptuous!")) + +# 4. mix_up +# Given strings a and b, return a single string with a and b separated +# by a space ' ', except swap the first 2 chars of each string. +# e.g. +# 'mix', pod' -> 'pox mid' +# 'dog', 'dinner' -> 'dig donner' +# Assume a and b are length 2 or more. +def mix_up(a, b): + new_a = b[:2] + a[2:] + new_b = a[:2] + b[2:] + + return new_a + ' ' + new_b + +print(mix_up("What", "the???")) +print(mix_up("Patrick", "Kennedy")) diff --git a/cc70lists/lists.py b/cc70lists/lists.py new file mode 100644 index 0000000..3b013f0 --- /dev/null +++ b/cc70lists/lists.py @@ -0,0 +1,59 @@ +# cc70 lists https://repl.it/student/submissions/1864112 +''' +For this challenge, you'll be writing some list functions to get you more +comfortable with Python lists. Simply follow along with each exercise's prompt. + +The following is a link on how sorting is done in Python: +https://docs.python.org/3/howto/sorting.html + +Additionally, here is a link to the Python docs on lists: +https://docs.python.org/3/tutorial/datastructures.html +''' + +# 1. match_ends +# Given a list of strings, return the count of the number of +# strings where the string length is 2 or more and the first +# and last chars of the string are the same. +# Note: python does not have a ++ operator, but += works. +def match_ends(words): + # Your code here + count = 0 + for x in words: + if (len(x) >= 2) and (x[0] == x[-1]): + count +=1 + return count + +print(match_ends(['abba', 'bobby', 'cc', 'd', 'falafelf'])) # ~~~> 3 + +# 2. front_x +# Given a list of strings, return a list with the strings +# in sorted order, except group all the strings that begin with 'x' first. +# e.g. ['mix', 'xyz', 'apple', 'xanadu', 'aardvark'] yields +# ['xanadu', 'xyz', 'aardvark', 'apple', 'mix'] +# Hint: this can be done by making 2 lists and sorting each of them +# before combining them. +def front_x(words): + # Your code here + words.sort() + x_list = [] + not_x_list = [] + for word in words: + if word[0] == 'x': + x_list.append(word) + else: + not_x_list.append(word) + return x_list + not_x_list + +print(front_x(['mix', 'xyz', 'apple', 'xanadu', 'aardvark'])) # ~~~> ['xanadu', 'xyz', 'aardvark', 'apple', 'mix'] + +# 3. sort_last +# Given a list of non-empty tuples, return a list sorted in increasing +# order by the last element in each tuple. +# e.g. [(1, 7), (1, 3), (3, 4, 5), (2, 2)] yields +# [(2, 2), (1, 3), (3, 4, 5), (1, 7)] +# Hint: use a custom key= function to extract the last element form each tuple. +def sort_last(tuples): + # Your code here + return sorted(tuples, key=lambda t: t[-1]) + +print(sort_last([(1, 7), (1, 3), (3, 4, 5), (2, 2)])) # ~~~> [(2, 2), (1, 3), (3, 4, 5), (1, 7)] diff --git a/cc70lists/solution.py b/cc70lists/solution.py new file mode 100644 index 0000000..ea69c09 --- /dev/null +++ b/cc70lists/solution.py @@ -0,0 +1,45 @@ +# https://repl.it/student/assignments/493801/model_solution?fromSubmissionId=1864112 +# + +# 1. match_ends +# Given a list of strings, return the count of the number of +# strings where the string length is 2 or more and the first +# and last chars of the string are the same. +# Note: python does not have a ++ operator, but += works. +def match_ends(words): + # Your code here + count = 0 + for word in words: + if len(word) >= 2 and word[0] == word[-1]: + count = count + 1 + return count + + +# 2. front_x +# Given a list of strings, return a list with the strings +# in sorted order, except group all the strings that begin with 'x' first. +# e.g. ['mix', 'xyz', 'apple', 'xanadu', 'aardvark'] yields +# ['xanadu', 'xyz', 'aardvark', 'apple', 'mix'] +# Hint: this can be done by making 2 lists and sorting each of them +# before combining them. +def front_x(words): + # Your code here + x_list = [] + other_list = [] + for w in words: + if w.startswith('x'): + x_list.append(w) + else: + other_list.append(w) + return sorted(x_list) + sorted(other_list) + + +# 3. sort_last +# Given a list of non-empty tuples, return a list sorted in increasing +# order by the last element in each tuple. +# e.g. [(1, 7), (1, 3), (3, 4, 5), (2, 2)] yields +# [(2, 2), (1, 3), (3, 4, 5), (1, 7)] +# Hint: use a custom key= function to extract the last element form each tuple. +def sort_last(tuples): + # Your code here + return sorted(tuples, key=lambda a: a[-1]) diff --git a/cc71meanMedianMode/meanMedianMode.py b/cc71meanMedianMode/meanMedianMode.py new file mode 100644 index 0000000..568ee2e --- /dev/null +++ b/cc71meanMedianMode/meanMedianMode.py @@ -0,0 +1,52 @@ +# cc71 meanMedianMode https://repl.it/student/submissions/1871422 +''' +Write a function that, given a list of numbers, calculates the +mean, median, and mode of those numbers. Return a dictionary with +properties for the mean, median and mode. + +For example: +mmm_dict = meanMedianMode([1,2,3,4,5,6,7,8,9,10,10]) +print(mmm_dict) should print: +{'mean': 5.909090909090909, 'median': 6, 'mode': 10} +''' + +def meanMedianMode (nums): + # MEAN average total all nums, divide total by number of numbers + total = 0 + for num in nums: + total += num + mean = total / len(nums) + + # MEDIAN: https://www.mathsisfun.com/definitions/median.html + # sort the numbers, if there are two middle numbers, return the average + median = None + sortedNums = sorted(nums, key=int) + middle = len(nums) / 2 + if (len(sortedNums) % 2 == 0): + median = (sortedNums[int(middle - 1)] + sortedNums[int(middle)]) / 2 + else: + median = sortedNums[int(middle)] + + # MODE https://en.wikipedia.org/wiki/Mode_(statistics) + mapping = {} + count = 0 + mode = max(set(nums), key=nums.count) + + # DICT + MMM = {} + MMM['mean'] = mean + MMM['median'] = median + MMM['mode'] = mode + return MMM + +# TEST SUITE +mmm_dict = meanMedianMode([1,2,3,4,5,6,7,8,9,10,10]) +print(mmm_dict) # ~~~> {'mean': 5.909090909090909, 'median': 6, 'mode': 10} +mmm_dict2 = meanMedianMode([1,2,3,4,5,6,7,8,9,10]) +print(mmm_dict2) +mmm_dict3 = meanMedianMode([1,1,2,3,4,5,6,7,8,9,10,10]) +print(mmm_dict3) +mmm_dict4 = meanMedianMode([951, 402, 984, 651, 360, 69, 408, 319, 601, 485, 980, 507, 725, 547, 544, 615, 83, 165, 141, 501, 263, 617, 865, 575, 219, 390, 984, 592, 236, 105, 942, 941, 386, 462, 47, 418, 907, 344, 236, 375, 823, 566, 597, 978, 328, 615, 953, 345, 399, 162, 758, 219, 918, 237, 412, 566, 826, 248, 866, 950, 626, 949, 687, 217, 815, 67, 104, 58, 512, 24, 892, 894, 767, 553, 81, 379, 843, 831, 445, 742, 717, 958, 609, 842, 451, 688, 753, 854, 685, 93, 857, 440, 380, 126, 721, 328, 753, 470, 743, 527]) +print(mmm_dict4) +mmm_dict5 = meanMedianMode([24, 47, 58, 67, 69, 81, 83, 93, 104, 105, 126, 141, 162, 165, 217, 219, 219, 236, 236, 237, 248, 263, 319, 328, 328, 344, 345, 360, 375, 379, 380, 386, 390, 399, 402, 408, 412, 418, 440, 445, 451, 462, 470, 485, 501, 507, 512, 527, 544, 547, 553, 566, 566, 575, 592, 597, 601, 609, 615, 615, 617, 626, 651, 685, 687, 688, 717, 721, 725, 742, 743, 753, 753, 758, 767, 815, 823, 826, 831, 842, 843, 854, 857, 865, 866, 892, 894, 907, 918, 941, 942, 949, 950, 951, 953, 958, 978, 980, 984, 984]) +print(mmm_dict5) diff --git a/cc71meanMedianMode/solution.py b/cc71meanMedianMode/solution.py new file mode 100644 index 0000000..d9aa07a --- /dev/null +++ b/cc71meanMedianMode/solution.py @@ -0,0 +1,43 @@ +# https://youtu.be/r0xWh4QqS9Q +# https://piazza.com/class/j63w1pdyopf7kj?cid=83 + +from functools import reduce +from collections import Counter + +def findMean(numbers): + sum = reduce(lambda x, y: x + y, numbers) + mean = sum / len(numbers) + return mean + +def findMedian(numbers): + numbers.sort() + mid = len(numbers) // 2 + if len(numbers) % 2 is 0: + return findMean([numbers[mid], numbers[mid-1]]) + return numbers[mid] + +# Non-Pythonic solution +# def findMode(numbers): +# mode = None +# mapping = {x: 0 for x in numbers} +# greatestFrequency = 0 +# for n in numbers: +# mapping[n] += 1 +# if mapping[n] > greatestFrequency: +# greatestFrequency = mapping[n] +# mode = n +# return mode + +# Pythonic solution +def findMode(numbers): + counter = Counter(numbers) + return counter.most_common(1)[0][0] + +def meanMedianMode(numbers): + mmm_dict = { + 'mean': findMean(numbers), + 'median': findMedian(numbers), + 'mode': findMode(numbers) + } + + return mmm_dict diff --git a/cc72permutationPalindrome/permutationPalindrome.py b/cc72permutationPalindrome/permutationPalindrome.py new file mode 100644 index 0000000..2b6682e --- /dev/null +++ b/cc72permutationPalindrome/permutationPalindrome.py @@ -0,0 +1,30 @@ +# cc72 permutationPalindrome https://repl.it/student/submissions/1878345 + +from collections import Counter +import timeit + +def is_permutation_palindrome(string): + unpaired_chars = set() + + for char in string: + if char in unpaired_chars: + unpaired_chars.remove(char) + else: + unpaired_chars.add(char) + return len(unpaired_chars) <= 1 + +def is_permutation_palindrome2(string): + return sum(v % 2 for v in Counter(string).values()) <= 1 + +def wrapper(func, *args, **kwargs): + def wrapped(): + return func(*args, **kwargs) + return wrapped + +string1 = 'asdfdsa' +wrapped1 = wrapper(is_permutation_palindrome, string1); +wrapped2 = wrapper(is_permutation_palindrome2, string1); + + +print(timeit.timeit(wrapped1)) +print(timeit.timeit(wrapped2)) diff --git a/cc72permutationPalindrome/solution.py b/cc72permutationPalindrome/solution.py new file mode 100644 index 0000000..6809759 --- /dev/null +++ b/cc72permutationPalindrome/solution.py @@ -0,0 +1,30 @@ +# + +from collections import Counter +import timeit + +def is_permutation_palindrome(string): + unpaired_chars = set() + + for char in string: + if char in unpaired_chars: + unpaired_chars.remove(char) + else: + unpaired_chars.add(char) + return len(unpaired_chars) <= 1 + +def is_permutation_palindrome2(string): + return sum(v % 2 for v in Counter(string).values()) <= 1 + +def wrapper(func, *args, **kwargs): + def wrapped(): + return func(*args, **kwargs) + return wrapped + +string1 = 'asdfdsa' +wrapped1 = wrapper(is_permutation_palindrome, string1); +wrapped2 = wrapper(is_permutation_palindrome2, string1); + + +print(timeit.timeit(wrapped1)) +print(timeit.timeit(wrapped2)) diff --git a/cc73linkedList/linkedList.py b/cc73linkedList/linkedList.py new file mode 100644 index 0000000..7ae428b --- /dev/null +++ b/cc73linkedList/linkedList.py @@ -0,0 +1,22 @@ +# cc73linkedList https://repl.it/student/submissions/1891345 +''' +Now it's time to implement a linked list in Python! +The main takeaway of this exercise is to delve into classes and OOP in Python. + +We'll start off by defining a Node class. +Each linked list node will be an instance of a Node. + +OO programming in Python is very similar to what you've seen in JavaScript. +The main surface-level differences are that, in Python, the class constructor +method is called __init__, and also that every class method accepts self as +its first input parameter, in order to delineate to the Python interpreter +that it is a class method instead of a regular function. +Lastly, there is no new keyword in Python that is needed to instantiate a new +class instance. We would just define a new node with something like +new_node = Node(data). + +Note that when we invoke a class method, you don't actually pass self into the +class method. For example, if we want to instantiate a new Node instance, we can +do that with new_node = Node(data), where data is the piece of data we want the +Node to hold. We don't need to actually pass in some context as the first parameter. +''' diff --git a/cc73linkedList/solution.py b/cc73linkedList/solution.py new file mode 100644 index 0000000..6824a6d --- /dev/null +++ b/cc73linkedList/solution.py @@ -0,0 +1,82 @@ +# https://youtu.be/6Ilb270zYpU +# https://repl.it/student/assignments/499618/model_solution?fromSubmissionId=1891345 + +"""Define a class with the `class` keyword""" +class Node: + """The `__init__` method on a class in Python is analogous + with JavaScript's `constructor` method; it specifies how a + class should be initialized give some parameters. You'll + also notice the `self` keyword, which is passed in to + every class method as the first argument. It's very much + analogous to JavaScript's `this` keyword.""" + def __init__(self, data=None, next_node=None): + self.data = data + self.next_node = next_node + + """Returns the data stored at the current node""" + def get_data(self): + return self.data + + """Returns the next node this node points to""" + def get_next(self): + return self.next_node + + """Sets this node's `next_node` pointer""" + def set_next(self, new_next): + self.next_node = new_next + + +"""Now that we've defined our `Node`, we can define our Linked List +class, which will utilize our `Node` class""" +class LinkedList: + def __init__(self, head=None): + self.head = head + + """Wraps the input item in a Node and adds it as the + current node's next node""" + def insert(self, item): + new_node = Node(item) + new_node.set_next(self.head) + self.head = new_node + + """Returns the number of nodes in the linked list""" + def size(self): + current = self.head + count = 0 + while current: + count += 1 + current = current.get_next() + return count + + """Returns the target item if it is in the linked list, + and None otherwise""" + def search(self, target): + current = self.head + found = False + while current and found is False: + if current.get_data() == target: + found = True + else: + current = current.get_next() + return current + + """Deletes the target item from the linked list if it is + in the list. Raises a ValueError exception otherwise if + the target item is not in the list""" + def delete(self, target): + current = self.head + previous = None + found = False + while current and found is False: + if current.get_data() == target: + found = True + else: + previous = current + current = current.get_next() + if current is None: + raise ValueError('Data not in list') + if previous is None: + self.head = current.get_next() + else: + previous.set_next(current.get_next()) + diff --git a/cc74doublyLinkedList/cc74doublyLinkedList.py b/cc74doublyLinkedList/cc74doublyLinkedList.py new file mode 100644 index 0000000..5a1b9f5 --- /dev/null +++ b/cc74doublyLinkedList/cc74doublyLinkedList.py @@ -0,0 +1,14 @@ +# cc74 doublyLinkedList https://repl.it/student/submissions/1895354 +''' +Implement a doubly-linked list, where each node points to both the node after it +in the list, as well as the node that came before it. + +This challenge is difficult, but please put your best foot forward, +as with every morning code challenge, to at the very least get pseudocode for +how you would implement this data structure. Taking the easy route and just +waiting for the solution without making any sort of attempt is not only a +disservice to you but also to us, the instructors. + +If questions arise while you're working on the challenge, please ask questions +in the appropriate channels to get you unstuck. +''' diff --git a/cc74doublyLinkedList/solution.py b/cc74doublyLinkedList/solution.py new file mode 100644 index 0000000..57d1022 --- /dev/null +++ b/cc74doublyLinkedList/solution.py @@ -0,0 +1,119 @@ +# https://youtu.be/acl83_x8Wew +# https://piazza.com/class/j63w1pdyopf7kj?cid=86 + +"""Each ListNode holds a reference to its previous node +as well as its next node in the List.""" +class ListNode: + def __init__(self, val, prev=None, next=None): + self.prev = prev + self.val = val + self.next = next + + """Wrap the given value in a ListNode and insert it + after this node. Note that this Node could already + have a next node it is pointing to.""" + def insert_after(self, val): + current_next = self.next + self.next = ListNode(val, self, current_next) + if current_next: + current_next.prev = self.next + + """Wrap the given value in a ListNode and insert it + before this node. Note that this Node could already + have a previous node it is pointing to.""" + def insert_before(self, val): + current_prev = self.prev + self.prev = ListNode(val, current_prev, self) + if current_prev: + current_prev.next = self.prev + + """Rearranges this ListNode's previous and next pointers + accordingly, effectively deleting this ListNode.""" + def delete(self): + if self.prev: + self.prev.next = self.next + if self.next: + self.next.prev = self.prev + +"""Our doubly-linked list class. It holds references to +the list's head and tail nodes.""" +class List: + def __init__(self, node=None): + self.head = node + self.tail = node.next if node else None + + """Wraps the given value in a ListNode and inserts it + as the new head of the list. Don't forget to handle + the old head node's previous pointer accordingly.""" + def add_to_head(self, val): + if not self.head: + self.head = ListNode(val, None, self.tail) + elif not self.tail: + self.tail = self.head + self.head = ListNode(val, None, self.tail) + self.tail.prev = self.head + else: + self.head = ListNode(val, None, self.head) + self.head.next.prev = self.head + + """Removes the List's current head node, making the + current head's next node the new head of the List. + Returns the removed Node.""" + def shift(self): + if not self.head: + if not self.tail: + return None + return self.remove_from_tail() + else: + current_head = self.head + self.head = self.head.next + self.head.prev = None + return current_head.val + + """Wraps the given value in a ListNode and inserts it + as the new tail of the list. Don't forget to handle + the old tail node's next pointer accordingly.""" + def add_to_tail(self, val): + if not self.tail: + self.tail = ListNode(val, self.head, None) + elif not self.head: + self.head = self.tail + self.tail = ListNode(val, self.head, None) + self.head.next = self.tail + else: + self.tail = ListNode(val, self.tail, None) + self.tail.prev.next = self.tail + + """Removes the List's current tail node, making the + current tail's previous node the new tail of the List. + Returns the removed Node.""" + def remove_from_tail(self): + if not self.tail: + if not self.head: + return None + return self.shift() + else: + current_tail = self.tail + self.tail = self.tail.prev + self.tail.next = None + return current_tail.val + + """Removes the input node from its current spot in the + List and inserts it as the new head node of the List.""" + def move_to_front(self, node): + value = node.val + if node is self.tail: + self.remove_from_tail() + else: + node.delete() + self.add_to_head(value) + + """Removes the input node from its current spot in the + List and inserts it as the new tail node of the List.""" + def move_to_end(self, node): + value = node.val + if node is self.head: + self.shift() + else: + node.delete() + self.add_to_tail(value) diff --git a/cc75findRotationPoint/findRotationPoint.py b/cc75findRotationPoint/findRotationPoint.py new file mode 100644 index 0000000..99dd5f9 --- /dev/null +++ b/cc75findRotationPoint/findRotationPoint.py @@ -0,0 +1,26 @@ +# cc75 findRotationPoint +''' +Let's say we're given an alphabetically-sorted list of words that has been +rotated at a single point. It might look something like this: + + words = [ + 'ptolemaic', + 'retrograde', + 'supplant', + 'undulate', + 'xenoepist', + 'asymptote', # <-- rotates here! + 'babka', + 'banoffee', + 'engender', + 'karpatka', + 'othellolagkage', +] + +Write a function that, given a list of words such as this, returns the index of +the rotation point. You can assume that no words will be duplicated. + +print(find_rotation_point(words)) # returns 5 + +Can you do this with O(lg n) runtime complexity? +''' diff --git a/cc75findRotationPoint/solution.py b/cc75findRotationPoint/solution.py new file mode 100644 index 0000000..fe56623 --- /dev/null +++ b/cc75findRotationPoint/solution.py @@ -0,0 +1,22 @@ +# https://repl.it/student/assignments/515914/model_solution?fromSubmissionId=1903866 +# https://piazza.com/class/j63w1pdyopf7kj?cid=89 +# https://youtu.be/HCa69879ZGo + +def find_rotation_point(words): + first_word = words[0] + floor_index = 0 + ceiling_index = len(words) - 1 + + while floor_index < ceiling_index: + # guess a point halfway between floor and ceiling + guess_index = floor_index + ((ceiling_index - floor_index) // 2) + # if the guess comes after the first word or is the first word + if words[guess_index] >= first_word: + # go right + floor_index = guess_index + else: + # go left + ceiling_index = guess_index + # check if our floor and ceiling indices have converged + if floor_index + 1 == ceiling_index: + return ceiling_index diff --git a/cc76makeChange/makeChange.py b/cc76makeChange/makeChange.py new file mode 100644 index 0000000..4e62ce2 --- /dev/null +++ b/cc76makeChange/makeChange.py @@ -0,0 +1,60 @@ +# cc75 makeChange https://repl.it/student/submissions/1910097 +''' +Write a function that, given an amount of money and a list of coin denominations, +returns an integer representing the number of ways that change can be made from +those denominations for the given amount. + +For example, given amount = 4 (let's assume 4 cents) and denominations = [1, 2, 3], +your program would return 4, i.e. the number of ways to make 4 cents from the given denominations: + + 1) 1, 1, 1, 1 + 2) 1, 1, 2 + 3) 1, 3 + 4) 2, 2 + +This problem lends itself well to being solved recursively by breaking it down +into smaller subproblems. You can imagine that for each denomination, we can use +it once, twice, three time; as many as it takes to reach or exceed the given +amount with coins of that denomination alone. + +For each of those choices of how many times to include coins of each denomination, +we have the subproblem of seeing how many ways we can get the remaining amount +from the remaining denominations. + +Here's that logic in pseudocode to help get you started: + +function make_change(amount, denominations): + answer = 0 + for each denomination in denominations: + for each number_of_times_to_use_denomination in possible_number_of_times_to_use_denomination_without_overshooting: + answer += make_change(amount_remaining, other_denominations) + return answer + +If you figure out a working solution, think about whether you're duplicating a +lot of work that isn't necessary. How could that be cut down? +''' + +def make_change(amount, denominations): + # # Recursive solution - redundancies + # # BASE CASE + # if (amount < 0): + # return 0 + # elif (amount == 0): + # return 1 + # else: + # return sum([make_change(amount - denom, denominations) for denom in denominations]) + + # # Iterative solution + combinations = [1] + [0] * amount + print('start: ', combinations) + for denom in denominations: + print('active denomination: ', denom) + for i in range(denom, amount + 1): + print(combinations[i], '+=', combinations[i - denom]) + combinations[i] += combinations[i - denom] + print('iterate: ', combinations) + return combinations[amount] + +# TEST SUITE +print(make_change(4, [1,2,3])) +print(make_change(5, [1,2,3])) diff --git a/cc76makeChange/solution.py b/cc76makeChange/solution.py new file mode 100644 index 0000000..3eba52a --- /dev/null +++ b/cc76makeChange/solution.py @@ -0,0 +1,64 @@ +# https://repl.it/student/assignments/515954/model_solution?fromSubmissionId=1910097 +# https://piazza.com/class/j63w1pdyopf7kj?cid=91 +# https://youtu.be/ZmN9F07PjB0 + +# Recursive solution that duplicates work +# def make_change(amount, denominations, index=0): +# # base cases +# if amount == 0: +# return 1 +# if amount < 0: +# return 0 +# # otherwise, +# if index == len(denominations): +# return 0 +# # choose a coin +# coin = denominations[index] +# # see how many possibilities we can get for each number of times to use coin +# num_possibilities = 0 +# while amount >= 0: +# num_possibilities += make_change(amount, denominations, index + 1) +# amount -= coin +# return num_possibilities + + +# Solution that memoizes old solutions +# class Change: +# def __init__(self): +# self.memo = dict() + +# def make_change(self, amount, denominations, index=0): +# # check our memo and short-circuit if we've already solved this one +# memo_key = str((amount, index)) +# if memo_key in self.memo: +# return self.memo[memo_key] +# # base cases: we hit the amount spot on, or we overshot the amount left (user too many coins) +# if amount == 0: +# return 1 +# if amount < 0: +# return 0 +# # we're out of denominations +# if index == len(denominations): +# return 0 +# # choose a current coin +# coin = denominations[index] +# num_possibilities = 0 +# while amount >= 0: +# num_possibilities += self.make_change(amount, denominations, index + 1) +# amount -= coin +# # save this solution in our memo storage +# self.memo[memo_key] = num_possibilities +# return num_possibilities + + +# Bottom-up approach that doesn't waste old solutions we've solved before +def make_change(amount, denominations): + ways_of_making_n_cents = [0 for i in range(amount + 1)] + ways_of_making_n_cents[0] = 1 + + for coin in denominations: + for higher_amount in range(coin, amount + 1): + higher_amount_remainder = higher_amount - coin + ways_of_making_n_cents[higher_amount] += ways_of_making_n_cents[higher_amount_remainder] + + return ways_of_making_n_cents[amount] diff --git a/cc77lruCache/lruCache.py b/cc77lruCache/lruCache.py new file mode 100644 index 0000000..c69a7bb --- /dev/null +++ b/cc77lruCache/lruCache.py @@ -0,0 +1,192 @@ +# cc77 lruCache https://repl.it/student/submissions/1917830 +''' +Implement the set and get methods we'll need for our LRU cache implementation +by leveraging the doubly-linked list class you worked on a few days ago (provided). + +Recall that an LRU cache is a data structure built atop a doubly-linked list +that stores key-value pairs in list nodes. It maintains the condition that the +head node of the list is the oldest key-value pair, and the tail node is the +newest. It also needs to be able to set and get new nodes in constant time. + +Whenever a node is accessed, either via reading an already-existing node, or +writing a new node to the cache, that node is moved to the tail of the list as +the 'most-recently accessed' node. + +So our LRU cache keeps track of most-recently accessed key-value pairs, up to a +storage limit. Once that limit has been reached, if a new pair is to be added to +the list, the oldest (the head) node in the list needs to be evicted to make +room for the newest pair. + +A few gotchas you may run into when implementing this class in Python: + +1. If you want to check if a key is in a dictionary, you cannot attempt to +access the key-value pair by the key and then check if the pair is truthy. +For example, you can't do this for some key that is not in the dictionary: + +node = self.storage[key] +if node: + ... + +This will return a KeyError. Instead, check if a key is in a dictionary like so: + +if key in self.storage: + node = self.storage[key] + ... + +2. Use a Python tuple to represent a key-value pair. Note however that tuples +are immutable; you cannot mutate an already-existing tuple. If you want to +update a tuple, you'll need to create a new copy. +''' + +"""Our LRUCache class keeps references to the max limit of nodes it +can hold, the current number of nodes it is holding, a doubly-linked +list that holds the nodes in the correct order, as well as a storage +dictionary for easy access to every node stored in our LRU cache.""" +class LRUCache: + def __init__(self, limit=10): + self.limit = limit + self.size = 0 + self.list = List() + self.storage = {} + + """Retrieves the value of the node given a key. Moves the + retrieved node to the end of the List. Should be an + O(1) operation.""" + def get(self, key): + if key in self.storage: + node = self.storage[key] + if node: + self.list.move_to_end(node) + return node.val.val + else: + return None + + + """Sets the given key-value pair as the new tail of the List, + as well as adding it to the storage dict. If the List is already + at its limit, the head of the List will need to be evicted before + the new key-value pair is added. Lastly, if the key already exists + in the List, its value should be updated, and then the updated pair + should be moved to the end of the List. Should be an O(1) + operation.""" + def set(self, key, val): + node = self.storage[key] + if node: + node.val.val = val + self.list.move_to_end(node) + return + + if self.size === self.limit: + # already reached our limit + delete(self.storage[self.list.head.val.key]) + self.list.shift() + self.size -= 1 + + self.list.push((key, val)) + self.storage[key] = self.list.tail + self.size += 1 + + + +"""***********Doubly-Linked List Implementation***********""" +"""ListNode class that comprises a single node in the List""" +class ListNode: + def __init__(self, val, prev=None, next=None): + self.prev = prev + self.val = val + self.next = next + + """Inserts a new node as this node's next node""" + def insert_after(self, val): + current_next = self.next + self.next = ListNode(val, self, current_next) + if current_next: + current_next.prev = self.next + + """Inserts a new node as this node's previous node""" + def insert_before(self, val): + current_prev = self.prev + self.prev = ListNode(val, current_prev, self) + if current_prev: + current_prev.next = self.prev + + """Deletes this node from the List""" + def delete(self): + if self.prev: + self.prev.next = self.next + if self.next: + self.next.prev = self.prev + + + +"""Doubly-linked List class""" +class List: + def __init__(self, node=None): + self.head = node + self.tail = node.next if node else None + + """Adds the given value as the new head of the List""" + def add_to_head(self, val): + if not self.head: + self.head = ListNode(val, None, self.tail) + elif not self.tail: + self.tail = self.head + self.head = ListNode(val, None, self.tail) + self.tail.prev = self.head + else: + self.head = ListNode(val, None, self.head) + self.head.next.prev = self.head + + """Removes the head of the List and returns its value""" + def shift(self): + if not self.head: + if not self.tail: + return None + return self.remove_from_tail() + else: + current_head = self.head + self.head = self.head.next + self.head.prev = None + return current_head.val + + """Adds the given value as the new tail of the List""" + def add_to_tail(self, val): + if not self.tail: + self.tail = ListNode(val, self.head, None) + elif not self.head: + self.head = self.tail + self.tail = ListNode(val, self.head, None) + self.head.next = self.tail + else: + self.tail = ListNode(val, self.tail, None) + self.tail.prev.next = self.tail + + """Removes the tail of the List and returns its value""" + def remove_from_tail(self): + if not self.tail: + if not self.head: + return None + return self.shift() + else: + current_tail = self.tail + self.tail = self.tail.prev + self.tail.next = None + return current_tail.val + + """Moves the given node to the head of the List""" + def move_to_front(self, node): + value = node.val + if node is self.tail: + self.remove_from_tail() + else: + node.delete() + self.add_to_head(value) + + """Moves the given node to the tail of the List""" + def move_to_end(self, node): + value = node.val + if node is self.head: + self.shift() + else: + node.delete() + self.add_to_tail(value) diff --git a/cc77lruCache/solution.py b/cc77lruCache/solution.py new file mode 100644 index 0000000..6b44841 --- /dev/null +++ b/cc77lruCache/solution.py @@ -0,0 +1,184 @@ +# https://piazza.com/class/j63w1pdyopf7kj?cid=93 +# https://youtu.be/tg4JEUsYKSM + +# Original solution that leverages our homebrew doubly-linked list: +"""Our LRUCache class keeps references to the max limit of nodes it +can hold, the current number of nodes it is holding, a doubly-linked +list that holds the nodes in the correct order, as well as a storage +dictionary for easy access to every node stored in our LRU cache.""" +class LRUCache: + def __init__(self, limit=10): + self.limit = limit + self.size = 0 + self.list = List() + self.storage = {} + + """Retrieves the value of the node given a key. Moves the + retrieved node to the end of the List. Should be an + O(1) operation.""" + def get(self, key): + # check that the key exists in our cache + if key in self.storage: + # if so, access the node, return its value, and move the node to the tail of the List + node = self.storage[key] + self.list.move_to_end(node) + return node.val[1] + else: + return None + + """Sets the given key-value pair as the new tail of the List, + as well as adding it to the storage dict. If the List is already + at its limit, the head of the List will need to be evicted before + the new key-value pair is added. Lastly, if the key already exists + in the List, its value should be updated, and then the updated pair + should be moved to the end of the List. Should be an O(1) + operation.""" + def set(self, key, val): + # first, handle the case where we need to overwrite an already-existing node + if key in self.storage: + node = self.storage[key] + node.val = (key, val) + self.list.move_to_end(node) + return + # handle the case where our list is already full + if self.size == self.limit: + del self.storage[self.list.head.val[0]] + self.list.shift() + self.size -= 1 + # now we can add the newest key-value pair + self.list.add_to_tail((key, val)) + self.storage[key] = self.list.tail + self.size += 1 + + +"""***********Doubly-Linked List Implementation***********""" +"""ListNode class that comprises a single node in the List""" +class ListNode: + def __init__(self, val, prev=None, next=None): + self.prev = prev + self.val = val + self.next = next + + """Inserts a new node as this node's next node""" + def insert_after(self, val): + current_next = self.next + self.next = ListNode(val, self, current_next) + if current_next: + current_next.prev = self.next + + """Inserts a new node as this node's previous node""" + def insert_before(self, val): + current_prev = self.prev + self.prev = ListNode(val, current_prev, self) + if current_prev: + current_prev.next = self.prev + + """Deletes this node from the List""" + def delete(self): + if self.prev: + self.prev.next = self.next + if self.next: + self.next.prev = self.prev + +"""Doubly-linked List class""" +class List: + def __init__(self, node=None): + self.head = node + self.tail = node.next if node else None + + """Adds the given value as the new head of the List""" + def add_to_head(self, val): + if not self.head: + self.head = ListNode(val, None, self.tail) + elif not self.tail: + self.tail = self.head + self.head = ListNode(val, None, self.tail) + self.tail.prev = self.head + else: + self.head = ListNode(val, None, self.head) + self.head.next.prev = self.head + + """Removes the head of the List and returns its value""" + def shift(self): + if not self.head: + if not self.tail: + return None + return self.remove_from_tail() + else: + current_head = self.head + self.head = self.head.next + self.head.prev = None + return current_head.val + + """Adds the given value as the new tail of the List""" + def add_to_tail(self, val): + if not self.tail: + self.tail = ListNode(val, self.head, None) + elif not self.head: + self.head = self.tail + self.tail = ListNode(val, self.head, None) + self.head.next = self.tail + else: + self.tail = ListNode(val, self.tail, None) + self.tail.prev.next = self.tail + + """Removes the tail of the List and returns its value""" + def remove_from_tail(self): + if not self.tail: + if not self.head: + return None + return self.shift() + else: + current_tail = self.tail + self.tail = self.tail.prev + self.tail.next = None + return current_tail.val + + """Moves the given node to the head of the List""" + def move_to_front(self, node): + value = node.val + if node is self.tail: + self.remove_from_tail() + else: + node.delete() + self.add_to_head(value) + + """Moves the given node to the tail of the List""" + def move_to_end(self, node): + value = node.val + if node is self.head: + self.shift() + else: + node.delete() + self.add_to_tail(value) + +# Here is a Pythonic solution that leverages Python's built-in Ordered Dictionary data structure. It's certainly a much cleaner solution, but abstracts away more of the underlying details as well: +import collections + +class LRUCache: + def __init__(self, limit=10): + self.limit = limit + self.cache = collections.OrderedDict() + + def get(self, key): + # attempt to fetch our key-value pair from the cache + try: + value = self.cache.pop(key) + # re-add our key-value pair to the cache so that we maintain ordering + self.cache[key] = value + return value + except KeyError: + return None + + def set(self, key, value): + # check to see if the key is already in our cache + try: + self.cache.pop(key) + except KeyError: + # check to see if cache is holding the max number of key-value pairs + if len(self.cache) >= self.limit: + # if it is, remove the least-recently accessed key-value pair + self.cache.popitem(last=False) + # add the key-value pair to the cache + self.cache[key] = value + diff --git a/cc78goIntroI/goIntroI.go b/cc78goIntroI/goIntroI.go new file mode 100644 index 0000000..9accd18 --- /dev/null +++ b/cc78goIntroI/goIntroI.go @@ -0,0 +1,114 @@ +// cc78 goIntroI Variables, Types & Loops https://repl.it/student/submissions/1929699 +/* +For the next two weeks, we'll be doing morning code challenges using Go +(sometimes referred to as Golang). Go is a statically typed, compiled language +in the tradition of C. It has built-in garbage collection, limited structural +typing, memory safety features, as well as a strong focus on concurrency. + +For these morning exercises, we're going to slow things down a bit and really +try to solidify lower-level concepts such as static typing, pointers, memory +management, and concurrency. These concepts are not tied to Go, but Go provides +us a gentler environment in which to practice these concepts compared to C. + +In today's intro, we'll going over the basics of Go's variable declarations, +type declarations, and loops. At the end, we'll be combining these concepts to +implement a square root function. +*/ + +/* The "main" package is declared as it is needed to tell the Go + compiler that the package should compile as an executable */ +package main +/* The "fmt" package implements formatted I/O with functions + analogous with C's `printf` and `scanf` functions + "math" gives you access to math operations */ +import ( + "fmt" + "math" +) + +// Unlike with C, type declarations are specified after the +// variable names instead of before +var i, j int = 1, 2 + +// A `main` function is required that encapsulates the primary +// functionality of the program +func main() { + /* + Go also supports short variable declarations inside of function + bodies, along with type inference so that you don't always need + to specify the type of variables + */ + cake, canneles, cream := true, false, "no!" + // We can print out our variables like so + fmt.Println(cake, canneles, cream) + + // Type Conversions + // In Go, variable types can be converted to other valid types depending upon their value + i := 42 + f := float64(i) + fmt.Println(i, f) + + // TODO: Convert the variable `z` to an unsigned integer type + x, y := 3, 4 + var a float64 = math.Sqrt(float64(x*x + y*y)) + z := uint64(a) // <~~~~~ correct??????????????????????????????? + fmt.Println(x, y, z) + + // Loops + /* + Go doesn't have a `while` loop; instead, all looping is done via for loops + The only main difference with Go's for loops is that the loop conditions are + not surrounded by parentheses in Go + */ + sum := 0 + for i:= 0; i < 10; i++ { + sum += i + } + fmt.Println(sum) + + /* + Note the initialization and post statements + (the first and last statements in a for loop condition) are optional + This way, Go's for loop can be used just like a while loop + */ + sum = 1 + for sum < 1000 { + sum += sum + } + fmt.Println(sum) + + /* + If statements are exactly what you'd expect, except, again, there are no parentheses + surrounding the condition statement + */ + if sum > 1000 { + fmt.Println("Sum is larger than 1000") + } + + /* + TODO: Implement the Sqrt function below + Let's utilize loops to write a square root function. Computers typically calculate the square + root of some x by starting with some guess z and adjusting the guess based on how close z^2 is to x. + The formula we'll be used to adjust our guess is given by `z -= (z*z - x) / (2*z)`. + Start with some initial guess (1.0 is typically a reasonable starting guess) and adjust z 10 times + using the formula. How close is it to the result the `math.Sqrt` function returns? Try increasing + the number of iterations. + + Given enough iterations, the result of your Sqrt function will converge more precisely to the + correct answer. But can we be more precise about the number of iterations we update z by? We can + do that by breaking out of our loop once the amount we're updating z by is extremely small. + */ + fmt.Println(Sqrt(2)) + fmt.Println(math.Sqrt(2)) +} + +// CONVERGE ON THE SQUARE ROOT +func Sqrt(x float64) float64 { + // start with initial guess z + // update guess using Newton's method formula + z := 1.0 + for i := 0; 1 < 10; i++ { + z -= (z*z - x) / 2*z) + } + return z; +} diff --git a/cc78goIntroI/solution.go b/cc78goIntroI/solution.go new file mode 100644 index 0000000..68a7d9c --- /dev/null +++ b/cc78goIntroI/solution.go @@ -0,0 +1,98 @@ +// https://youtu.be/1J1ckOZ1WRM +// https://piazza.com/class/j63w1pdyopf7kj?cid=95 + +/* The "main" package is declared as it is needed to tell the Go + compiler that the package should compile as an executable */ +package main +/* The "fmt" package implements formatted I/O with functions + analogous with C's `printf` and `scanf` functions + "math" gives you access to math operations */ +import ( + "fmt" + "math" +) + +// Unlike with C, type declarations are specified after the +// variable names instead of before +var i, j int = 1, 2 + +// A `main` function is required that encapsulates the primary +// functionality of the program +func main() { + /* + Go also supports short variable declarations inside of function + bodies, along with type inference so that you don't always need + to specify the type of variables + */ + cake, canneles, cream := true, false, "no!" + // We can print out our variables like so + fmt.Println(cake, canneles, cream) + + // Type Conversions + // In Go, variable types can be converted to other valid types depending upon their value + i := 42 + f := float64(i) + fmt.Println(i, f) + + // TODO: Convert the variable `z` to an unsigned integer type + x, y := 3, 4 + var a float64 = math.Sqrt(float64(x*x + y*y)) + z := uint(a) + fmt.Println(x, y, z) + + // Loops + /* + Go doesn't have a `while` loop; instead, all looping is done via for loops + The only main difference with Go's for loops is that the loop conditions are + not surrounded by parentheses in Go + */ + sum := 0 + for i:= 0; i < 10; i++ { + sum += i + } + fmt.Println(sum) + + /* + Note the initialization and post statements + (the first and last statements in a for loop condition) are optional + This way, Go's for loop can be used just like a while loop + */ + sum = 1 + for sum < 1000 { + sum += sum + } + fmt.Println(sum) + + /* + If statements are exactly what you'd expect, except, again, there are no parentheses + surrounding the condition statement + */ + if sum > 1000 { + fmt.Println("Sum is larger than 1000") + } + + /* + TODO: Implement the Sqrt function below + Let's utilize loops to write a square root function. Computers typically calculate the square + root of some x by starting with some guess z and adjusting the guess based on how close z^2 is to x. + The formula we'll be used to adjust our guess is given by `z -= (z*z - x) / (2*z)`. + Start with some initial guess (1.0 is typically a reasonable starting guess) and adjust z 10 times + using the formula. How close is it to the result the `math.Sqrt` function returns? Try increasing + the number of iterations. + + Given enough iterations, the result of your Sqrt function will converge more precisely to the + correct answer. But can we be more precise about the number of iterations we update z by? + We can do that by breaking out of our loop once the amount we're updating z by is extremely + small. + */ + fmt.Println(Sqrt(2)) + fmt.Println(math.Sqrt(2)) +} + +func Sqrt(x float64) float64 { + z := 1.0 + for i := 0; i < 10; i++ { + z -= (z*z - x) / (2*z) + } + return z +} diff --git a/cc79goIntroII/goIntroII.go b/cc79goIntroII/goIntroII.go new file mode 100644 index 0000000..fd4dfae --- /dev/null +++ b/cc79goIntroII/goIntroII.go @@ -0,0 +1,94 @@ +// cc79 goIntroII: Arrays, Slices & Makes https://repl.it/student/submissions/1936670 +/* +For this coding challenge, you'll need to install Go locally on your machine! Yay!!! + +Go here to download the appropriate binary: https://golang.org/dl/ + +Follow the instructions to properly setup your PATH environment variable. +Make sure to test your installation as prompted by the instructions. + +Once that's done, start working through the challenge. +*/ + +package main + +import "fmt" + +// Just like in C, Go has two ways of allocating arrays: statically, or dynamically +// Here we statically declare an empty array named `a` that can store up to 10 integers +var a [10]int + +func main() { + // Using shorthand style to declare and initialize an array with some values + primes := [6]int {2, 3, 5, 7, 11, 13} + + /* + Like in C, arrays in Go are static, they cannot be dynamically + resized. Static arrays are in fact not commonly used when + writing Go. Instead, dynamic references to arrays, called + slices, are the standard method of working with data in arrays. + A slice is formed like so: + */ + slice_of_primes := primes[1:4] + fmt.Println(slice_of_primes) + + /* + A slice itself does not store any data. It is simply a + reference to a section of a larger array. Slices have + a length property and a capacity property, which indicates + the number of elements in the underlying array, counting + from the first element in the slice. Both properties + can be accessed by using the `len` and `cap` functions + respectively. + */ + fmt.Println(len(slice_of_primes)) + fmt.Println(cap(slice_of_primes)) + + /* + The `make` function in Go is very much akin to C's malloc. + It can create dynamically-sized structures for cases when + we don't know the size of something ahead of time. + `make` takes up to three arguments, the first being the + shape of the data structure you want to create, the second + being the length, and the third being the capacity. It + returns a reference to the created structure. + */ + a := make([]int, 5, 10) + fmt.Println(a) + + // In order to loop through arrays, use the range function + // Here, i is the current index, and v is the current value + for i, v := range primes { + fmt.Println(i, v) + } + + /* + TODO: Use arrays, slices, and make to write a function + that renders a bluescale image. + We'll be using your local Go installation for this exercise, so if you haven't done that yet, + go do it now. + Once you have Go installed and tested locally, move the following commented-out code to a new + file called `pic.go` in your working Go directory. + */ +} + +/********************** Copy this code below into a file called `pic.go` **************************/ +// package main + +// import "golang.org/x/tour/pic" + +// func Pic(x, y int) [][]uint8 { + /* + Let's write a function that, given two integers, creates a two-dimensional array + of uint8 values that represent an image. To do that, we need to allocate a two-dimensional + array using `make`, with the length of the "outer" array given by the input y. Then, once + we've allocated that 2D array, we need to allocate another array, each one of length x, + for each slot in our outer array. Inside each of those inner arrays, store a uint8 given by + some function of x and y. Some functions that produce interesting images include `(x + y) / 2`, + `x * y`, and `x ^ y`, just to name a few examples. Your function should return the outermost array. + */ +// } + +// func main() { +// pic.Show(Pic) +// } diff --git a/cc79goIntroII/pic b/cc79goIntroII/pic new file mode 100755 index 0000000..c313fe0 Binary files /dev/null and b/cc79goIntroII/pic differ diff --git a/cc79goIntroII/pic.go b/cc79goIntroII/pic.go new file mode 100644 index 0000000..61465e7 --- /dev/null +++ b/cc79goIntroII/pic.go @@ -0,0 +1,31 @@ +package main + +import "golang.org/x/tour/pic" + +func Pic(x, y int) [][]uint8 { + /* + * Let's write a function that, given two integers, creates a two-dimensional array + * of uint8 values that represent an image. To do that, we need to allocate a two-dimensional + * array using `make`, with the length of the "outer" array given by the input y. Then, once + * we've allocated that 2D array, we need to allocate another array, each one of length x, + * for each slot in our outer array. Inside each of those inner arrays, store a uint8 given by + * some function of x and y. Some functions that produce interesting images include `(x + y) / 2`, + * `x * y`, and `x ^ y`, just to name a few examples. Your function should return the outermost array. + * $ go get "golang.org/x/tour/pic" + * $ go build + */ + array2D := make([][]uint8, y) + // for i := 0; i < y; i++ { + for i := range array2D { + array2D[i] = make([]uint8, x) + // for j := 0; j < x; j++ { + for j := range array2D[i] { + array2D[i][j] = uint8(x * y / (j + 1) + i) + } + } + return array2D; + } + +func main() { + pic.Show(Pic) +} diff --git a/cc79goIntroII/solution.go b/cc79goIntroII/solution.go new file mode 100644 index 0000000..72d020a --- /dev/null +++ b/cc79goIntroII/solution.go @@ -0,0 +1,26 @@ +/* https://piazza.com/class/j63w1pdyopf7kj?cid=99 + * https://youtu.be/_sym-joan7U + */ + +package main + +import "golang.org/x/tour/pic" + +func Pic(x, y int) [][]uint8 { + outer := make([][]uint8, y) + for i := range outer { + outer[i] = make([]uint8, x) + } + + for y, row := range outer { + for inner := range row { + row[inner] = uint8(x ^ y) + } + } + + return outer +} + +func main() { + pic.Show(Pic) +} diff --git a/cc80goIntroIII/goIntroIII.go b/cc80goIntroIII/goIntroIII.go new file mode 100644 index 0000000..609312b --- /dev/null +++ b/cc80goIntroIII/goIntroIII.go @@ -0,0 +1,116 @@ +// cc80 goIntroIII: Functions and Pointers https://repl.it/student/submissions/1943334 +/* +In today's challenge, we'll be learning about functions and pointers in Go. +*/ + +package main + +import ( + "fmt" + "math" +) + +func pointer_example() { +/* + Go pointers look and act analogously with C's. A pointer holds + the memory address of some value. More formally, the type `*T` + is a pointer to a type `T` value. +*/ + i, j := 42, 2701 + + // Declare p to be the memory address of i + // p is now a pointer to i's value of 42 + p := &i + fmt.Println(*p) // read i through the pointer + + // Set the pointer p's underlying value to be 21 + // This is the same as setting i to 21 + *p = 21 + fmt.Println(i) // print the new value of i + + // Set p to be j's memory address now + // p is now a pointer to j's value of 2701 + p = &j + *p = *p / 37 // divide j through the pointer + fmt.Println(j) // see the new value of j +} + +// Declare a new Vertex type to be a struct with two properties X and Y, each a float64 +type Vertex struct { + X, Y float64 +} + +/* + The Abs function receives a Vertex instance as input and returns + the square root of the sum of the squares of X and Y +*/ +func Abs(v Vertex) float64 { + return math.Sqrt(v.X * v.X + v.Y * v.Y) +} + +/* + The Scale function receives a pointer to a Vertex instance + This is because this function modifies the values of the input struct + So the rule of thumb is, is your function seeks to modify the values of something, + it needs to receive a pointer to that thing. If it doesn't seek to modify something's + values, then it doesn't need to receive a pointer to it. So in C and Go, the developer + gets to decide whether they want a function to be pass by value, or pass by reference. +*/ +func Scale(v *Vertex, factor float64) { + v.X = v.X * factor + v.Y = v.Y * factor +} + +/* + Methods in Go + Go does not have classes. Instead, methods can be defined on types. + To showcase this, let's change our Abs and Scale functions to be + methods on the Vertex type. + The only difference between a method and a function is that a method has a + special receiver argument that designates the owner of the method. The Abs + function as a method would declared as the following: +*/ + +// The receiver argument (the 'owner' of this method) comes before the actual function name +func (v Vertex) Abs() float64 { + return math.Sqrt(v.X * v.X + v.Y * v.Y) +} + +// TODO: Convert the Scale function to be a method on the Vertex class. The receiver argument in +// this case should still be a pointer since values are still being modified +// Implement your function here +func (v *Vertex) Scale(factor float64) { + v.X = v.X * factor + v.Y = v.Y * factor +} + +// TODO: Implement a method on the Vertex class called Midpoint that receives another vertex and finds the +// midpoint between the two vertices. Should return the midpoint as a Vertex. +// Implement your function here +func (v1 Vertex) Midpoint(v2 Vertex) Vertex { + Xm := (v1.X + v2.X) / 2; + Ym := (v1.Y - v2.Y) / 2; + return Vertex{Xm, Ym}; +} + + +// TODO: Implement a method on the Vertex class called Distance that receives another vertex and finds the +// distance between the two vertices. Should return a float64 representing the distance. +// Implement your function here +func (v1 Vertex) Distance(v2 Vertex) float64 { + Xd := math.Pow(v1.X - v2.X, 2); + Yd := math.Pow(v1.Y - v2.Y, 2); + return math.Sqrt(Xd + Yd); +} + + +func main() { + pointer_example() + x := Vertex{3, 4} + x.Scale(10) + fmt.Println(x.Abs()) + + y := Vertex{9, 11} + fmt.Println(x.Midpoint(y)) + fmt.Println(x.Distance(y)) +} diff --git a/cc80goIntroIII/solution.go b/cc80goIntroIII/solution.go new file mode 100644 index 0000000..9904aad --- /dev/null +++ b/cc80goIntroIII/solution.go @@ -0,0 +1,111 @@ +// https://repl.it/student/assignments/535531/model_solution?fromSubmissionId=1943334 +// https://piazza.com/class/j63w1pdyopf7kj?cid=102 +// https://youtu.be/mIhpRnLLhG0 + +package main + +import ( + "fmt" + "math" +) + +func pointer_example() { +/* + Go pointers look and act analogously with C's. A pointer holds + the memory address of some value. More formally, the type `*T` + is a pointer to a type `T` value. +*/ + i, j := 42, 2701 + + // Declare p to be the memory address of i + // p is now a pointer to i's value of 42 + p := &i + fmt.Println(*p) // read i through the pointer + + // Set the pointer p's underlying value to be 21 + // This is the same as setting i to 21 + *p = 21 + fmt.Println(i) // print the new value of i + + // Set p to be j's memory address now + // p is now a pointer to j's value of 2701 + p = &j + *p = *p / 37 // divide j through the pointer + fmt.Println(j) // see the new value of j +} + +// Declare a new Vertex type to be a struct with two properties X and Y, each a float64 +type Vertex struct { + X, Y float64 +} + +/* + The Abs function receives a Vertex instance as input and returns + the square root of the sum of the squares of X and Y +*/ +func Abs(v Vertex) float64 { + return math.Sqrt(v.X * v.X + v.Y * v.Y) +} + +/* + The Scale function receives a pointer to a Vertex instance + This is because this function modifies the values of the input struct + So the rule of thumb is, is your function seeks to modify the values of something, + it needs to receive a pointer to that thing. If it doesn't seek to modify something's + values, then it doesn't need to receive a pointer to it. So in C and Go, the developer + gets to decide whether they want a function to be pass by value, or pass by reference. +*/ +func Scale(v *Vertex, factor float64) { + v.X = v.X * factor + v.Y = v.Y * factor +} + +/* + Methods in Go + Go does not have classes. Instead, methods can be defined on types. + To showcase this, let's change our Abs and Scale functions to be + methods on the Vertex type. + The only difference between a method and a function is that a method has a + special receiver argument that designates the owner of the method. The Abs + function as a method would declared as the following: +*/ + +// The receiver argument (the 'owner' of this method) comes before the actual function name +func (v Vertex) Abs() float64 { + return math.Sqrt(v.X * v.X + v.Y * v.Y) +} + +// TODO: Convert the Scale function to be a method on the Vertex class. The receiver argument in +// this case should still be a pointer since values are still being modified +// Implement your function here +func (v *Vertex) Scale(factor float64) { + v.X = v.X * factor + v.Y = v.Y * factor +} + +// TODO: Implement a method on the Vertex class called Midpoint that receives another vertex and finds the +// midpoint between the two vertices. Should return the midpoint as a Vertex. +// Implement your function here +func (v Vertex) Midpoint (z Vertex) Vertex { + return Vertex{(v.X + z.X) / 2, (v.Y + z.Y) / 2} +} + + +// TODO: Implement a method on the Vertex class called Distance that receives another vertex and finds the +// distance between the two vertices. Should return a float64 representing the distance. +// Implement your function here +func (v Vertex) Distance (z Vertex) float64 { + return math.Sqrt(math.Pow(v.X - z.X, 2) + math.Pow(v.Y - z.Y, 2)) +} + + +func main() { + pointer_example() + x := Vertex{3, 4} + x.Scale(10) + fmt.Println(x.Abs()) + + y := Vertex{9, 11} + fmt.Println(x.Midpoint(y)) + fmt.Println(x.Distance(y)) +} diff --git a/cc81stack/solution.go b/cc81stack/solution.go new file mode 100644 index 0000000..cd04187 --- /dev/null +++ b/cc81stack/solution.go @@ -0,0 +1,58 @@ +// https://piazza.com/class/j63w1pdyopf7kj?cid=107 +// https://youtu.be/K9aOAyGow28 + +package main + +import "fmt" + +// A type that represents values stored in our Stack +type Value struct { + value int +} + +// Type declaration of our Stack +// Holds an array of Values and a count of the number of Values in the stack +type Stack struct { + storage [] *Value + count int +} + +// Creates and returns a pointer to a Stack instance +func createStack() *Stack { + return &Stack{} +} + +// A Stack method that pushes the input Value onto our Stack +func (s *Stack) Push(v *Value) { + s.storage = append(s.storage[:s.count], v) + s.count++ +} + +// A Stack method that pops the top Value off of our Stack +// Returns a pointer to the popped Value +func (s *Stack) Pop() *Value { + if s.count == 0 { + return nil + } + s.count-- + return s.storage[s.count] +} + +func main() { + s := createStack() + s.Push(&Value{1}) + s.Push(&Value{2}) + s.Push(&Value{3}) + s.Push(&Value{4}) + s.Push(&Value{5}) + fmt.Println(s.Pop(), s.Pop(), s.Pop(), s.Pop(), s.Pop(), s.Pop()) +} + +/* +The Value type is used as a workaround for the fact that we would like to return +`nil` for the case when we try to pop from an empty stack. The `nil` value for +integers is 0, which would mean then that when we popped off of an empty stack, +the `Pop` method would return 0. However, 0 should be a valid value that we +could push onto our stack. Wrapping integers in a `Value` type allows us to +return `nil` then in the case that we call `Pop` on an empty stack. +*/ diff --git a/cc81stack/stack b/cc81stack/stack new file mode 100755 index 0000000..bce23d6 Binary files /dev/null and b/cc81stack/stack differ diff --git a/cc81stack/stack.go b/cc81stack/stack.go new file mode 100644 index 0000000..529a020 --- /dev/null +++ b/cc81stack/stack.go @@ -0,0 +1,55 @@ +// cc81 stack https://repl.it/student/submissions/1951449 +/* +Time to implement our first data structure in Go! +Today we'll be implementing a good ol' stack. + +If you get a working implementation completed, try to figure out why a struct +to store the integer value was needed for this exercise. +*/ + +package main + +import "fmt" + +// A type that represents values stored in our Stack +type Value struct { + value int +} + +// Type declaration of our Stack +// Holds an array of Values and a count of the number of Values in the stack +type Stack struct { + storage [] *Value + count int +} + +// Creates and returns a pointer to a Stack instance +func createStack() *Stack { + return &Stack{} +} + +// A Stack method that pushes the input Value onto our Stack +func (s *Stack) Push(v *Value) { + s.storage = append(s.storage[:s.count], v) + s.count++ +} + +// A Stack method that pops the top Value off of our Stack +// Returns a pointer to the popped Value +func (s *Stack) Pop() *Value { + if s.count == 0 { + return nil + } + s.count-- + return s.storage[s.count] +} + +func main() { + s := createStack() + s.Push(&Value{1}) + s.Push(&Value{2}) + s.Push(&Value{3}) + s.Push(&Value{4}) + s.Push(&Value{5}) + fmt.Println(s.Pop(), s.Pop(), s.Pop(), s.Pop(), s.Pop(), s.Pop()) +} diff --git a/cc82binaryTreeSearch/binaryTreeSearch.go b/cc82binaryTreeSearch/binaryTreeSearch.go new file mode 100644 index 0000000..a4a88e1 --- /dev/null +++ b/cc82binaryTreeSearch/binaryTreeSearch.go @@ -0,0 +1,282 @@ +// cc81 binarySearchTree https://repl.it/student/submissions/1958450 +/* +Implement a binary search tree type. +The MapInt method is akin to the depthFirstForEach method from Data Structures II. +It receives a function that is applied to every element in the BST. +However, since we're now in statically-typed land, it only works on a single +type (integers in this case). + +If you need a refresher on binary search trees, definitely go back and reference +the Data Structures II solution repo or your own implementation. + +Testing functions are at the bottom of the file. Hit the run button to execute +them in order to test your code. Try to get as many of them passing as you can :) +*/ + +package main + +import ( + "fmt" + "reflect" +) + +// Type that represents a binary search tree node +type TreeNode struct { + value int + left *TreeNode + right *TreeNode +} + +// Creates a BST node +func createTreeNode(value int) *TreeNode { + return &TreeNode{value: value} +} + +// Inserts the input value into the BST according to BST ordering rules +func (t *TreeNode) Insert(value int) { + node := &t.left + if value > t.value { +} + +// Checks to see if the BST contains the target value; returns a boolean +func (t TreeNode) Contains(target int) bool { + +} + +/* + The MapInt method gets passed an intFunc that itself receives an integer and returns + and integer; the intFunc is applied to every element in the BST, and an array of the + resulting values is returned +*/ +func (t *TreeNode) MapInt(intFunc func(int) int) []int { + +} + + + +/**********************Testing Functions***************************/ + +func TestDataIsRetained() { + actual := createTreeNode(4).value + expected := 4 + + if actual != expected { + fmt.Println("createTreeNode(4).value: %d, want %d.", actual, expected) + } else { + fmt.Println("TestDataIsRetained passed!") + } +} + +func TestInsertingLess() { + passed := true + bst := TreeNode{value: 9} + bst.Insert(5) + + actual := bst.value + expected := 9 + + if actual != expected { + passed = false + fmt.Println("bst.value: %d, want %d.", actual, expected) + } + + actual = bst.left.value + expected = 5 + + if actual != expected { + passed = false + fmt.Println("bst.left.value: %d, want %d.", actual, expected) + } + + if passed { + fmt.Println("TestInsertingLess passed!") + } +} + +func TestInsertingSame() { + passed := true + bst := TreeNode{value: 4} + bst.Insert(4) + + actual := bst.value + expected := 4 + + if actual != expected { + passed = false + fmt.Println("bst.data: %d, want %d.", actual, expected) + } + + actual = bst.left.value + expected = 4 + + if actual != expected { + passed = false + fmt.Println("bst.left.data: %d, want %d.", actual, expected) + } + + if passed { + fmt.Println("TestInsertingSame passed!") + } +} + +func TestInsertingMore() { + passed := true + bst := TreeNode{value: 4} + bst.Insert(5) + + actual := bst.value + expected := 4 + + if actual != expected { + passed = false + fmt.Println("bst.value: %d, want %d.", actual, expected) + } + + actual = bst.right.value + expected = 5 + + if actual != expected { + passed = false + fmt.Println("bst.value: %d, want %d.", actual, expected) + } + + if passed { + fmt.Println("TestInsertingMore passed!") + } +} + +func TestContains() { + passed := true + bst := TreeNode{value: 10} + bst.Insert(90) + + actual := bst.Contains(10) + expected := true + + if actual != expected { + passed = false + fmt.Println("bst.Contains expected to return true, got false.") + } + + actual = bst.Contains(90) + expected = true + + if actual != expected { + passed = false + fmt.Println("bst.Contains expected to return true, got false.") + } + + actual = bst.Contains(20) + expected = false + + if actual != expected { + passed = false + fmt.Println("bst.Contains expected to return false, got true.") + } + + if passed { + fmt.Println("TestContains passed!") + } +} + +func TestComplexTree() { + passed := true + bst := TreeNode{value: 4} + bst.Insert(2) + bst.Insert(6) + bst.Insert(1) + bst.Insert(3) + bst.Insert(7) + bst.Insert(5) + + actual := bst.value + expected := 4 + + if actual != expected { + passed = false + fmt.Println("bst.value: %d, want %d.", actual, expected) + } + + actual = bst.left.value + expected = 2 + + if actual != expected { + passed = false + fmt.Println("bst.left.value: %d, want %d.", actual, expected) + } + + actual = bst.left.left.value + expected = 1 + + if actual != expected { + passed = false + fmt.Println("bst.left.left.value: %d, want %d.", actual, expected) + } + + actual = bst.left.right.value + expected = 3 + + if actual != expected { + passed = false + fmt.Println("bst.left.right.value: %d, want %d.", actual, expected) + } + + actual = bst.right.value + expected = 6 + + if actual != expected { + passed = false + fmt.Println("bst.right.value: %d, want %d", actual, expected) + } + + actual = bst.right.left.value + expected = 5 + + if actual != expected { + passed = false + fmt.Println("bst.right.left.value: %d, want %d", actual, expected) + } + + actual = bst.right.right.value + expected = 7 + + if actual != expected { + passed = false + fmt.Println("bst.right.right.value: %d, want %d", actual, expected) + } + + if passed { + fmt.Println("TestComplexTree passed!") + } +} + +func TestMapIntWithComplexStructure() { + bst := TreeNode{value: 4} + bst.Insert(2) + bst.Insert(1) + bst.Insert(3) + bst.Insert(6) + bst.Insert(7) + bst.Insert(5) + + f := func(i int) int { + return i + } + + actual := bst.MapInt(f) + expected := []int{1,2,3,4,5,6,7} + + if !reflect.DeepEqual(actual, expected) { + fmt.Println("bst.MapInt(): %v, want %v.", actual, expected) + } +} + +func main() { + TestDataIsRetained() + TestInsertingLess() + TestInsertingSame() + TestInsertingMore() + TestContains() + TestComplexTree() + TestMapIntWithComplexStructure() +} diff --git a/cc82binaryTreeSearch/solution.go b/cc82binaryTreeSearch/solution.go new file mode 100644 index 0000000..d1d7b61 --- /dev/null +++ b/cc82binaryTreeSearch/solution.go @@ -0,0 +1,65 @@ +// https://piazza.com/class/j63w1pdyopf7kj?cid=110 +// https://youtu.be/Vdui-EVc-fU + +package main + +import ( + "fmt" + "reflect" +) + +// Type that represents a binary search tree node +type TreeNode struct { + value int + left *TreeNode + right *TreeNode +} + +// Creates a BST node +func createTreeNode(value int) *TreeNode { + return &TreeNode{value: value} +} + +// Inserts the input value into the BST according to BST ordering rules +func (t *TreeNode) Insert(value int) { + node := &t.left + if value > t.value { + node = &t.right + } + if *node == nil { + *node = createTreeNode(value) + } else { + (*node).Insert(value) + } +} + +// Checks to see if the BST contains the target value; returns a boolean +func (t TreeNode) Contains(target int) bool { + if t.value == target { + return true + } + if t.left != nil { + if t.left.Contains(target) { + return true + } + } + if t.right != nil { + if t.right.Contains(target) { + return true + } + } + return false +} + +/* + The MapInt method gets passed an intFunc that itself receives an integer and returns + an integer; the intFunc is applied to every element in the BST, and an array of the + resulting values is returned +*/ +func (t *TreeNode) MapInt(intFunc func(int) int) []int { + if t == nil { + return []int{} + } + right := append([]int{intFunc(t.value)}, t.right.MapInt(intFunc)...) + return append(t.left.MapInt(intFunc), right...) +} diff --git a/commonCharacters/commonCharacters.js b/commonCharacters/commonCharacters.js deleted file mode 100644 index 677d965..0000000 --- a/commonCharacters/commonCharacters.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Common Characters: - * Write a function that accepts two strings as arguments, and returns only the characters that are common to both strings. * - * Your function should return the common characters in the same order that they appear in the first argument. - * Do not return duplicate characters and ignore whitespace in your returned string. * - * Example: commonCharacters('acexivou', 'aegihobu') * - * Returns: 'aeiou' -*/ - diff --git a/constructors/constructors.js b/constructors/constructors.js deleted file mode 100644 index 34310c9..0000000 --- a/constructors/constructors.js +++ /dev/null @@ -1,24 +0,0 @@ - -/* Design several classes and their relationships for an RPG videogame. - * Classes: - * NPC -> Humanoid, Animal, Plant - * Humanoid -> Human, Elf, Orc - * Animal -> Bear, Wolf - * Plant -> FleshEatingDaisy - * - * Human -> Soldier, Peasant, Bandit - * - * NPC should be a general class for a non-player character in the game. - * This class will probably include general attributes like hp, strength, speed, etc. - * - * Humanoid, Animal, and Plant should all inherit from NPC. The classes - * shown to the right of the arrow are classes that will inherit - * from those classes. - * - * Soldier, Peasant, and Bandit should all inherit from Human. - * - * Create properties for these different classes that fit with the character. - * - * This is how you would structure the game objects in an actual game - * application in Unity or another similar framework. - */ \ No newline at end of file diff --git a/evenOccurences/evenOccurences.js b/evenOccurences/evenOccurences.js deleted file mode 100644 index 35da569..0000000 --- a/evenOccurences/evenOccurences.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - * * Find the first item that occurs an even number of times in an array. - * * Remember to handle multiple even-occurance items and return the first one. - * * Return null if there are no even-occurance items. - * */ - -/* - * * example usage: - * * const onlyEven = evenOccurence([1, 7, 2, 4, 5, 1, 6, 8, 9, 6, 4, 1]); - * * console.log(onlyEven); // 4 - * */ - -const evenOccurence = (arr) => { - // Your code here. -}; diff --git a/fizzBuzzTesting/fizzBuzz.js b/fizzBuzzTesting/fizzBuzz.js deleted file mode 100644 index a49221b..0000000 --- a/fizzBuzzTesting/fizzBuzz.js +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Create the function fizzBuzz that takes a single integer as an argument. - * Return 'fizz' if num is divisible by 3 with no remainder. - * Return 'buzz' if num is divisible by 5 with no remainder. - * Return 'fizzbuzz' if num is divisible by both 3 and 5 with no remainder. - * If the number is not divisible by either 3 or 5 then return the number given as the argument. - * Before you write your function write automated tests to test this function. - * The main focus of this challenge is the testing aspect of it. - */ - -const fizzBuzz = (num) => { - -}; - diff --git a/forLoopTimeout/forLoopTimeout.js b/forLoopTimeout/forLoopTimeout.js deleted file mode 100644 index ea85835..0000000 --- a/forLoopTimeout/forLoopTimeout.js +++ /dev/null @@ -1,13 +0,0 @@ -// Explain what is wrong with this code and how you would fix this. -// With ES6 there is a very, very simple way to solve this. -// See if you can solve this with just ES5 JS. -// The output should be 1, 2, 3, .... 10. Right now it just prints 11. -// I've been asked this three times in separate interviews. - -for (var i = 1; i <= 10; i++) { - setTimeout(function() { - // From looking at the code you would assume it would print 1 - 10 - // It doesn't. Why? How can you make it print 1 - 10. - console.log(i); - }, 0); -} diff --git a/isUnique/isUnique.js b/isUnique/isUnique.js deleted file mode 100644 index 3fae3d2..0000000 --- a/isUnique/isUnique.js +++ /dev/null @@ -1,11 +0,0 @@ -/* -* Implement an algorithm to determine if a string has all unique characters. -* Extra Credit - Answer this question - What if you cannot use additional data structures? -*/ - -const isUnique = (str) => { - -}; - -console.log(isUnique('abcdhijklmnopqrstuv')); // true -console.log(isUnique('abcdefga')); // false \ No newline at end of file diff --git a/largestPrimePalindrome/largestPrimePalindrome.js b/largestPrimePalindrome/largestPrimePalindrome.js deleted file mode 100644 index 1d15751..0000000 --- a/largestPrimePalindrome/largestPrimePalindrome.js +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Create a function that returns the largest prime palindrome less than 1000. - * Hint: it's 929 - * You will first want to determine if the number is a palindrome and then determine if it is prime. - * A palindrome is a number that is the same forwards and backwards: 121, 323, 123454321, etc. - * Extra credit: Modify the function to look for the largest prime palindrome less than any provided number. - * Extra credit 2: How can you improve the time complexity? (Google: Sieve of Eratosthenes) - */ diff --git a/logicGates/logicGates.js b/logicGates/logicGates.js deleted file mode 100644 index 6433782..0000000 --- a/logicGates/logicGates.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * For this coding challenge you will be recreating low level logic gates. - * You will first create the NAND function and then you will create - * NOT, OR, AND, and XOR all using the NAND function that you created. - * Implement NAND however you would like and then use NAND to implement the - * other logic gates. - * See the link below for the truth tables for these logic gates. - * https://en.wikipedia.org/wiki/NAND_logic#NAND - * All functions should return a 1 for true and a 0 for false. - */ - -const NAND = (x, y) => { - // You can use whatever JS operators that you would like: &&, ||, ! -}; - -const NOT = (n) => { - // Do not use !, &&, or || -}; - -const AND = (x, y) => { - // Do not use &&, ||, or ! - // You can use any of the functions that you have already written -}; - -const OR = (x, y) => { - // Do not use ||, &&, or ! - // You can use any of the functions that you have already written -}; - -const XOR = (x, y) => { - // Do not use ||, &&, or ! - // You can use any of the functions that you have already written -}; diff --git a/longestRun/longestRun.js b/longestRun/longestRun.js deleted file mode 100644 index e7151f1..0000000 --- a/longestRun/longestRun.js +++ /dev/null @@ -1,10 +0,0 @@ -/** -* Longest Run -* Write a function that, given a string, finds the longest run of identical characters and returns an array containing the start and end indices of that run. -* If there are two runs of equal length, return the first one. Return [0,0] for no runs. -* Examples: -* Input: "abbbcc" Output: [ 1, 3 ] -* Input: "mississippi" Output: [ 2, 3 ] -* Input: "abcdefgh" Output: [ 0, 0 ] -* Input: "aabbbcccc" Output: [ 5, 4 ] -*/ diff --git a/longestString/longestString.js b/longestString/longestString.js deleted file mode 100644 index e36a1c1..0000000 --- a/longestString/longestString.js +++ /dev/null @@ -1,4 +0,0 @@ -/* - * Write a function that accepts an array of strings. - * Return the longest string in the array. - */ \ No newline at end of file diff --git a/longestString/solution.js b/longestString/solution.js deleted file mode 100644 index e843ce5..0000000 --- a/longestString/solution.js +++ /dev/null @@ -1,9 +0,0 @@ -const longestString = (strArr) => { - let tempStr = ''; - strArr.forEach(str => { - if(str.length > tempStr.length) tempStr = str; - }); - return tempStr; -}; - -longestString(['abc', 'def', 'gasdfasf', 'asdf', 'e', 'agwoaiengpoing']); \ No newline at end of file diff --git a/meanMedianMode/meanMedianMode.js b/meanMedianMode/meanMedianMode.js deleted file mode 100644 index 821fdc0..0000000 --- a/meanMedianMode/meanMedianMode.js +++ /dev/null @@ -1,4 +0,0 @@ -/* - * Given an array of numbers calculate the mean, median, and mode. - * Return an object with properties for the mean, median, and mode. - */ diff --git a/operators/operators.js b/operators/operators.js deleted file mode 100644 index b6dbed4..0000000 --- a/operators/operators.js +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Implement three functions called multiply, divide, and modulo. - * These functions should multiply, divide, or return the remainder of two arguments. - * Now for the tricky part: you can only use the + and - operators to implement these functions. - * For division just drop the remainder. - */ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..8e683b7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1144 @@ +{ + "name": "code-challenges", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "acorn": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", + "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz", + "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "json-schema-traverse": "0.3.1", + "json-stable-stringify": "1.0.1" + } + }, + "ajv-keywords": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz", + "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=", + "dev": true + }, + "ansi-escapes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "color-convert": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", + "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + } + }, + "doctrine": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "dev": true, + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.8.0.tgz", + "integrity": "sha1-Ip7w41Tg5h2DfHqA/fuoJeGZgV4=", + "dev": true, + "requires": { + "ajv": "5.2.3", + "babel-code-frame": "6.26.0", + "chalk": "2.1.0", + "concat-stream": "1.6.0", + "cross-spawn": "5.1.0", + "debug": "3.1.0", + "doctrine": "2.0.0", + "eslint-scope": "3.7.1", + "espree": "3.5.1", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.5", + "imurmurhash": "0.1.4", + "inquirer": "3.3.0", + "is-resolvable": "1.0.0", + "js-yaml": "3.10.0", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "7.0.0", + "progress": "2.0.0", + "require-uncached": "1.0.3", + "semver": "5.4.1", + "strip-ansi": "4.0.0", + "strip-json-comments": "2.0.1", + "table": "4.0.2", + "text-table": "0.2.0" + } + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "espree": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz", + "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=", + "dev": true, + "requires": { + "acorn": "5.1.2", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "external-editor": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.5.tgz", + "integrity": "sha512-Msjo64WT5W+NhOpQXh0nOHm+n0RfU1QUwDnKYvJ8dEJ8zlwLrqXNTv5mSUTJpepf41PDJGyhueTw2vNZW+Fr/w==", + "dev": true, + "requires": { + "iconv-lite": "0.4.19", + "jschardet": "1.5.1", + "tmp": "0.0.33" + } + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "ignore": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", + "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "3.0.0", + "chalk": "2.1.0", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.0.5", + "figures": "2.0.0", + "lodash": "4.17.4", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-resolvable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "dev": true, + "requires": { + "tryit": "1.0.3" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "jschardet": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.1.tgz", + "integrity": "sha512-vE2hT1D0HLZCLLclfBSfkfTTedhVj0fubHpJBHKwwUWX0nSbhPAfk+SG9rTX95BYNmau8rGFfCeaT6T5OW1C2A==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "4.0.8" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + } + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "5.2.3", + "ajv-keywords": "2.1.0", + "chalk": "2.1.0", + "lodash": "4.17.4", + "slice-ansi": "1.0.0", + "string-width": "2.1.1" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "tryit": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..d3aa35d --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "code-challenges", + "version": "1.0.0", + "description": "Prep for Job Interviews", + "main": "app.js", + "scripts": { + "test": "eslint *.js && mocha -R nyan tests", + "watch": "npm test -- --watch" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/mixelpixel/CS1-Code-Challenges.git" + }, + "author": "Patrick Kennedy", + "license": "ISC", + "bugs": { + "url": "https://github.com/mixelpixel/CS1-Code-Challenges/issues" + }, + "homepage": "https://github.com/mixelpixel/CS1-Code-Challenges#readme", + "dependencies": { + "babel-preset-es2015": "*", + "eslint-config-airbnb": "*", + "eslint-plugin-import": "*" + }, + "devDependencies": { + "eslint": "^4.8.0" + } +} diff --git a/parallel/parallel.js b/parallel/parallel.js deleted file mode 100644 index 9998dea..0000000 --- a/parallel/parallel.js +++ /dev/null @@ -1,40 +0,0 @@ -'use strict'; - -/* Implement the function parallel: - * - * Parallel has two parameters, an array of asynchronous functions (tasks) and a callback. - * Each of the tasks takes a callback and invokes that callback when complete. - * - * The callback passed to parallel is then performed on the results of the callbacks of the tasks. - * - * The order of these results should be the same as the order of the tasks. - * It is important to note that this is not the order in which the tasks return, - * but the order in which they are passed to parallel. - * - * Once all the callbacks of the tasks are returned, parallel should invoke the callback - * on the results array. - * - * - * Example: - * - * parallel([ - * function(callback){ - * setTimeout(function(){ - * callback('one'); - * }, 200); - * }, - * function(callback){ - * setTimeout(function(){ - * callback('two'); - * }, 100); - * } - * ], - * // optional callback - * (results) => { - * // the results array will equal ['one','two'] even though - * // the second function had a shorter timeout. - console.log(results); // ['one', 'two'] - * }); - * - * - */ diff --git a/queueStack/queueStack.js b/queueStack/queueStack.js deleted file mode 100644 index 5a05207..0000000 --- a/queueStack/queueStack.js +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Write a stack class. Once you're done, - * implement a queue using two stacks. - */ diff --git a/quickSort/quickSort.js b/quickSort/quickSort.js deleted file mode 100644 index 7af4064..0000000 --- a/quickSort/quickSort.js +++ /dev/null @@ -1,9 +0,0 @@ - -/* - * Implement the quick sort sorting algorithm. Assume the input is an array of integers. - * https://en.wikipedia.org/wiki/Quicksort - * https://www.khanacademy.org/computing/computer-science/algorithms#quick-sort - */ -const quickSort = (nums) => { - -}; \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..6b51c75 --- /dev/null +++ b/readme.md @@ -0,0 +1,11 @@ +# CS1 - Lambda School Code Challenges +## Steps to ensuring your changes get pulled down: +1. **You will only need to run this step once:** + - `git remote add upstream https://github.com/ryanhca/CS1-Code-Challenges.git` +2. **To get the daily repo changes each day, run this:** + - `git pull upstream master` + +### You'll then have to resolve any merge conflicts that come up. +*(Don't worry, you'll be pros at this after you're done and this is something that you'll have to do in the real world... all the time)* +*** +["Cracking the Coding Interview"](http://www.crackingthecodinginterview.com/) by Gayle Laakmann McDowell diff --git a/rockPaperScissors/rockPaperScissors.js b/rockPaperScissors/rockPaperScissors.js deleted file mode 100644 index 9f54ca2..0000000 --- a/rockPaperScissors/rockPaperScissors.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - * * Write a function that generates every sequence of throws a single - * * player could throw over a three-round game of rock-paper-scissors. - * * - * * Your output should look something like: - * * [["rock", "rock", "rock"], - * * ["rock", "rock", "paper"], - * * ["rock", "rock", "scissor"], - * * ["rock", "paper", "rock"], - * ...etc... - * */ - -const rockPaperScissors = () => { - // TODO: your solution here -}; \ No newline at end of file diff --git a/rotateImage/rotateImage.js b/rotateImage/rotateImage.js deleted file mode 100644 index a75ea9e..0000000 --- a/rotateImage/rotateImage.js +++ /dev/null @@ -1,2 +0,0 @@ -// Given an image represented by an NxN matrix, where each pixel in the image is an integer from 0 - 9, -// write a method to rotate the image by 90 degrees. Can you do this in place? diff --git a/rotatedArray/rotatedArray.js b/rotatedArray/rotatedArray.js deleted file mode 100644 index ae1f0f7..0000000 --- a/rotatedArray/rotatedArray.js +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Given a sorted array that has been rotated some number of items right or - * left, i.e. [0, 1, 2, 3, 4, 5, 6, 7] might become [4, 5, 6, 7, 0, 1, 2, 3] - * how can you efficiently find an element? For simplicity, you can assume - * that there are no duplicate elements in the array. - * - * rotatedArraySearch should return the index of the element if it is in the - * array and should return null otherwise. - * - * For instance: - * rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 2) === 5 - * - * rotatedArraySearch([4, 5, 6, 0, 1, 2, 3], 100) === null - * - * Target time complexity: O(log(n)) - */ \ No newline at end of file diff --git a/selectionSort/selectionSort.js b/selectionSort/selectionSort.js deleted file mode 100644 index feefe83..0000000 --- a/selectionSort/selectionSort.js +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Sort an array of numbers using selection sort. - * https://en.wikipedia.org/wiki/Selection_sort - * https://www.khanacademy.org/computing/computer-science/algorithms/sorting-algorithms/a/sorting - * - * [1, 6, 2, 5, 3, 4] -> [1, 2, 3, 4, 5, 6] - */ - -const selectionSort = (arr) => { - -}; \ No newline at end of file diff --git a/stackOfPlates/stackOfPlates.js b/stackOfPlates/stackOfPlates.js deleted file mode 100644 index 6a47b61..0000000 --- a/stackOfPlates/stackOfPlates.js +++ /dev/null @@ -1,7 +0,0 @@ -/* Stack of Plates: Imagine a (literal) stack of plates. If the stack gets too high, it might topple. - * Therefore, in real life, we would likely start a new stack when the previous stack exceeds some threshold. - * Implement a data structure SetOfStacks that mimics this. - * SetOfStacks should be composed of several stacks and should create a new stack once the previous one exceeds capacity. - * SetOfStacks.push() and SetOfStacks.pop() should behave identically to a single stack - * (that is, pop( ) should return the same values as it would if there were just a single stack). - */ \ No newline at end of file diff --git a/stringCompression/stringCompression.js b/stringCompression/stringCompression.js deleted file mode 100644 index 48db571..0000000 --- a/stringCompression/stringCompression.js +++ /dev/null @@ -1,6 +0,0 @@ -// String Compression: Implement a method to perform basic string compression using -// the counts of repeated characters. -// For example, the string aabcccccaaa would become a2b1c5a3. -// If the "compressed" string would not become smaller than the original string, -// your method should return the original string. -// You can assume the string has only uppercase and lowercase letters (a - z). diff --git a/vowelCount/vowelCount.js b/vowelCount/vowelCount.js deleted file mode 100644 index 27fad79..0000000 --- a/vowelCount/vowelCount.js +++ /dev/null @@ -1,4 +0,0 @@ -/* - * Write a function that returns the count of the total number of vowels in a string. - * Example: 'Hello World!' -> 3 - */