Caesars Cipher Not Behaving

Tell us what’s happening:
I think the .map method might be affecting how the charCodeAt and fromCharCode methods are behaving and I’m trying to find a solution.

The Regex doesn’t appear to be catching all letters and the 13 being added to each charcode doesn’t seem to be working as expected.

Any help would be much appreciated.

Your code so far


function rot13(str) {
  let regex = /[A-Z]/g;  
  return Array.from(str).map(letter => regex.test(letter) ?  
  String.fromCharCode(letter.charCodeAt()+13).toUpperCase() : letter).join("");
  
}

// Change the inputs below to test
console.log(rot13("SERR CVMMN!"));


Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/caesars-cipher

It’s not map nor CharCode, it’s simply the fact that you are not accounting for the “recursive” nature of the algorithm.

You don’t have to blindly add 13 to any character, but wrap them back at the beginning of the alphabet.

Let’s say I pass in the letter X.
You should account for the end of the alphabet and start again from A, when shifting by 13 positions:

X -> Y -> Z -> back to A -> B -> .... -> K

Hope it make sense :smile:

I just realized that I had an extraneous /g flag on the regex, which was causing errors. Also, I didn’t realize the DEC values for letters have some symbols between upper and lower case. That’s why I created this to blindly add 13. I’m going to try and fix this now.

was about to tell you that global flag was going to be a problem.

however, you will also need to make a choice of whether to add 13 or subtract 13.

you can also safely skip the toUpperCase() since the spec includes the following:

All letters will be uppercase.

1 Like

This was my original plan:

function rot13(str) {
  let regex1 = /[A-M]/; 
  let regex2 = /[N-Z]/; 
  return Array.from(str).map(letter => regex1.test(letter) ?  
  String.fromCharCode(letter.charCodeAt()+13).toUpperCase() : regex2.test(letter) ?
  String.fromCharCode(letter.charCodeAt()+19).toUpperCase() : letter).join("");
  }

// Change the inputs below to test
console.log(rot13("SERR CVMMN!"));

But then, after seeing rekurzion’s post. I realized that subtracting would be easier and simpler.

function rot13(str) {
  let regex1 = /[A-M]/; 
  let regex2 = /[N-Z]/; 
  return Array.from(str).map(letter => regex1.test(letter) ?  
  String.fromCharCode(letter.charCodeAt()+13) : regex2.test(letter) ?
  String.fromCharCode(letter.charCodeAt()-13) : letter).join("");
  }

// Change the inputs below to test
console.log(rot13("SERR CVMMN!"));
1 Like