├── Medium ├── 17: Prime Checker.js ├── 09: Binary Converter.js ├── 25: ThreeFive Multiples.js ├── 05: Division.js ├── 13: Formatted Division.js ├── 01: Prime Time.js ├── 02: Run Length.js ├── 04: Palindrome Two.js ├── 14: Consecutive.js ├── 20: Number Search.js ├── 06: String Scramble.js ├── 22: Bracket Matcher.js ├── 08: Array Addition.js ├── 03: Prime Mover.js ├── 24: Coin Determiner.js ├── 21: Triple Double.js ├── 11: Simple Mode.js ├── 26: Fibonacci Checker.js ├── 16: Permutation Step.js ├── 07: Arith Geo II.js ├── 10: Letter Count.js ├── 18: Dash Insert II.js ├── 29: Overlapping Rectangles.js ├── 27: Multiple Brackets.js ├── 15: Counting Minutes.js ├── 12: Caesar Cipher.js ├── 23: String Reduction.js ├── 19: Swap II.js └── 28: Most Free Time.js ├── Easy ├── 48: Power Set Count.js ├── 01: First Reverse.js ├── 08: Check Nums.js ├── 02: First Factorial.js ├── 13: Word Count.js ├── 20: Division Stringified.js ├── 26: Third Greatest.js ├── 05: Simple Adding.js ├── 27: Powers of Two.js ├── 10: Alphabet Soup.js ├── 09: Time Convert.js ├── 43: Next Palindrome.js ├── 34: Hamming Distance.js ├── 11: AB Check.js ├── 14: Ex Oh.js ├── 36: Bitwise One.js ├── 12: Vowel Count.js ├── 47: Bitwise Two.js ├── 23: Dash Insert.js ├── 37: Other Products.js ├── 42: Even Pairs.js ├── 15: Palindrome.js ├── 32: Overlapping Ranges.js ├── 24: Swap Case.js ├── 06: Letter Capitalize.js ├── 44: Largest Pair.js ├── 45: Nonrepeating Character.js ├── 33: Superincreasing.js ├── 46: Two Sum.js ├── 28: Additive Persistence.js ├── 39: Array Matching.js ├── 40: Binary Reversal.js ├── 38: Wave Sorting.js ├── 31: Changing Sequence.js ├── 29: Multiplicative Persistence.js ├── 07: Simple Symbols.js ├── 22: Mean Mode.js ├── 35: Rectangle Area.js ├── 51: Basic Roman Numerals.js ├── 04: Letter Changes.js ├── 30: Off Line Minimum.js ├── 19: Second GreatLow.js ├── 16: Arith Geo.js ├── 17: Array Addition I.js ├── 03: Longest Word.js ├── 50: Palindrome Creator.js ├── 25: Number Addition.js ├── 21: Counting Minutes I.js ├── 41: Longest Increasing Sequence.js ├── 49: Product Digits.js └── 18: Letter Count I.js └── README.md /Medium/17: Prime Checker.js: -------------------------------------------------------------------------------- 1 | TBD 2 | -------------------------------------------------------------------------------- /Medium/09: Binary Converter.js: -------------------------------------------------------------------------------- 1 | function BinaryConverter(str) { 2 | 3 | // Native method to the rescue! 4 | return parseInt(str, 2); 5 | } 6 | -------------------------------------------------------------------------------- /Easy/48: Power Set Count.js: -------------------------------------------------------------------------------- 1 | function PowerSetCount(arr) { 2 | 3 | // Total permutations is represented by 2 raised to the number of digits. Hence, "Power" set! 4 | return Math.pow(2, arr.length); 5 | } 6 | -------------------------------------------------------------------------------- /Easy/01: First Reverse.js: -------------------------------------------------------------------------------- 1 | function FirstReverse(str) { 2 | 3 | // Convert string to array, use native reverse method, then convert array back to string! 4 | return str.split('').reverse().join(''); 5 | 6 | } 7 | -------------------------------------------------------------------------------- /Easy/08: Check Nums.js: -------------------------------------------------------------------------------- 1 | function CheckNums(num1,num2) { 2 | 3 | // If the numbers are equal, return -1. Otherwise, return Boolean for whether num2 is greater than num1. 4 | return (num1 === num2) ? -1 : num2 > num1; 5 | } 6 | -------------------------------------------------------------------------------- /Easy/02: First Factorial.js: -------------------------------------------------------------------------------- 1 | function FirstFactorial(num) { 2 | 3 | // Recursively multiply by next factorial with base case === 1 4 | if (num === 1) { 5 | return 1; 6 | } 7 | return num * FirstFactorial(num - 1); 8 | } 9 | -------------------------------------------------------------------------------- /Easy/13: Word Count.js: -------------------------------------------------------------------------------- 1 | function WordCount(str) { 2 | 3 | // Split string by spaces to separate words 4 | let arr = str.split(' '); 5 | 6 | // Length of array represents total number of words! 7 | return arr.length; 8 | } 9 | -------------------------------------------------------------------------------- /Easy/20: Division Stringified.js: -------------------------------------------------------------------------------- 1 | function DivisionStringified(num1,num2) { 2 | 3 | // Use native toLocaleString method to standardize numbers. No decimals included here. 4 | return Number((num1 / num2).toFixed(0)).toLocaleString(); 5 | } 6 | -------------------------------------------------------------------------------- /Easy/26: Third Greatest.js: -------------------------------------------------------------------------------- 1 | function ThirdGreatest(strArr) { 2 | 3 | // Sort array in descending order of each string's length 4 | var arr = strArr.sort(function(a,b){ return b.length - a.length }); 5 | 6 | // Third term now equals third largest term! 7 | return arr[2]; 8 | } 9 | -------------------------------------------------------------------------------- /Easy/05: Simple Adding.js: -------------------------------------------------------------------------------- 1 | function SimpleAdding(num) { 2 | 3 | // Create storage for sum 4 | let sum = 0; 5 | 6 | // Add all values from 1 to num, inclusive 7 | for (let i = 1; i <= num; i++) { 8 | sum += i; 9 | } 10 | 11 | // Return total after adding 12 | return sum; 13 | } 14 | -------------------------------------------------------------------------------- /Easy/27: Powers of Two.js: -------------------------------------------------------------------------------- 1 | function PowersofTwo(num) { 2 | 3 | // Divide number by 2 until the number is smaller than 2. 4 | while (num >= 2) { 5 | num /= 2; 6 | } 7 | 8 | // If loop ends when num equals 1, then num is a power of two. Otherwise, two cannot multiply itself into num so we return false. 9 | return num === 1; 10 | } 11 | -------------------------------------------------------------------------------- /Easy/10: Alphabet Soup.js: -------------------------------------------------------------------------------- 1 | function AlphabetSoup(str) { 2 | 3 | // Split string into array of letters to use native sort method 4 | let arr = str.split(''); 5 | 6 | // Sort letters by ascending order of Unicode 7 | arr.sort(function(a, b) { return a.charCodeAt(0) - b.charCodeAt(0); }); 8 | 9 | // Join letters into string 10 | return arr.join(''); 11 | } 12 | -------------------------------------------------------------------------------- /Medium/25: ThreeFive Multiples.js: -------------------------------------------------------------------------------- 1 | function ThreeFiveMultiples(num) { 2 | 3 | // To add all multiples 4 | let sum = 0; 5 | 6 | // Loop from first possible multiple to just under given number 7 | for (let i = 3; i < num; i++) { 8 | if (i % 3 === 0 || i % 5 === 0) { 9 | sum += i; 10 | } 11 | } 12 | 13 | // This represents the sum of all multiples of 3 and 5 below num! 14 | return sum; 15 | } 16 | -------------------------------------------------------------------------------- /Easy/09: Time Convert.js: -------------------------------------------------------------------------------- 1 | function TimeConvert(num) { 2 | 3 | // The number of hours is represented by the floor integer after the number is divided by 60 4 | let hours = Math.floor(num / 60); 5 | 6 | // The number of leftover minutes is represented by the remainder 7 | let minutes = num % 60; 8 | 9 | // Concatenate hours and minutes with a colon between to match the desired format 10 | return hours + ":" + minutes; 11 | } 12 | -------------------------------------------------------------------------------- /Medium/05: Division.js: -------------------------------------------------------------------------------- 1 | function Division(num1,num2) { 2 | 3 | // Need minimum value to begin looping through factors 4 | var min = Math.min(num1, num2); 5 | 6 | // A factor is found when both inputs are divisible by the same number 7 | for (let i = min; i > 0; i--) { 8 | 9 | // The first shared factor will be the GCF since we're looping downward! 10 | if ((num1 % i === 0) && (num2 % i === 0)) { 11 | return i; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Easy/43: Next Palindrome.js: -------------------------------------------------------------------------------- 1 | function NextPalindrome(num) { 2 | 3 | // Create check for palindrome 4 | function isPalindrome(str) { 5 | return str.split('').reverse().join('') === str; 6 | } 7 | 8 | // Start checking at next number 9 | num = num + 1; 10 | 11 | // Increase number until find palindrome 12 | while (isPalindrome(num.toString()) === false) { 13 | num++; 14 | } 15 | 16 | // When loop exits, we have our next palindrome! 17 | return (num); 18 | } 19 | -------------------------------------------------------------------------------- /Easy/34: Hamming Distance.js: -------------------------------------------------------------------------------- 1 | function HammingDistance(strArr) { 2 | 3 | // Track number of different characters 4 | let counter = 0; 5 | 6 | // Loop through first string 7 | for (let i = 0; i < strArr[0].length; i++) { 8 | 9 | // When characters in same position don't match, increase counter by 1 10 | if (strArr[0][i] !== strArr[1][i]) { 11 | counter++; 12 | } 13 | } 14 | 15 | // Counter represents hamming distance 16 | return counter; 17 | } 18 | -------------------------------------------------------------------------------- /Easy/11: AB Check.js: -------------------------------------------------------------------------------- 1 | function ABCheck(str) { 2 | 3 | // Loop through word 4 | for (let i = 0; i < str.length; i++) { 5 | 6 | // If letter equals 'a', check 3 positions in front and behind for 'b' 7 | if (str.charAt(i) === 'a') { 8 | if (str.charAt(i+4) === 'b' || str.charAt(i-4) === 'b') { 9 | return true; 10 | } 11 | } 12 | } 13 | 14 | // If loop fails to return true, then 'a' and 'b' are not 3 spaces apart! 15 | return false; 16 | } 17 | -------------------------------------------------------------------------------- /Easy/14: Ex Oh.js: -------------------------------------------------------------------------------- 1 | function ExOh(str) { 2 | 3 | // Establish counters for 'x' and 'o' 4 | let x = 0; 5 | let o = 0; 6 | 7 | // Loop through string 8 | for (let i = 0; i < str.length; i++) { 9 | 10 | // Add 1 to respective counter each time an 'x' or 'o' is found 11 | if (str[i] === 'x') { 12 | x++; 13 | } else { 14 | o++; 15 | } 16 | } 17 | 18 | // If the counters for 'x' and 'o' are the same, return true. Otherwise, return false. 19 | return x === o; 20 | } 21 | -------------------------------------------------------------------------------- /Easy/36: Bitwise One.js: -------------------------------------------------------------------------------- 1 | function BitwiseOne(strArr) { 2 | 3 | // Need storage array to push 1 or 0 according to rules 4 | var answer = []; 5 | 6 | // If either character is 1, then 1 is pushed instead of 0. 7 | for (var i = 0; i < strArr[0].length; i++) { 8 | if (strArr[0][i] == 1 || strArr[1][i] == 1) { 9 | answer.push(1); 10 | } else { 11 | answer.push(0); 12 | } 13 | } 14 | 15 | // Answer array contains correct binary values. Return as joined string. 16 | return answer.join(''); 17 | } 18 | -------------------------------------------------------------------------------- /Medium/13: Formatted Division.js: -------------------------------------------------------------------------------- 1 | function FormattedDivision(num1,num2) { 2 | /* 3 | * We have a native method for this type of output! 4 | * But be careful about the data type per method, since all require numbers. 5 | * toFixed returns a STRING, so we convert to a number for toLocaleString. 6 | * The arguments in toLocaleString set the region standard for decimals/ commas 7 | * and amount of sigfigs after the decimal place. 8 | */ 9 | 10 | return Number((num1 / num2).toFixed(4)).toLocaleString(undefined, { minimumFractionDigits: 4 }); 11 | } 12 | -------------------------------------------------------------------------------- /Easy/12: Vowel Count.js: -------------------------------------------------------------------------------- 1 | function VowelCount(str) { 2 | 3 | // Make all letters lowercase for conditional check in loop 4 | str = str.toLowerCase(); 5 | 6 | // Create counter storage 7 | let counter = 0; 8 | 9 | // Loop through string 10 | for (let i = 0; i < str.length; i++) { 11 | 12 | // If character is a vowel, add 1 to counter 13 | if (str[i] === 'a' || str[i] === 'e' || str[i] === 'i' || str[i] === 'o' || str[i] === 'u') { 14 | counter++; 15 | } 16 | } 17 | 18 | // Counter represents total number of vowels in string 19 | return counter; 20 | } 21 | -------------------------------------------------------------------------------- /Easy/47: Bitwise Two.js: -------------------------------------------------------------------------------- 1 | function BitwiseTwo(strArr) { 2 | 3 | // Create storage for digits that pass operation 4 | var answer = []; 5 | 6 | // Both strings have same length so loop through either 7 | for (var i = 0; i < strArr[0].length; i++) { 8 | 9 | // If either respective digit is a 0, then 0 is pushed instead of 1 10 | if (strArr[0][i] === '0' || strArr[1][i] === '0') { 11 | answer.push('0'); 12 | } else { 13 | answer.push('1'); 14 | } 15 | } 16 | 17 | // Output as string 18 | return answer.join(''); 19 | } 20 | -------------------------------------------------------------------------------- /Easy/23: Dash Insert.js: -------------------------------------------------------------------------------- 1 | function DashInsert(str) { 2 | 3 | // Storage for pushing integers and dashes 4 | let answer = []; 5 | 6 | // Loop through array 7 | for (let i = 0; i < str.length; i++) { 8 | 9 | // Number will always be pushed as integer 10 | answer.push(parseInt(str[i])); 11 | 12 | // If odd integer followed by odd integer, push dash 13 | if (parseInt(str[i]) % 2 === 1 && parseInt(str[i+1]) % 2 === 1) { 14 | answer.push('-'); 15 | } 16 | } 17 | 18 | // Odd pairs will have exactly one dash between them! 19 | return answer.join(''); 20 | } 21 | -------------------------------------------------------------------------------- /Medium/01: Prime Time.js: -------------------------------------------------------------------------------- 1 | function PrimeTime(num) { 2 | 3 | // Integers less than 2 cannot be prime 4 | if (num < 2) { 5 | return false; 6 | } 7 | 8 | // Brute force method checks if our number is divisible by any number until its square root. 9 | // This ends the loop before iterating over factors a second time (assuming we had ended the loop at num instead). 10 | for (i = 2; i <= Math.sqrt(num); i++) { 11 | if (num % i === 0) { 12 | return false; 13 | } 14 | } 15 | 16 | // If no integers divide into our number (excluding values less than 2), then we have a prime number! 17 | return true; 18 | } 19 | -------------------------------------------------------------------------------- /Easy/37: Other Products.js: -------------------------------------------------------------------------------- 1 | function OtherProducts(arr) { 2 | 3 | // Create storage array 4 | var answer = []; 5 | 6 | // Loop through integer array 7 | for (var i = 0; i < arr.length; i++) { 8 | 9 | // Create shallow copy of array 10 | var newArr = arr.slice(); 11 | 12 | // Remove current character 13 | newArr.splice(i, 1); 14 | 15 | // Sum all remaining values 16 | var product = newArr.reduce(function(p, v) { return p * v; }); 17 | 18 | // Store product in answer array 19 | answer.push(product); 20 | } 21 | 22 | // Join with hyphens as requested 23 | return answer.join('-'); 24 | } 25 | -------------------------------------------------------------------------------- /Easy/42: Even Pairs.js: -------------------------------------------------------------------------------- 1 | function EvenPairs(str) { 2 | 3 | // Create array where odds will never be pushed 4 | var noOdds = []; 5 | 6 | // Loop through str pushing non-odd characters 7 | for (var i = 0; i < str.length; i++) { 8 | if (parseInt(str[i]) % 2 !== 1) { 9 | answer.push(str[i]); 10 | } 11 | } 12 | 13 | // All numbers are now even. If any two next to each other, return true. 14 | for (var j = 0; j < answer.length - 1; j++) { 15 | if (!isNaN(parseInt(answer[j])) && !isNaN(parseInt(answer[j+1]))) { 16 | return true; 17 | } 18 | } 19 | 20 | // If no pairs exist, return false. 21 | return false; 22 | } 23 | -------------------------------------------------------------------------------- /Medium/02: Run Length.js: -------------------------------------------------------------------------------- 1 | function RunLength(str) { 2 | 3 | // Storage for characters and count 4 | let answer = []; 5 | let counter = 1; 6 | 7 | // Loop through given string 8 | for (var i = 0; i < str.length; i++) { 9 | 10 | // Track how many times a character repeats 11 | if (str[i] === str[i+1]) { 12 | counter++; 13 | 14 | // When arrive at different character, store the previous character with its count, then reset counter 15 | } else { 16 | answer.push(counter, str[i]); 17 | counter = 1; 18 | } 19 | } 20 | 21 | // Return the Run Length Encoding of our string! 22 | return answer.join(""); 23 | } 24 | -------------------------------------------------------------------------------- /Easy/15: Palindrome.js: -------------------------------------------------------------------------------- 1 | function Palindrome(str) { 2 | 3 | // Convert to array with spaces removed 4 | let arr = str.split(' ').join('').split(''); 5 | 6 | // Reverse characters with native array method 7 | let reversed = arr.reverse().join(''); 8 | 9 | // Create original string without spaces to compare 10 | let noSpaces = str.split(' ').join(''); 11 | 12 | // After removing all spaces, return Boolean for whether the original string equals the reversed string 13 | return noSpaces === reversed; 14 | } 15 | 16 | WITH CHAINING: 17 | 18 | function Palindrome(str) { 19 | return str.split(' ').join('').split('').reverse().join('') === str.split(' ').join(''); 20 | } 21 | -------------------------------------------------------------------------------- /Easy/32: Overlapping Ranges.js: -------------------------------------------------------------------------------- 1 | function OverlappingRanges(arr) { 2 | 3 | // Ranges should overlap by last array value or more 4 | let desiredOverlap = arr.pop(); 5 | 6 | // Calculate actual overlap by defining narrower range wtih overlapped values 7 | // e.g. [4, 10] with [2, 6] becomes [4, 6] 8 | let lowerBound = Math.max(arr[0], arr[2]); 9 | let upperBound = Math.min(arr[1], arr[3]); 10 | 11 | // Calculate number of values in new range 12 | let actualOverlap = upperBound - lowerBound + 1; 13 | 14 | // Return true if actual overlap is at least desired overlap. Otherwise, return false. 15 | return actualOverlap >= desiredOverlap; 16 | } 17 | -------------------------------------------------------------------------------- /Medium/04: Palindrome Two.js: -------------------------------------------------------------------------------- 1 | function PalindromeTwo(str) { 2 | 3 | // Make all letters lowercase 4 | str = str.toLowerCase(); 5 | 6 | // Create storage for alphabetic chars 7 | let alphabetArr = []; 8 | 9 | // Loop through entire string 10 | for (let i = 0; i < str.length; i++) { 11 | 12 | // Store alphabetic chars 13 | if (str.charCodeAt(i) > 96 && str.charCodeAt(i) < 123) { 14 | alphabetArr.push(str[i]); 15 | } 16 | } 17 | 18 | // Check to see whether original string matches reversed string! 19 | if (alphabetArr.join('') === alphabetArr.reverse().join('')) { 20 | return true; 21 | } else { 22 | return false; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Easy/24: Swap Case.js: -------------------------------------------------------------------------------- 1 | function SwapCase(str) { 2 | 3 | // Create array to modify in place 4 | let chars = str.split(""); 5 | 6 | // Loop through array of characters 7 | for (let i = 0; i < chars.length; i++) { 8 | 9 | // If current value is uppercase, make lowercase 10 | if (chars[i] === chars[i].toUpperCase()) { 11 | chars[i] = chars[i].toLowerCase(); 12 | 13 | // If current value is lowercase, make uppercase 14 | } else if (chars[i] === chars[i].toLowerCase()) { 15 | chars[i] = chars[i].toUpperCase(); 16 | } 17 | } 18 | 19 | // Non-alphabetic characters remain unaffected. Return as string. 20 | return chars.join(""); 21 | } 22 | -------------------------------------------------------------------------------- /Easy/06: Letter Capitalize.js: -------------------------------------------------------------------------------- 1 | function LetterCapitalize(str) { 2 | 3 | // Split string into array of words 4 | let words = str.split(' '); 5 | 6 | // Create solution storage 7 | let answer = []; 8 | 9 | // Loop through each word 10 | for (let i = 0; i < words.length; i++) { 11 | 12 | // Current word 13 | let word = words[i]; 14 | 15 | // Create new word by capitalizing first letter then concatenating with rest of word 16 | let newWord = word[0].toUpperCase() + word.slice(1, word.length + 1); 17 | 18 | // Push newly capitalized word to answer array 19 | answer.push(newWord); 20 | } 21 | 22 | // Return sentence with spaces 23 | return answer.join(' '); 24 | } 25 | -------------------------------------------------------------------------------- /Easy/44: Largest Pair.js: -------------------------------------------------------------------------------- 1 | function LargestPair(num) { 2 | 3 | // Convert to string for looping 4 | var str = num.toString(); 5 | 6 | // Store largest double digit pair 7 | var highest = 0; 8 | 9 | // Construct double digit number by making current digit the tens place 10 | // and the next digit the ones place, then combine 11 | for (var i = 0; i < str.length - 1; i++) { 12 | var tens = Number(str[i]); 13 | var unit = Number(str[i+1]); 14 | var curr = tens*10 + unit; 15 | 16 | // Update highest value if found larger double digit number 17 | if (curr > highest) 18 | highest = curr; 19 | } 20 | 21 | // Let the world know the largest double digit pair! 22 | return highest; 23 | } 24 | -------------------------------------------------------------------------------- /Medium/14: Consecutive.js: -------------------------------------------------------------------------------- 1 | function Consecutive(arr) { 2 | 3 | // Sort array in descending order 4 | arr.sort((a, b) => b - a); 5 | 6 | // Create storage for number of missing digits 7 | let missingDigits = 0; 8 | 9 | // Compare integer pair values 10 | for (let i = 0; i < arr.length - 1; i++) { 11 | let curr = arr[i]; 12 | let next = arr[i+1]; 13 | 14 | // If different non-consecutive digits, calculate number of digits between 15 | if (curr - next > 1) { 16 | missingDigits += (curr - next - 1) 17 | } 18 | } 19 | 20 | // Return the total number of digits required to make the sequence consecutive! 21 | return missingDigits; 22 | } 23 | -------------------------------------------------------------------------------- /Medium/20: Number Search.js: -------------------------------------------------------------------------------- 1 | function NumberSearch(str) { 2 | 3 | // Check Boolean check for alphabetic letter 4 | function isLetter(c) { return c.toLowerCase() !== c.toUpperCase();} 5 | 6 | // Initialize counters at 0 7 | let letterCount = 0; 8 | let sum = 0; 9 | 10 | // Loop through string to increment counters 11 | for (let i = 0; i < str.length; i++) { 12 | let char = str[i]; 13 | 14 | if (isLetter(char)) { 15 | letterCount++; 16 | } 17 | if (Number.isInteger(parseInt((char)))) { 18 | sum += parseInt(char); 19 | } 20 | } 21 | 22 | // Divide the sum of all numbers by letter count then round without decimals! 23 | return (sum / letterCount).toFixed(0); 24 | } 25 | -------------------------------------------------------------------------------- /Easy/45: Nonrepeating Character.js: -------------------------------------------------------------------------------- 1 | function NonrepeatingCharacter(str) { 2 | 3 | // Store key-value pairs for letter: count 4 | var table = {}; 5 | 6 | // Build up table 7 | for (var i = 0; i < str.length; i++) { 8 | 9 | // If letter not yet in table, create it with count of 1 10 | if (table[str[i]] === undefined) { 11 | table[str[i]] = 1; 12 | 13 | // If letter exists in table already, add 1 to count 14 | } else { 15 | table[str[i]]++; 16 | } 17 | } 18 | 19 | // If loop finds letter with a value of 1, then it's the first letter that doesn't repeat! 20 | for (var letter in table) { 21 | if (table[letter] === 1) { 22 | return letter; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Easy/33: Superincreasing.js: -------------------------------------------------------------------------------- 1 | function Superincreasing(arr) { 2 | 3 | // Loop through array starting at second term 4 | for (let i = 1; i < arr.length; i++) { 5 | 6 | // Create array of values before current term 7 | let prevArr = arr.slice(0, i); 8 | 9 | // Sum up previous array 10 | let prevSum = prevArr.reduce(function(p, v) { return p + v }); 11 | 12 | // If current term is ever less than or equal to 13 | // the sum of all numbers before it, then not superincreasing 14 | if (arr[i] <= prevSum) { 15 | return false; 16 | } 17 | } 18 | 19 | // If all values are greater than previous sum, sequence is superincreasing 20 | return true; 21 | } 22 | -------------------------------------------------------------------------------- /Easy/46: Two Sum.js: -------------------------------------------------------------------------------- 1 | function TwoSum(arr) { 2 | 3 | // Remove and store first integer 4 | let target = arr.shift(); 5 | 6 | // Store length for loops 7 | const LEN = arr.length; 8 | 9 | // Create storage array for sum pair subarrays 10 | let answer = []; 11 | 12 | // Add each term to rest of terms one by one 13 | for (let i = 0; i < LEN; i++) { 14 | for (let j = i + 1; j < LEN; j++) { 15 | 16 | // If both integers add to target, push as subarray then end inner loop since pair was found 17 | if (arr[i] + arr[j] === target) { 18 | answer.push([arr[i], arr[j]]); 19 | break; 20 | } 21 | } 22 | } 23 | 24 | // If subarray pairs stored, join with space. Otherwise, return -1. 25 | return (answer.length > 0) ? answer.join(' ') : -1; 26 | } 27 | -------------------------------------------------------------------------------- /Medium/06: String Scramble.js: -------------------------------------------------------------------------------- 1 | function StringScramble(str1,str2) { 2 | 3 | // Convert string to mutable array 4 | let arr1 = str1.split(''); 5 | 6 | // Loop through second string 7 | for (let i = 0; i < str2.length; i++) { 8 | 9 | // If a value from string 2 is not found in array 1, we know string 2 cannot be rearranged into string 1. 10 | if (!arr1.includes(str2[i])) { 11 | return false; 12 | 13 | // For every matching char, we remove that char from array 1 to track duplicates 14 | } else { 15 | arr1.splice(arr1.indexOf(str2[i]), 1); 16 | } 17 | } 18 | 19 | // If we were able to splice every letter out of array 1, then string 2 can be rearranged into string 1! 20 | return true; 21 | } 22 | -------------------------------------------------------------------------------- /Medium/22: Bracket Matcher.js: -------------------------------------------------------------------------------- 1 | function BracketMatcher(str) { 2 | 3 | // Track number of left parens vs right parens 4 | let counter = 0; 5 | 6 | // Loop through string 7 | for (let i = 0; i < str.length; i++) { 8 | 9 | // Increase counter by 1 if we find a left parens 10 | if (str[i] === "(") { 11 | counter++; 12 | 13 | // Decrease counter by 1 if we find a right parens 14 | } else if (str[i] === ")") { 15 | counter--; 16 | } 17 | 18 | // If counter drops below 0, a right parens has no left match! 19 | if (counter < 0) { 20 | return 0; 21 | } 22 | } 23 | 24 | // If all pairs match, return 1! Otherwise, return 0. 25 | return counter === 0 ? 1 : 0; 26 | } 27 | -------------------------------------------------------------------------------- /Easy/28: Additive Persistence.js: -------------------------------------------------------------------------------- 1 | function AdditivePersistence(num) { 2 | 3 | // Convert number to array of digits 4 | function numToArray(n) { 5 | return n.toString(10).split("").map(function(val){return parseInt(val)}); 6 | } 7 | 8 | // Initialize integer array 9 | let intArr = numToArray(num); 10 | 11 | // Keep track of number of times digits are combined a.k.a. additive persistence 12 | let count = 0; 13 | 14 | // Repeatedly sum digits, create new integer array for each sum, and increase counter until last digit left 15 | while (intArr.length > 1) { 16 | let newDigits = intArr.reduce(function(p, v){return p + v}); 17 | intArr = numToArray(newDigits); 18 | count++; 19 | } 20 | 21 | // The counter represents additive persistence of a number! 22 | return count; 23 | } 24 | -------------------------------------------------------------------------------- /Easy/39: Array Matching.js: -------------------------------------------------------------------------------- 1 | function ArrayMatching(strArr) { 2 | 3 | // Watch out for those string arrays! 4 | let firstArr = JSON.parse(strArr[0]); 5 | let secondArr = JSON.parse(strArr[1]); 6 | 7 | // Initialize variables for conditional check on array length 8 | let longerArr, shorterArr; 9 | 10 | // Remember longer and shorter array 11 | if (firstArr.length >= secondArr.length) { 12 | longerArr = firstArr; 13 | shorterArr = secondArr; 14 | } else { 15 | longerArr = secondArr; 16 | shorterArr = firstArr; 17 | } 18 | 19 | // Replace values in longer array with sum against shorter array's terms 20 | for (var i = 0; i < shorterArr.length; i++) { 21 | longerArr[i] += shorterArr[i]; 22 | } 23 | 24 | // Format with hyphens 25 | return longerArr.join('-'); 26 | } 27 | -------------------------------------------------------------------------------- /Medium/08: Array Addition.js: -------------------------------------------------------------------------------- 1 | function ArrayAddition(arr) { 2 | 3 | // Sort array in ascending order 4 | let array = arr.sort((a,b) => a - b); 5 | 6 | // Extract target 7 | let target = array.pop(); 8 | 9 | // Recursively search all possible combinations 10 | function lookForSolution(){ 11 | function search(sum, i) { 12 | if (sum == target) { 13 | return true; 14 | } 15 | else if (sum > target || i === array.length) { 16 | return null; 17 | } 18 | else { 19 | return search(sum + array[i], i + 1) || 20 | search(sum, i + 1); 21 | } 22 | } 23 | 24 | // Begin search 25 | return search(0,0); 26 | } 27 | 28 | // Call recursive search function and hope for a solution! 29 | return lookForSolution() || false; 30 | } 31 | -------------------------------------------------------------------------------- /Easy/40: Binary Reversal.js: -------------------------------------------------------------------------------- 1 | function BinaryReversal(str) { 2 | 3 | // Thanks to Infinities Loop on Stack Overflow for this padding function! 4 | function pad(num, size) { 5 | var s = num+""; 6 | while (s.length < size) {s = "0" + s;} 7 | return s; 8 | } 9 | 10 | // Convert to binary 11 | let binary = Number(str).toString(2); 12 | 13 | // Determine number of bits 14 | let bits = Math.ceil(binary.length / 8); 15 | 16 | // Convert number of bits into total digit length 17 | let digits = 8 * bits; 18 | 19 | // Pad zeros onto leading bit 20 | let padded = pad(binary, digits); 21 | 22 | // Reverse binary string 23 | let reversed = padded.split('').reverse().join(''); 24 | 25 | // Convert to decimal 26 | let decimal = parseInt(reversed, 2); 27 | 28 | return decimal; 29 | } 30 | -------------------------------------------------------------------------------- /Easy/38: Wave Sorting.js: -------------------------------------------------------------------------------- 1 | function WaveSorting(arr) { 2 | 3 | // Create object with key-value pairs of unique digit: count 4 | let digitCounts = arr.reduce(function(memo, value) { 5 | value in memo ? memo[value]++ : memo[value] = 1; 6 | return memo; 7 | }, {}); 8 | 9 | // Can wave sort if no number repeats more than all other numbers combined 10 | // so need to store the largest repeat 11 | let highestCount = 1; 12 | 13 | // Loop through object with digits and their counts 14 | for (let digit in digitCounts) { 15 | 16 | // Store highest count 17 | if (digitCounts[digit] > highestCount) { 18 | highestCount = digitCounts[digit]; 19 | } 20 | } 21 | 22 | // If one number's count doesn't exceed half the total of numbers, we can wave sort! 23 | return highestCount <= (arr.length / 2); 24 | } 25 | -------------------------------------------------------------------------------- /Easy/31: Changing Sequence.js: -------------------------------------------------------------------------------- 1 | function ChangingSequence(arr) { 2 | 3 | // Calculate whether beginning with increasing or decreasing sequence 4 | let diff = arr[1] - arr[0]; 5 | 6 | // Loop through sequence 7 | for (let i = 0; i < arr.length; i++) { 8 | 9 | // Readability 10 | let curr = arr[i]; 11 | let next = arr[i+1]; 12 | 13 | // If increasing sequence, return index when stops increasing 14 | if (diff > 0) { 15 | if (curr > next) { 16 | return i; 17 | } 18 | } 19 | 20 | // If decreasing sequence, return index when stops decreasing 21 | if (diff < 0) { 22 | if (curr < next) { 23 | return i; 24 | } 25 | } 26 | } 27 | 28 | // If never find change of sequence, return -1. 29 | return -1; 30 | } 31 | -------------------------------------------------------------------------------- /Easy/29: Multiplicative Persistence.js: -------------------------------------------------------------------------------- 1 | function MultiplicativePersistence(num) { 2 | 3 | // Convert number to array of digits 4 | function numToArray(n) { 5 | return n.toString(10).split("").map(function(val){return parseInt(val)}); 6 | } 7 | 8 | // Initialize integer array 9 | let intArr = numToArray(num); 10 | 11 | // Keep track of number of times digits are combined a.k.a. multiplicative persistence 12 | let count = 0; 13 | 14 | // Repeatedly multiply digits, create new integer array for each product, and increase counter until last digit left 15 | while (intArr.length > 1) { 16 | let newDigits = intArr.reduce(function(p, v){return p * v}); 17 | intArr = numToArray(newDigits); 18 | count++; 19 | } 20 | 21 | // The counter represents multiplicative persistence of a number! 22 | return count; 23 | } 24 | -------------------------------------------------------------------------------- /Medium/03: Prime Mover.js: -------------------------------------------------------------------------------- 1 | function PrimeMover(num) { 2 | 3 | // Create function that returns Boolean for whether a number is prime 4 | function isPrime(n) { 5 | if (n < 2) { 6 | return false; 7 | } 8 | for (i = 2; i <= Math.sqrt(n); i++) { 9 | if (n % i === 0) { 10 | return false; 11 | } 12 | } 13 | return true; 14 | } 15 | 16 | // Increment when we find a prime number 17 | let counter = 0; 18 | 19 | // Loop through values given in prompt 20 | for (let j = 2; j < 10000; j++) { 21 | 22 | // When a value is prime, counter is incremented by 1 23 | if (isPrime(j)) { 24 | counter++; 25 | } 26 | 27 | // When counter equals our target number, we know that j is the num'th prime! 28 | if (counter === num) { 29 | return j; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Easy/07: Simple Symbols.js: -------------------------------------------------------------------------------- 1 | function SimpleSymbols(str) { 2 | 3 | // Convert alphabetic characters to lowercase for Unicode check 4 | str = str.toLowerCase(); 5 | 6 | // Loop through string 7 | for (let i = 0; i < str.length; i++) { 8 | 9 | // If alphabetic character... 10 | if (str.charCodeAt(i) > 96 && str.charCodeAt(i) < 123) { 11 | 12 | // ...and it doesn't have a plus sign to the left or right... 13 | if (str[i-1] !== '+' || str[i+1] !== '+') { 14 | 15 | // ... we know that at least one alphabetic character lacks a plus sign to the left or right! 16 | return false; 17 | } 18 | } 19 | } 20 | 21 | // If loop never finds an alphabetic character without plus signs to the left or right, 22 | // then all alphabetic characters must have a plus sign to the left and right! 23 | return true; 24 | } 25 | -------------------------------------------------------------------------------- /Easy/22: Mean Mode.js: -------------------------------------------------------------------------------- 1 | function MeanMode(arr) { 2 | 3 | // Sum all values, then divide by the total number of values to get the mean 4 | let mean = arr.reduce(function(p, v) { return p + v; }) / arr.length; 5 | 6 | // Create object with key-value pairs of digit: count 7 | let table = arr.reduce(function(memo, n) { 8 | n in memo ? memo[n]++ : memo[n] = 1; 9 | return memo; 10 | }, {}); 11 | 12 | // Track mode and number of times it appears in array 13 | let answer = {mode: null, count: 0}; 14 | 15 | // Loop through integers to determine which has highest count. Update mode and count if find new mode. 16 | for (let n in table) { 17 | if (table[n] > answer['count']) { 18 | answer['mode'] = parseInt(n); 19 | answer['count'] = table[n]; 20 | } 21 | } 22 | 23 | // If mode equals mean, return 1. Otherwise, return 0. 24 | return (answer['mode'] === mean) ? 1 : 0; 25 | } 26 | -------------------------------------------------------------------------------- /Medium/24: Coin Determiner.js: -------------------------------------------------------------------------------- 1 | function CoinDeterminer(num) { 2 | 3 | // Create helper function that creates all possible sums 4 | function addCoins(coins, sums) { 5 | let output = []; 6 | 7 | for (let i = 0; i < coins.length; i++) { 8 | for (let j = 0; j < sums.length; j++) { 9 | output.push(coins[i] + sums[j]); 10 | } 11 | } 12 | 13 | return output; 14 | } 15 | 16 | let coins = [1, 5, 7, 9, 11]; 17 | let counter = 1; 18 | 19 | // Track all possible sums 20 | let coinSums = coins; 21 | 22 | // If our number does not exist in the coinSums array, 23 | // then sum again and increase the sum counter by 1 24 | while (!coinSums.includes(num)) { 25 | coinSums = addCoins(coins, coinSums); 26 | counter++; 27 | } 28 | 29 | // When our input number is found in the coinSums array, 30 | // counter will represent how many coins were added! 31 | return counter; 32 | } 33 | -------------------------------------------------------------------------------- /Medium/21: Triple Double.js: -------------------------------------------------------------------------------- 1 | function TripleDouble(num1,num2) { 2 | 3 | // Need to loop through each character in number, so set to strings 4 | let str1 = num1.toString(); 5 | let str2 = num2.toString(); 6 | 7 | // Loop through first number until can't begin a triple match 8 | for (let i = 0; i < str1.length - 2; i++) { 9 | 10 | // If three terms in a row are the same... 11 | if (str1[i] === str1[i+1] && str1[i+1] === str1[i+2]) { 12 | 13 | //.. then loop through second number until can't begin a double match 14 | for (var j = 0; j < str2.length - 1; j++) { 15 | 16 | // If two terms in a row match the character from the first number, 17 | // then we've found a triple double! 18 | if (str2[j] === str1[i] && str2[j] === str2[j+1]) { 19 | return 1; 20 | } 21 | } 22 | } 23 | } 24 | 25 | // If no triple double found, return 0. 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Easy/35: Rectangle Area.js: -------------------------------------------------------------------------------- 1 | function RectangleArea(strArr) { 2 | 3 | // Create function to format points by erasing parentheses and separating x and y values into subarray 4 | function makePoint(p) { 5 | return p.replace('(', '').replace(')', '').split(' '); 6 | } 7 | 8 | // By increasing in order of x-coordinates, we know which values to subtract for width and height 9 | let sorted = strArr.sort(function(a, b) { return b[1] < a[1] }); 10 | 11 | // Create 3 coordinate points to find difference of x and y values 12 | let corner0 = makePoint(strArr[0]); 13 | let corner1 = makePoint(strArr[1]); 14 | let corner2 = makePoint(strArr[2]); 15 | 16 | // Difference of x values yields width 17 | let width = Math.abs(corner2[0] - corner1[0]); 18 | 19 | // Difference of y values between other two points yields height 20 | let height = Math.abs(corner1[1] - corner0[1]); 21 | 22 | // Area equals width times height 23 | return width * height; 24 | } 25 | -------------------------------------------------------------------------------- /Easy/51: Basic Roman Numerals.js: -------------------------------------------------------------------------------- 1 | function BasicRomanNumerals(str) { 2 | 3 | // Create references for each numeral 4 | var numbers = {I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000}; 5 | 6 | // Keep tally 7 | var sum = 0; 8 | 9 | // Look at current and next numeral to determine value 10 | for (var i = 0; i < str.length; i++) { 11 | var curr = numbers[str[i]]; 12 | var next = numbers[str[i+1]]; 13 | 14 | // If the current value is lesser, subtract it from the next value THEN add that to sum 15 | if (curr < next) { 16 | sum += next - curr; 17 | 18 | // Skip next term since it has been absorbed into sum already 19 | i++; 20 | 21 | // If current value is greater than or equal to the next value, increase sum by that amount 22 | } else { 23 | sum += curr; 24 | } 25 | } 26 | 27 | // This represents the total given by the Roman numerals! 28 | return sum; 29 | } 30 | -------------------------------------------------------------------------------- /Medium/11: Simple Mode.js: -------------------------------------------------------------------------------- 1 | function SimpleMode(arr) { 2 | 3 | // Create storage for mode and its count 4 | let mode = {integer: null, count: 1}; 5 | 6 | // Build table with key-value pairs of integer: count 7 | let table = arr.reduce((memo, value) => { 8 | 9 | // Increase integer count by 1 if already exists in table. Otherwise, create integer with count of 1. 10 | value in memo ? memo[value]++ : memo[value] = 1; 11 | 12 | // If any number repeats more than previous mode does, then we've found a new mode! 13 | if (memo[value] > mode.count) { 14 | mode.count = memo[value]; 15 | mode.integer = value; 16 | } 17 | 18 | // Don't forget to return the table every time we call reduce! 19 | return memo; 20 | 21 | // Second argument sets memo to empty object for first reduction. 22 | }, {}); 23 | 24 | // If no numbers repeat, return -1. Otherwise, return the mode! 25 | return mode.count > 1 ? mode.integer : -1; 26 | } 27 | -------------------------------------------------------------------------------- /Easy/04: Letter Changes.js: -------------------------------------------------------------------------------- 1 | function LetterChanges(str) { 2 | 3 | // A solution without regex or Unicode! 4 | 5 | // Write out alphabet and shifted alphabet with vowels capitalized 6 | const ALPHABET = 'abcdefghijklmnopqrstuvwxyz'; 7 | const NEW_ALPHABET = 'bcdEfghIjklmnOpqrstUvwxyzA'; 8 | 9 | // Create storage array 10 | let answer = []; 11 | 12 | // Preprocess string to be all lowercase to match alphabet 13 | str = str.toLowerCase(); 14 | 15 | // Loop through string 16 | for (let i = 0; i < str.length; i++) { 17 | 18 | // If alphabetic character, store shifted character from new alphabet 19 | if (ALPHABET.includes(str[i])) { 20 | answer.push(NEW_ALPHABET[ALPHABET.indexOf(str[i])]); 21 | 22 | // If non-alphabetic character, simply push that character to answer array 23 | } else { 24 | answer.push(str[i]); 25 | } 26 | } 27 | 28 | // Join the array into our final modified string! 29 | return answer.join(''); 30 | } 31 | -------------------------------------------------------------------------------- /Medium/26: Fibonacci Checker.js: -------------------------------------------------------------------------------- 1 | function FibonacciChecker(num) { 2 | 3 | // Base cases 4 | if (num === 0 || num === 1) { 5 | return 'yes'; 6 | } 7 | 8 | // Cache pairs of values while looping 9 | let prev = 0; 10 | let curr = 1; 11 | 12 | // Loop until we match or exceed our number 13 | while(num > curr) { 14 | 15 | // Save previous value temporarily 16 | let temp = prev; 17 | 18 | // Set new previous value to old current value 19 | prev = curr; 20 | 21 | // Set new current value to the sum of old current and old previous values 22 | curr += temp; 23 | } 24 | 25 | // If we exited the loop when our number equals the current fibonacci value, 26 | // then our number is part of the fibonacci sequence! Otherwise, the current value 27 | // has passed over our number, and num is therefore not part of the fibonacci sequence. 28 | return num === curr ? 'yes' : 'no' 29 | } 30 | -------------------------------------------------------------------------------- /Easy/30: Off Line Minimum.js: -------------------------------------------------------------------------------- 1 | function OffLineMinimum(strArr) { 2 | 3 | // Test for integers 4 | function isNumeric(n) { 5 | return !isNaN(parseInt(n)) && isFinite(n); 6 | } 7 | 8 | // Need one array for holding integers during loop and another for storing smallest integers at each 'E' 9 | let integers = []; 10 | let answer = []; 11 | 12 | // Loop through array of characters 13 | for (let i = 0; i < strArr.length; i++) { 14 | let char = strArr[i]; 15 | 16 | // If character is a number, push to integer array and 17 | // sort so that integers are always in ascending order 18 | if (isNumeric(char)) { 19 | integers.push(parseInt(char)); 20 | integers.sort(function(a, b) { return a - b }); 21 | } 22 | 23 | // If character is 'E', push smallest number to answer array and remove from integer array 24 | if (char === 'E') { 25 | answer.push(integers.shift()); 26 | } 27 | } 28 | 29 | // Format 30 | return answer.join(','); 31 | } 32 | -------------------------------------------------------------------------------- /Medium/16: Permutation Step.js: -------------------------------------------------------------------------------- 1 | function PermutationStep(num) { 2 | 3 | // Convert to array for modifying digits in place 4 | let arr = num.toString().split(''); 5 | 6 | // Loop through array from back to front 7 | for (let i = arr.length - 1; i > 0; i--) { 8 | let curr = arr[i]; 9 | let next = arr[i-1]; 10 | 11 | // If our current digit is larger than the next digit, swap them 12 | if (curr > next) { 13 | arr[i] = next; 14 | arr[i-1] = curr; 15 | 16 | // If you think about it, the smallest permutation occurs by 17 | // sorting all digits after the swap in ascending order 18 | let sortedTail = arr.splice(i, arr.length - 1).sort((a, b) => a - b); 19 | 20 | // Combine the spliced array and ascending tail to get the next greatest permutation! 21 | return arr.concat(sortedTail).join(''); 22 | } 23 | } 24 | 25 | // If digits cannot be rearranged to produce a greater number, return -1! 26 | return -1; 27 | } 28 | -------------------------------------------------------------------------------- /Easy/19: Second GreatLow.js: -------------------------------------------------------------------------------- 1 | function SecondGreatLow(arr) { 2 | 3 | // Sort array in ascending order 4 | let sorted = arr.sort(function(a,b) {return a - b;}); 5 | 6 | // Edge case: if only two digits, we simply reverse them. 7 | if (arr.length === 2) { 8 | return sorted.reverse().join(' '); 9 | } 10 | 11 | // Store the largest and smallest values 12 | let highest = arr[arr.length - 1]; 13 | let smallest = arr[0]; 14 | 15 | // Create solution storage 16 | let answer = []; 17 | 18 | // Loop through array 19 | for (let i = 0; i < arr.length; i++) { 20 | 21 | // If value is not equal to highest or lowest, store in answer array 22 | if (arr[i] !== highest && arr[i] !== smallest) { 23 | answer.push(arr[i]); 24 | } 25 | } 26 | 27 | // Sort new array without largest and smallest values in ascending order 28 | let newSort = answer.sort(function(a,b) { return a - b; }); 29 | 30 | // Newly sorted array will have the second lowest and second greatest terms as first and last terms, respectively. 31 | return answer[0] + " " + answer[answer.length - 1]; 32 | } 33 | -------------------------------------------------------------------------------- /Medium/07: Arith Geo II.js: -------------------------------------------------------------------------------- 1 | function ArithGeoII(arr) { 2 | 3 | // Write function test for arithmetic sequence where each pair of terms should have same difference 4 | function isArithmetic(arr) { 5 | const DIFF = arr[1] - arr[0]; 6 | let arith = true; 7 | 8 | for (let i = 0; i < arr.length - 1; i++) { 9 | if (arr[i+1] - arr[i] !== DIFF) { 10 | arith = false; 11 | } 12 | } 13 | return arith; 14 | } 15 | 16 | // Write function test for geometric sequence where each pair of terms should have same ratio 17 | function isGeometric(arr) { 18 | const RATIO = arr[1] / arr[0]; 19 | let geo = true; 20 | 21 | for (let i = 0; i < arr.length - 1; i++) { 22 | if (arr[i+1] / arr[i] !== RATIO) { 23 | geo = false; 24 | } 25 | } 26 | return geo; 27 | } 28 | 29 | // The tests guide the way! 30 | if (isArithmetic(arr)) { 31 | return 'Arithmetic'; 32 | } else if (isGeometric(arr)) { 33 | return 'Geometric'; 34 | } else { 35 | return -1; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Medium/10: Letter Count.js: -------------------------------------------------------------------------------- 1 | function LetterCount(str) { 2 | 3 | // Separate words into array 4 | let words = str.split(' '); 5 | 6 | // Create storage for word objects with letter counts 7 | let table = {}; 8 | 9 | // Track word with largest number of repeated characters 10 | let answer = {word: null, highest: 1}; 11 | 12 | // Loop through each word 13 | for (let i = 0; i < words.length; i++) { 14 | let word = words[i]; 15 | 16 | // Create word property in table with value object of each letter and count 17 | table[word] = word.split('').reduce((memo, letter) => { 18 | letter in memo ? memo[letter]++ : memo[letter] = 1; 19 | 20 | // If a letter repeats more than any other letter, store new answer 21 | if (memo[letter] > answer['highest']) { 22 | answer['highest'] = memo[letter]; 23 | answer['word'] = word; 24 | } 25 | return memo; 26 | }, {}) 27 | } 28 | 29 | // If no repeats, return -1. Otherwise, return first word with greatest number of repeated letters! 30 | return answer['highest'] > 1 ? answer['word'] : -1; 31 | } 32 | -------------------------------------------------------------------------------- /Medium/18: Dash Insert II.js: -------------------------------------------------------------------------------- 1 | function DashInsertII(num) { 2 | 3 | // Write parity functions 4 | function isOdd(n) { 5 | return n % 2 === 1; 6 | } 7 | function isEven(n) { 8 | return n % 2 === 0; 9 | } 10 | 11 | // Convert num to string for looping 12 | let str = num.toString(); 13 | 14 | // Create storage for integers, dashes and asterisks 15 | let answer = []; 16 | 17 | // Loop through every digit 18 | for (let i = 0; i < str.length; i++) { 19 | 20 | // Convert each digit into a number data type 21 | let curr = parseInt(str[i]); 22 | let next = parseInt(str[i+1]); 23 | 24 | // Push the current integer 25 | answer.push(curr); 26 | 27 | // If consecutive terms share parity and neither is 0, insert symbol 28 | if (isOdd(curr) && isOdd(next)) { 29 | answer.push('-'); 30 | } 31 | if (isEven(curr) && isEven(next) && curr !== 0 && next !== 0) { 32 | answer.push('*'); 33 | } 34 | } 35 | 36 | // Return manipulated number! 37 | return answer.join(''); 38 | } 39 | -------------------------------------------------------------------------------- /Easy/16: Arith Geo.js: -------------------------------------------------------------------------------- 1 | function ArithGeo(arr) { 2 | 3 | // Store arithmetic difference and geometric ratio 4 | let diff = arr[1] - arr[0]; 5 | let ratio = arr[1] / arr[0]; 6 | 7 | // Use counters to see if entire sequence is arithmetic or geometric 8 | let arithCount = 0; 9 | let geoCount = 0; 10 | 11 | // Loop through sequence 12 | for (let i = 0; i < arr.length - 1; i++) { 13 | 14 | // If difference of terms matches arithmetic difference, add 1 to arithmetic counter 15 | if (arr[i+1] - arr[i] === diff) { 16 | arithCount++; 17 | } 18 | 19 | // If ratio of terms matches geometric ratio, add 1 to geometric counter 20 | if (arr[i+1] / arr[i] === ratio) { 21 | geoCount++; 22 | } 23 | } 24 | 25 | // If all terms share same difference, sequence is arithmetic 26 | if (arithCount === arr.length - 1) { 27 | return 'Arithmetic'; 28 | } 29 | 30 | // If all terms share same ratio, sequence is geometric 31 | if (geoCount === arr.length - 1) { 32 | return 'Geometric'; 33 | } 34 | 35 | // If both conditional checks fail, then sequence is neither arithmetic nor geometric! 36 | return -1; 37 | } 38 | -------------------------------------------------------------------------------- /Easy/17: Array Addition I.js: -------------------------------------------------------------------------------- 1 | function ArrayAdditionI(arr) { 2 | 3 | // Calculate highest value by reducing array such that only the larger of each pair of values is returned 4 | let highest = arr.reduce(function(p, v) { return v > p ? v : p; }); 5 | 6 | // Filter out highest value by keeping all values less than the highest value 7 | let smallArr = arr.filter(function(val) { return val < highest; }); 8 | 9 | // Found this subsetsum function from lumberjack87 in Coderbyte forum 10 | // Uses recursive template from Eloquent Javascript Ch.3 to search all possible combinations via branching 11 | function subsetsum(target, array) { 12 | 13 | // Base case when array is emptied 14 | if (array.length === 0) { 15 | return target === 0; 16 | } 17 | 18 | // First term is stored 19 | let n = array[0]; 20 | 21 | // The rest of the array is stored separately 22 | array = array.slice(1); 23 | 24 | // Call function with same target and sliced array OR subtract first value from target, then search sliced array 25 | return subsetsum(target, array) || subsetsum(target - n, array); 26 | } 27 | 28 | // Recursive magic finds combination of values in smallArr that add to our highest value 29 | return subsetsum(highest, smallArr); 30 | } 31 | -------------------------------------------------------------------------------- /Easy/03: Longest Word.js: -------------------------------------------------------------------------------- 1 | function LongestWord(sen) { 2 | // A solution without regex! 3 | 4 | // Make all letters lowercase for Unicode check and convert to array by splitting at spaces 5 | let withSymbols = sen.toLowerCase().split(' '); 6 | 7 | // Use storage array to push words without symbols 8 | let noSymbols = []; 9 | 10 | // Create memory for word with largest length 11 | let highest = {word: null, count: 0}; 12 | 13 | // Loop through array containing symbols 14 | for (let i = 0; i < withSymbols.length; i++) { 15 | let word = withSymbols[i]; 16 | 17 | // For each word, push alphanumeric characters to noSymbols array 18 | for (let j = 0; j < word.length; j++) { 19 | let letter = word[j]; 20 | 21 | if ((word.charCodeAt(j) > 96 && word.charCodeAt(j) < 123) || (word.charCodeAt(j) > 47 && word.charCodeAt(j) < 58)) { 22 | noSymbols.push(letter); 23 | } 24 | } 25 | 26 | // If word length without symbols is higher than previous highest amount, store new count and word 27 | if (noSymbols.length > highest['count']) { 28 | highest['count'] = noSymbols.length; 29 | highest['word'] = noSymbols.join(''); 30 | } 31 | 32 | // Reset array for next word in loop 33 | noSymbols = []; 34 | } 35 | 36 | // Return word with highest count 37 | return highest['word']; 38 | } 39 | -------------------------------------------------------------------------------- /Easy/50: Palindrome Creator.js: -------------------------------------------------------------------------------- 1 | function PalindromeCreator(str) { 2 | 3 | // Write a palindrome test 4 | function isPalindrome(string) { 5 | return string === string.split('').reverse().join(''); 6 | } 7 | 8 | // Check if input is already a palindrome 9 | if (isPalindrome(str)) return 'palindrome'; 10 | 11 | let arr = str.split(''); 12 | let len = arr.length; 13 | 14 | // Remove one character at a time and test if palindrome 15 | for (let i = 0; i < len; i++) { 16 | let removedChar = arr.splice(i, 1).join(''); 17 | 18 | if (isPalindrome(arr.join(''))) return removedChar; 19 | 20 | arr.splice(i, 0, removedChar); 21 | } 22 | 23 | // For every character removed, remove another character and test if palindrome 24 | for (let i = 0; i < len; i++) { 25 | let removedChar = arr.splice(i, 1).join(''); 26 | 27 | if (len > 4) { 28 | for (let j = 0; j < len; j++) { 29 | let removedChar2 = arr.splice(j, 1).join(''); 30 | 31 | if (isPalindrome(arr.join(''))) return removedChar + '' + removedChar2; 32 | 33 | arr.splice(j, 0, removedChar2); 34 | } 35 | } 36 | 37 | arr.splice(i, 0, removedChar); 38 | } 39 | 40 | // If no palindrome was found after removing 2 characters 41 | return 'not possible'; 42 | } 43 | -------------------------------------------------------------------------------- /Easy/25: Number Addition.js: -------------------------------------------------------------------------------- 1 | function NumberAddition(str) { 2 | 3 | // No regex or eval used! 4 | 5 | // Found deep integer check on Stack Overflow by Starx 6 | function isNumeric(n) { 7 | return !isNaN(parseInt(n)) && isFinite(n); 8 | } 9 | 10 | // Need one storage array for temporary consecutive digits 11 | // and another to combine those into the actual multiple-digit number they represent 12 | let digits = []; 13 | let realNumbers = []; 14 | 15 | // Loop through string 16 | for (let i = 0; i < str.length; i++) { 17 | 18 | // Readability! 19 | let char = str[i]; 20 | let nextChar = str[i+1]; 21 | 22 | // If current character is an integer, push that value to digits array 23 | if (isNumeric(char) === true) { 24 | digits.push(char); 25 | 26 | // If next character is NOT an integer, then current number is finished, 27 | // so push previously consecutive digits to realNumbers array and clear digits for next loop. 28 | if (isNumeric(nextChar) === false) { 29 | realNumbers.push(digits.join('')); 30 | digits = []; 31 | } 32 | } 33 | } 34 | 35 | // If no numbers exist in string, return 0. If numbers do exist, add 'em up! 36 | return realNumbers.length ? realNumbers.reduce(function(p, v) { return parseInt(p) + parseInt(v); }) : 0; 37 | } 38 | -------------------------------------------------------------------------------- /Medium/29: Overlapping Rectangles.js: -------------------------------------------------------------------------------- 1 | WIP 2 | 3 | function OverlappingRectangles(strArr) { 4 | 5 | function rectangleArea(strArr) { 6 | 7 | // Format points 8 | function makePoint(p) { 9 | return p.replace('(', '').replace(')', '').split(','); 10 | } 11 | 12 | // By increasing in order of x-coordinates, we know which values to subtract for width and height 13 | let sorted = strArr.sort(function(a, b) { return b[1] < a[1] }); 14 | 15 | // Create 3 coordinate points to find difference of x and y values 16 | let corner0 = makePoint(strArr[0]); 17 | let corner1 = makePoint(strArr[1]); 18 | let corner2 = makePoint(strArr[2]); 19 | 20 | // Difference of x-values yields width 21 | let width = Math.abs(corner2[0] - corner1[0]); 22 | 23 | // Difference of y-values between other two points yields height 24 | let height = Math.abs(corner1[1] - corner0[1]); 25 | 26 | // Area equals width times height 27 | return width * height; 28 | } 29 | 30 | let arr = strArr[0].split(','); 31 | let rectangle1 = []; 32 | let rectangle2 = []; 33 | 34 | for (let i = 0; i < arr.length - 1; i += 2) { 35 | let point = arr[i] + ',' + arr[i+1]; 36 | 37 | (i < arr.length / 2) ? rectangle1.push(point) : rectangle2.push(point); 38 | } 39 | 40 | let area1 = rectangleArea(rectangle1); 41 | let area2 = rectangleArea(rectangle2); 42 | 43 | return area1 44 | } 45 | 46 | console.log(OverlappingRectangles(["(0,0),(2,2),(2,0),(0,2),(1,0),(1,2),(6,0),(6,2)"])) 47 | -------------------------------------------------------------------------------- /Medium/27: Multiple Brackets.js: -------------------------------------------------------------------------------- 1 | function MultipleBrackets(str) { 2 | 3 | // Create storage and count for left brackets 4 | let leftBrackets = []; 5 | let leftCount = 0; 6 | 7 | // Loop through string 8 | for (let char of str){ 9 | 10 | // Store and count left brackets 11 | if (char === '(' || char === '[') { 12 | leftCount++; 13 | leftBrackets.push(char); 14 | 15 | // For every right parenthesis, check if left parenthesis previously existed to match. 16 | } else if (char === ')') { 17 | if (leftBrackets.includes('(') === false) { 18 | return 0; 19 | 20 | // If parentheses match, remove one left parenthesis 21 | } else { 22 | leftBrackets.splice(leftBrackets.indexOf('('), 1); 23 | } 24 | 25 | // For every right square bracket, check if left square bracket previously existed to match. 26 | } else if (char === ']') { 27 | if (leftBrackets.includes('[') === false) { 28 | return 0; 29 | 30 | // If square brackets match, remove one left square bracket 31 | } else { 32 | leftBrackets.splice(leftBrackets.indexOf('['), 1); 33 | } 34 | } 35 | } 36 | 37 | // If all pairs match, return 1 with number of pairs or just 1 if no pairs existed 38 | if (leftBrackets.length === 0) { 39 | return leftCount > 0 ? 1 + ' ' + leftCount : 1; 40 | 41 | // If extra left brackets at end of loop, then not all brackets match! 42 | } else { 43 | return 0; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Easy/21: Counting Minutes I.js: -------------------------------------------------------------------------------- 1 | function CountingMinutesI(str) { 2 | 3 | // Split into beginning and end times 4 | let times = str.split('-'); 5 | let startTime = times[0]; 6 | let endTime = times[1]; 7 | 8 | // Create function that calculates minutes from midnight for each time 9 | function minutesFromMidnight(time) { 10 | 11 | // Split by colon to access hours and minutes 12 | let split = time.split(':'); 13 | let hours = parseInt(split[0]); 14 | let minutes = parseInt(split[1]); 15 | 16 | // Calculate total minutes temporarily 17 | let totalMinutes = hours * 60 + minutes; 18 | 19 | // If midnight, subtract 720 minutes 20 | if (time.includes('a') && hours === 12) { 21 | totalMinutes -= 12 * 60; 22 | } 23 | 24 | // If pm but NOT noon, add 720 minutes 25 | if (time.includes('p') && hours !== 12) { 26 | totalMinutes += 12 * 60; 27 | } 28 | 29 | // Function returns total minutes with edge cases included 30 | return totalMinutes; 31 | } 32 | 33 | // Calculate minutes from midnight for each time 34 | let startMinutesFromMidnight = minutesFromMidnight(startTime); 35 | let endMinutesFromMidnight = minutesFromMidnight(endTime); 36 | 37 | // If ends same day, return difference 38 | if (endMinutesFromMidnight > startMinutesFromMidnight) { 39 | return endMinutesFromMidnight - startMinutesFromMidnight; 40 | 41 | // If ends next day, subtract difference from 1440 minutes (total minutes in a day) 42 | } else { 43 | return 1440 - (startMinutesFromMidnight - endMinutesFromMidnight); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Medium/15: Counting Minutes.js: -------------------------------------------------------------------------------- 1 | function CountingMinutes(str) { 2 | 3 | // Split into beginning and end times 4 | let times = str.split('-'); 5 | let startTime = times[0]; 6 | let endTime = times[1]; 7 | 8 | // Create function that calculates minutes from midnight for each time 9 | function minutesFromMidnight(time) { 10 | 11 | // Split by colon to access hours and minutes 12 | let split = time.split(':'); 13 | let hours = parseInt(split[0]); 14 | let minutes = parseInt(split[1]); 15 | 16 | // Calculate total minutes temporarily 17 | let totalMinutes = hours * 60 + minutes; 18 | 19 | // If midnight, subtract 720 minutes 20 | if (time.includes('a') && hours === 12) { 21 | totalMinutes -= 12 * 60; 22 | } 23 | 24 | // If pm but NOT noon, add 720 minutes 25 | if (time.includes('p') && hours !== 12) { 26 | totalMinutes += 12 * 60; 27 | } 28 | 29 | // Function returns total minutes with edge cases included 30 | return totalMinutes; 31 | } 32 | 33 | // Calculate minutes from midnight for each time 34 | let startMinutesFromMidnight = minutesFromMidnight(startTime); 35 | let endMinutesFromMidnight = minutesFromMidnight(endTime); 36 | 37 | // If ends same day, return difference 38 | if (endMinutesFromMidnight > startMinutesFromMidnight) { 39 | return endMinutesFromMidnight - startMinutesFromMidnight; 40 | 41 | // If ends next day, subtract difference from 1440 minutes (total minutes in a day) 42 | } else { 43 | return 1440 - (startMinutesFromMidnight - endMinutesFromMidnight); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Easy/41: Longest Increasing Sequence.js: -------------------------------------------------------------------------------- 1 | function LongestIncreasingSequence(arr) { 2 | 3 | /* 4 | * First, create a function that recursively builds increasing sequences (IS). 5 | * The first parameter, start, represents the first value of each subarray. 6 | * The second parameter, arr, represents the rest of the subarray's values. 7 | */ 8 | 9 | function findLongestFromStart(start, arr) { 10 | 11 | // When the array is emptied, return 1 as base case. 12 | if (arr.length === 0) return 1; 13 | 14 | // Build array to capture lengths of all IS. 15 | let listLength = arr.map((elem, index) => { 16 | 17 | // When we encounter a larger term, build all subarrays from that value. 18 | // Add 1 to represent increased length caused by that term. 19 | if (elem > start) { 20 | return 1 + findLongestFromStart(arr[index], arr.slice(index + 1)); 21 | } 22 | 23 | // If we encounter smaller terms, we stop their sequence at length of 1. 24 | return 1; 25 | }); 26 | 27 | // LIS of this array is represented by the max value found in listLength 28 | return Math.max(...listLength); 29 | } 30 | 31 | // Create storage for LIS of all possible IS arrays 32 | let maxLength = 0; 33 | 34 | // Now we can loop through input array to calculate length of 35 | // all possible IS and update our max length accordingly. 36 | arr.forEach((elem, index) => { 37 | let longest = findLongestFromStart(elem, arr.slice(index + 1)); 38 | if (longest > maxLength) maxLength = longest; 39 | }); 40 | 41 | // Output represents longest increasing sequence! 42 | return maxLength; 43 | } 44 | -------------------------------------------------------------------------------- /Easy/49: Product Digits.js: -------------------------------------------------------------------------------- 1 | function ProductDigits(num) { 2 | 3 | // Create function that generates list of factor pairs 4 | function factors(n) { 5 | let factors = [1]; // Always include 1. 6 | let i, j; 7 | 8 | // Determine our increment value for the loop and starting point. 9 | n % 2 === 0 ? (i = 2, j = 1) : (i = 3, j = 2); 10 | 11 | for (i; i <= Math.floor(n/2); i += j) { 12 | if (n % i === 0) { 13 | factors.push(i) 14 | } 15 | } 16 | 17 | factors.push(n); // Always include the original number. 18 | return factors; 19 | } 20 | 21 | // Generate factors for our number 22 | let factorList = factors(num); 23 | 24 | // Create storage for pair subarrays 25 | let factorPairs = []; 26 | 27 | // Factor pairs are generated from first and last factors, then moving inward and taking new first and last 28 | for (let k = 0; k < factorList.length/2; k++) { 29 | let first = factorList[k]; 30 | let last = factorList[factorList.length - 1 - k]; 31 | factorPairs.push([first, last]); 32 | } 33 | 34 | // Store smallest number of digits necessary to multiply into num 35 | let lowest = num.toString().length + 1; 36 | 37 | // Loop through factorPairs to calculate total number of digits per pair 38 | for (let m = 0; m < factorPairs.length; m++) { 39 | let digits = factorPairs[m][0].toString() + factorPairs[m][1].toString(); 40 | 41 | // The factor pair with the fewest digits should end up as lowest 42 | if (digits.length < lowest) { 43 | lowest = digits.length; 44 | } 45 | } 46 | 47 | // This represents our lowest number of product digits! 48 | return lowest; 49 | } 50 | -------------------------------------------------------------------------------- /Medium/12: Caesar Cipher.js: -------------------------------------------------------------------------------- 1 | function CaesarCipher(str,num) { 2 | 3 | // Create storage for shifted characters 4 | let answer = []; 5 | 6 | // Loop through string 7 | for (let i = 0; i < str.length; i++) { 8 | 9 | // Store unicode and shifted unicode for each character 10 | let unicode = str.charCodeAt(i); 11 | let shiftedUnicode = unicode + (num % 26); 12 | 13 | // If lowercase alphabetic character... 14 | if (unicode > 96 && unicode < 123) { 15 | 16 | //... and shifted unicode didn't pass 'z', push shifted character 17 | if (shiftedUnicode < 123) { 18 | answer.push(String.fromCharCode(shiftedUnicode)); 19 | 20 | // If passed 'z', subtract 26 to return to beginning of lowercase alphabet 21 | } else { 22 | answer.push(String.fromCharCode(shiftedUnicode - 26)); 23 | } 24 | 25 | // If uppercase alphabetic character... 26 | } else if (unicode < 91 && unicode > 64) { 27 | 28 | //... and shifted unicode didn't pass 'Z', push shifted character 29 | if (shiftedUnicode < 91) { 30 | answer.push(String.fromCharCode(shiftedUnicode)); 31 | 32 | // If passed 'Z', subtract 26 to return to beginning of uppercase alphabet 33 | } else { 34 | answer.push(String.fromCharCode(shiftedUnicode - 26)); 35 | } 36 | 37 | // For all non-alphabetic characters, simply push that value to the answer array. 38 | } else { 39 | answer.push(str[i]); 40 | } 41 | } 42 | 43 | // All alphabetic characters are now shifted by the amount requested! 44 | return answer.join(''); 45 | } 46 | -------------------------------------------------------------------------------- /Medium/23: String Reduction.js: -------------------------------------------------------------------------------- 1 | function StringReduction(str) { 2 | 3 | // Need array for native reduce method 4 | let arr = str.split(''); 5 | 6 | // Create storage for each reduction 7 | let reduced = []; 8 | 9 | // Create function that reduces depending on the values of pairs of characters 10 | function doReduce(array) { 11 | 12 | // Since we'll be reducing multiple times and appending to reduced, 13 | // we empty the array before adding newly reduced values to it 14 | reduced = []; 15 | 16 | // Reduction begins at first and second characters 17 | let reduction = array.reduce((memo, curr) => { 18 | 19 | // If different letters, combine into non-included letter from set of 'abc' 20 | if ((memo === 'a' && curr === 'b') || (memo === 'b' && curr === 'a')) { 21 | return 'c'; 22 | } else if ((memo === 'a' && curr === 'c') || (memo === 'c' && curr === 'a')) { 23 | return 'b'; 24 | } else if ((memo === 'b' && curr === 'c') || (memo === 'c' && curr === 'b')) { 25 | return 'a'; 26 | 27 | // If same letters, push one to reduced array and continue reduction 28 | } else { 29 | reduced.push(memo) 30 | return curr; 31 | } 32 | }); 33 | 34 | // Reduction always leaves one final term, which we add 35 | // to the reduced array before returning it 36 | reduced.push(reduction) 37 | return reduced; 38 | } 39 | 40 | // Perform first reduction on original array 41 | doReduce(arr); 42 | 43 | // Until all terms are the same, continue to reduce the reduced arrays 44 | while (reduced.every((val) => val === reduced[0]) === false) { 45 | doReduce(reduced); 46 | } 47 | 48 | // We now have the smallest number of characters possible through this reduction method! 49 | return reduced.length; 50 | } 51 | -------------------------------------------------------------------------------- /Easy/18: Letter Count I.js: -------------------------------------------------------------------------------- 1 | function LetterCountI(str) { 2 | 3 | // Create object to store word objects, which will contain key-value pairs of letter: count and highest: # 4 | let table = {}; 5 | 6 | // Break string into separate words 7 | let arr = str.split(' '); 8 | 9 | // Loop through words 10 | for (let i = 0; i < arr.length; i++) { 11 | let word = arr[i]; 12 | 13 | // Give each word a 'highest' property to tell us its highest letter count 14 | table[word] = {highest: 1}; 15 | 16 | // Loop through letters of each word 17 | for (let j = 0; j < word.length; j++) { 18 | let letter = word[j]; 19 | 20 | // If letter doesn't exist in word object, create it with a value of 1 21 | if (table[word][letter] === undefined) { 22 | table[word][letter] = 1; 23 | 24 | // If letter exists, add 1 to its count and update highest if this letter has the new highest count in that word 25 | } else { 26 | table[word][letter]++; 27 | if (table[word][letter] > table[word]['highest']) { 28 | table[word]['highest'] = table[word][letter]; 29 | } 30 | } 31 | } 32 | } 33 | 34 | // Create storage for word with highest count 35 | let answer = {word: null, highest: 1}; 36 | 37 | // Loop through words in table to track highest count per word 38 | for (let w in table) { 39 | 40 | // If current word's highest count is greater than the overall highest, replace highest and store associated word 41 | if (table[w]['highest'] > answer['highest']) { 42 | answer['highest'] = table[w]['highest']; 43 | answer['word'] = w; 44 | } 45 | } 46 | 47 | // If no letters repeat in any word, return -1. Otherwise, return word with the most repeated letters! 48 | return (answer['highest'] > 1) ? answer['word'] : -1; 49 | } 50 | -------------------------------------------------------------------------------- /Medium/19: Swap II.js: -------------------------------------------------------------------------------- 1 | function SwapII(str) { 2 | 3 | // A solution without regex or Unicode! 4 | 5 | // Create Boolean check for alphabetic letter 6 | function isLetter(c) { 7 | return c.toLowerCase() !== c.toUpperCase(); 8 | } 9 | 10 | // Create function to swap the case for all alphabetic letters in a word 11 | function swapCase(str) { 12 | let swapped = str.split('').map((char) => { 13 | if (char === char.toLowerCase()) { 14 | return char.toUpperCase(); 15 | } else { 16 | return char.toLowerCase(); 17 | } 18 | }); 19 | return swapped.join(''); 20 | } 21 | 22 | // Create function to swap numbers with letters between them 23 | function swapNumbers(arr) { 24 | 25 | // Loop through array of characters 26 | for (let i = 0; i < arr.length - 1; i++) { 27 | let curr = arr[i]; 28 | let next = arr[i+1]; 29 | 30 | // If current char is a number AND next char is a letter... 31 | if (!isNaN(curr) && isLetter(next)) { 32 | 33 | //... loop through rest of word beyond next letter 34 | for (let j = i+2; j < arr.length; j++) { 35 | 36 | // If we encounter another number, swap the numbers! 37 | if (!isNaN(arr[j])) { 38 | let temp = arr[i]; 39 | arr[i] = arr[j]; 40 | arr[j] = temp; 41 | } 42 | } 43 | } 44 | } 45 | 46 | // Return word with numbers swapped or, if no swap, as is 47 | return arr.join(''); 48 | } 49 | 50 | // Create storage for modified words 51 | let answer = []; 52 | 53 | // Split string to later loop through every word 54 | let arr = str.split(' '); 55 | 56 | // Loop through words to swap cases and numbers, then push to answer 57 | for (let i = 0; i < arr.length; i++) { 58 | answer.push(swapNumbers(swapCase(arr[i]).split(''))); 59 | } 60 | 61 | // Return with spaces for a successful case AND number swap! 62 | return answer.join(' '); 63 | } 64 | -------------------------------------------------------------------------------- /Medium/28: Most Free Time.js: -------------------------------------------------------------------------------- 1 | function MostFreeTime(strArr) { 2 | 3 | // Create function that calculates minutes from midnight for each time 4 | function minutesFromMidnight(time) { 5 | 6 | // Split by colon to access hours and minutes 7 | let split = time.split(':'); 8 | let hours = parseInt(split[0]); 9 | let minutes = parseInt(split[1]); 10 | 11 | // Calculate total minutes temporarily 12 | let totalMinutes = hours * 60 + minutes; 13 | 14 | // If midnight, subtract 720 minutes 15 | if (time.includes('A') && hours === 12) { 16 | totalMinutes -= 12 * 60; 17 | } 18 | 19 | // If pm but NOT noon, add 720 minutes 20 | if (time.includes('P') && hours !== 12) { 21 | totalMinutes += 12 * 60; 22 | } 23 | 24 | // Function returns total minutes with edge cases included 25 | return totalMinutes; 26 | } 27 | 28 | // Create function that converts number of minutes into hour:minute format 29 | function convertMinsToHrsMins(minutes) { 30 | let h = Math.floor(minutes / 60); 31 | let m = minutes % 60; 32 | h = h < 10 ? '0' + h : h; 33 | m = m < 10 ? '0' + m : m; 34 | return h + ':' + m; 35 | } 36 | 37 | // Create storage for each time's total minutes from midnight 38 | let minutes = []; 39 | 40 | // Loop through all time slots 41 | for (let time of strArr) { 42 | 43 | // Split each time slot into start and end times 44 | let times = time.split('-'); 45 | 46 | // Calculate minutes from midnight for each time and store in minutes array 47 | minutes.push(minutesFromMidnight(times[0]), minutesFromMidnight(times[1])); 48 | } 49 | 50 | // Sort minutes in ascending order 51 | minutes.sort((a, b) => a - b); 52 | 53 | // Create storage for length of free time intervals 54 | let freeTime = []; 55 | 56 | // Subtract each session's start time by previous session's end time to get free time 57 | minutes.forEach((startTime, index) => { 58 | if (index % 2 === 0 && index !== 0) { 59 | freeTime.push(startTime - minutes[index-1]); 60 | } 61 | }); 62 | 63 | // Find the largest amount of free time and return formatted! 64 | let mostMinutes = freeTime.reduce((p, v) => p > v ? p : v); 65 | return convertMinsToHrsMins(mostMinutes); 66 | } 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # My-Coderbyte-Solutions 2 | If you need help with Coderbyte's Easy or Medium Challenges, you've come to the right place! I've laid out all my solutions with well-commented code as a resource for any programmer to follow along. 3 | 4 | **Background** 5 | 6 | After finishing Codecademy and Code School's Javascript courses, I was disappointed that I could barely tackle the easiest Coderbyte Challenges. It turns out that most online Javascript courses are great for learning syntax, but they don't teach problem-solving skills. I hope that by sharing my solutions and thought process for each problem that you can pick up some common (and not so common!) strategies and, most importantly, understand why these strategies work. 7 | 8 | **Pro Tip** 9 | 10 | Before proceeding further on your Coderbyte journey, I highly recommend learning the native string, number and array methods ASAP. These are your basic tools in your toolbox for problem-solving. I personally created flash cards so that if given a name, I could tell you what the method does, and if given what the method does, I could tell you the name. At a minimum, this will improve your recognition of all methods, and recognition is VITAL to both navigating paths to solutions and knowing where to look when you're stuck. 11 | 12 | String methods: http://www.w3schools.com/js/js_string_methods.asp 13 | 14 | Number methods: http://www.w3schools.com/js/js_number_methods.asp 15 | 16 | Array methods: http://www.w3schools.com/js/js_array_methods.asp 17 | 18 | **Additional Pro Tips** 19 | 20 | - Get comfortable converting between the various data types. For example, you will often need to convert a number into a string with .toString(), a string into an array with .split(''), an array into a string with .join(''), and so on. 21 | 22 | - Stack Overflow is your friend! Almost any question you'll have as a beginner or intermediate programmer has already been answered there. 23 | 24 | - Strings are immutable, which means they cannot be modified as is. Arrays are mutable and can be modified in place, so you will often convert to an array to change the way a string looks. 25 | 26 | - You will often need to keep track of how many times an event occurs with a "counter" variable initialized to 0 that increases by 1 every time we satisfy a condition. We usually place it outside of loops because otherwise the counter is reset to 0 upon every loop! 27 | 28 | - Regular expressions (abbreviated as "regex" or "RegExp") show up early on in the top solutions to various problems. I've provided solutions without regex because of its complexity to learn and read. However, regex can be incredibly powerful as a search and replace tool, so if you'd like to give it a try, I recommend checking out this website: http://www.regexr.com/ 29 | 30 | **Quick Note** 31 | 32 | If you notice any ways to improve one of my solutions, feel free to message me! I'd love to chat about modifying any of my code to make it more clear, readable or efficient. 33 | 34 | Good luck on your journey, and happy coding! 35 | --------------------------------------------------------------------------------