I did 2.5h today of the free code camp final Javascript Algorithms And Data Structures Certification projects. I only have one left! They went better than yesterday, I am proud to report. I used .exec with regex for the first time to return the index of the find, and I also worked on doing optional regex patterns.
Roman Numeral Generator
function convertToRoman(num) { /* strategy find roman numerals rules use mod operator to find remainder make array with key val pairs loop through numerals in decreasing order read number left to right, slicing it to even places (ie 12453 -> 10000, 2000, 400, 50, 3) if num = numeral num -= numeral str += array[numeral] else return the low=(num >numeral) and the high(num >numeral) take the absval of the numeral before and after num >=numeral if the new number is greater than halfway, make it as subtractor in front of the high else num -= high str += array[high] */ let valArray =[1,4,5,9,10,40,50,90,100,400,500,900,1000] let valHash={1:"I",4:"IV",5:"V",9:"IX",10:"X",40:"XL",50:"L",90:"XC",100:"C",400:"CD",500:"D",900:"CM",1000:"M"} let str="" //add smaller thing first. add str to newStr but don't add to str. add to num //then subtract big thing. add str to newStr. add to str. subtract lookup from num //if counting up //this part is below for (let i=valArray.length-1;i>=0;i--){ CountUp(i) } function CountUp(i){ while (num>=valArray[i]){ console.log(num+" "+str) num-=valArray[i] str+=valHash[valArray[i]] } } console.log(str) return(str) } // convertToRoman(9); convertToRoman(97) //should return "XCVII" // convertToRoman(99) //should return "XCIX" // convertToRoman(400) //should return "CD" // convertToRoman(798) //should return "DCCXCVIII" // convertToRoman(891) //should return "DCCCXCI" // convertToRoman(3999) //should return "MMMCMXCIX" /* things I learned .repeat() is useful! I totally overthought this. I ended up having to look at a hint, and I was using way, way too much logic. Putting the few weird values like 4,9,40 into the dict was the easy answer. It worked too. */ Caesars cipher function rot13(str) { // LBH QVQ VG! /* strategy find the char codes for uppercase numbers. make a function to offset the numbers by 13. if they are over the Z char, then subtract 26 from it split string to array modify array in place if char code >14th char and <26th char, subtract 13 from it else if char code <14th char and >1st char add 13 to it. else do nothing join array */ str=str.split('') for (let i=0;i<str.length;i++){ if ((str[i].charCodeAt(0)>=65) && (str[i].charCodeAt(0)<=77)){ str[i]=String.fromCharCode(str[i].charCodeAt(0)+13) } else if ((str[i].charCodeAt(0)>77) && (str[i].charCodeAt(0)<=90)){ str[i]=String.fromCharCode(str[i].charCodeAt(0)-13) } } console.log(str.length) str=str.join('') console.log(str) return str; } //65-90 // Change the inputs below to test // rot13("A"); rot13("SERR PBQR PNZC"); /* lessons learned. This was way less of a struggle than the roman numeral one. it was far easier conceptually. the string splitting and joining came easily. I found that I could either add or subtract 13 based on position in the alphabet, which simplified things. after I found the pos in the alphabet I can also filter out non uppercase easily. */
Caesars cipher
function rot13(str) { // LBH QVQ VG! /* strategy find the char codes for uppercase numbers. make a function to offset the numbers by 13. if they are over the Z char, then subtract 26 from it split string to array modify array in place if char code >14th char and <26th char, subtract 13 from it else if char code <14th char and >1st char add 13 to it. else do nothing join array */ str=str.split('') for (let i=0;i<str.length;i++){ if ((str[i].charCodeAt(0)>=65) && (str[i].charCodeAt(0)<=77)){ str[i]=String.fromCharCode(str[i].charCodeAt(0)+13) } else if ((str[i].charCodeAt(0)>77) && (str[i].charCodeAt(0)<=90)){ str[i]=String.fromCharCode(str[i].charCodeAt(0)-13) } } console.log(str.length) str=str.join('') console.log(str) return str; } //65-90 // Change the inputs below to test // rot13("A"); rot13("SERR PBQR PNZC"); /* lessons learned. This was way less of a struggle than the roman numeral one. it was far easier conceptually. the string splitting and joining came easily. I found that I could either add or subtract 13 based on position in the alphabet, which simplified things. after I found the pos in the alphabet I can also filter out non uppercase easily. */
Telephone Number validator
telephone number validator function telephoneCheck(str) { // Good luck /* strategy regex, a lot of regex try to make some non regex rules like number of numbers=10 or 11 if #numbers==11 then 0 needs to be a one optional 1 / optional paren and or space / three digits / optional paren space and or hyphen / three digits /optional paren space and or hyphen / four digits */ let regexB=/^[0-9(]/g; if (regexB.test(str) != true){ return false } let regexA=/[0-9]*/g; console.log(str.match(regexA).join("").length) let numLength=str.match(regexA).join("").length if (numLength<10 | numLength>11){ console.log('wrong length') return false } if (numLength==11){ if (str.match(regexA).join("")[0] != 1){ console.log('not a 1') return false } } var openParen = /\(/.exec(str); if ((openParen) && (str[openParen.index+4]!=")")) { console.log(openParen.index); console.log('missing a paren') return false } var closeParen = /\)/.exec(str); if ((closeParen) && (str[closeParen.index-4]!="(")) { console.log(closeParen.index); console.log('missing a paren') return false } let regex=/1?\s?\(?[0-9]{3}\)?\s?-?[0-9]{3}-?\s?[0-9]{4}$/; console.log(regex.test(str)) return regex.test(str); } // telephoneCheck("1 (456 789 4444") telephoneCheck("(555)555-5555") // telephoneCheck("-0 (757) 622-7382") // telephoneCheck("555-555-5555"); // telephoneCheck("1 555-555-5555") //should return true. // telephoneCheck("1 (555) 555-5555") //should return true. // telephoneCheck("1(555)555-5555") //should return true. // telephoneCheck("1 555 555 5555") //should return true. // telephoneCheck("1 456 789 4444") //should return true. // telephoneCheck("555)-555-5555") //should return false. // telephoneCheck("(555-555-5555") //should return false. /* what I learned I used .exec with regex for the first time to return the index of the find I worked on my optional regex terms, and I worked on making my rules fit together so there are as few as possible, but they cover as many cases as possible. */