# 9.20 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=""
//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("") != 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.
*/```

This site uses Akismet to reduce spam. Learn how your comment data is processed.