Caesars Cipher Project Help

Hello, I am working through the caesars cipher project but can’t figure out how to make my code function beyond this point.

Task link: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/caesars-cipher

I have looped through the input and an array containing alphabetical characters and created a new array named numbers, this has provided an array of numbers by alphabetical order that the input string contains. I have then looped through this array applying the ROT13 requirements (if the number is <= 13 then the index has added 13, if the index is > 13 then subtracted 13 to get a new indexed value.

Now I want to loop back through the alphabet array with the new index values and get the corresponding letter at each index to decipher the input string, however, at the moment I am getting a blank array:

Output:

[ 18, 4, 17, 17, 15, 1, 16, 17, 15, 13, 25, 2 ]
[ 5, 17, 4, 4, 2, 14, 3, 4, 2, 26, 12, 15 ]
[]

Line 1 is the output after the first loop, line 2 is the output after adding or subtracting 13, and the final line should be the corresponding letter at the index in line 2 of the alphabet array but it is coming up blank.

My code so far is:

function rot13(str) { // LBH QVQ VG!

let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let alphArr = alphabet.split("");
let whitespace = /\s/g;

let newStr = str.split("");

let numbers = [];
let rotatedNum = [];
let result = [];

for(let i = 0; i < newStr.length; i++) {
  for(let j = 0; j < alphArr.length; j++) {
    if(newStr[i] === alphArr[j]) {
      numbers.push(alphArr.indexOf(alphArr[j]));
    }
  }
}

for(let e = 0; e <= numbers.length; e++) {
  if(numbers[e] <= 13) {
    rotatedNum.push(numbers[e] + 13);
  } else if(numbers[e] > 13) {
    rotatedNum.push(numbers[e] - 13);
  }
}

for(let x = 0; x <= alphArr; x++) {
  for(let y = 0; y <= rotatedNum; y++) {
    if(alphArr[x].indexOf(rotatedNum[y])) {
      result.push(alphArr[x]);
    }
  }
}

console.log(numbers);
console.log(rotatedNum);
console.log(result);


}

// Change the inputs below to test
rot13("SERR PBQR PNZC");

Thank you :slight_smile:

Your last loop has some things wrong.

alphArr & rotatedNum are not numbers and alphArr[x] is not an array…

You have all ready done most of the hard part by decoding the arrays and there is a simple method to translate what you have back to alpha… you can figure that out or go your own route :slight_smile:

There are also 2 errors that I see you running into:

  1. no whitespaces/punctuation accounted for (but you have some regex set up so i’ll assume you just working on alpha characters now)
  2. … once you get the alpha’s figured out you’ll see it. (it’s a simple fix though)

You are really close to the end! good work. But I can’t give too many hints with this being a project and all. Dont want to spoil your fun :slight_smile:

Happy coding!

1 Like

I have corrected the final loop but the output isn’t as I expected:

Final loop:

for(let x = 0; x <= alphArr.length; x++) {
  for(let y = 0; y <= rotatedNum.length; y++) {
      result.push(alphArr[rotatedNum[y]]);
  }
}

output:

[ 'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined,
  'F',
  'R',
  'E',
  'E',
  'C',
  'O',
  'D',
  'E',
  'C',
  undefined,
  'M',
  'P',
  undefined ]

Why is A showing as undefined in this case? and how can I translate this into an array.filter(), I’ve tried to do it using the loop above but doesn’t seem to work.

Task link: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/caesars-cipher

My code so far:

function rot13(str) { // LBH QVQ VG!

  let collection = [];
  let result = "";

  for(let i = 0; i <= str.length-1; i++) {
    if(str[i].charCodeAt(i) >= 65 && str[i].charCodeAt(i) <= 77) {
        result += str[i].fromCharCode(str[i].charCodeAt(i) + 13);
    } else if(str[i].charCodeAt(i) >= 66 && str[i].charCodeAt(i) <= 90) {
      result += str[i].fromCharCode(str[i].charCodeAt(i) - 13);
    }
  } 
}

// Change the inputs below to test
rot13("SERR PBQR PNZC");

Output:

TypeError: str[i].fromCharCode is not a function


I don't understand why I keep running into this problem, I've tried loops and using arrays to match characters and tried several iterations of applying charCodeAt() and fromCharCode() and I always run into this problem. Can someone please point me in the right direction, I'm obviously looking at it the wrong way but can't figure out how. 

Thanks :)

what is typeof str[i] ?

…also I am wondering why you switched directions from your last code? You were really close.

you can’t do this
look at things here:

fixed that, you will find an other issue
look up also documentation on charCodeAt

I suggest you do ample use of console.log statements

something like this: https://repl.it/@Ieahleen/AmazingQuarterlyAttributes

I’m going to go back the the code from yesterday. As you’ve figured out, the result should be “FREE CODE CAMP”

But you have an issue with the “A”

You’ve done all the work already, but there is a tiny error. (like 1 character in the wrong spot)

hint: alphabet[26] is ?

On the last strategy the loop was returning several repeated strings after decoding it and I couldn’t figure out a way to handle white spaces and symbols

You are struggling with your final loop. And this is not correct

Take a step back. What do you have at this point?

Which is 95% correct. (minus the 26).

And you know the result. What does the “5” mean to the result? And how can you get it?

Once you get “FREECODECAMP” then you will need to figure out how to ignore or pass on non Alpha characters. (you already have all of them listed in alphabet so how can you check if there is no index of a ’ ’ or ‘!’ ?)

So, I have managed to get the code to function correctly and seems to be working to all the test cases, however now I am returning the result and the test cases are still saying that they are failing, but when I console.log the result they match the test case criteria.

When returning the string:

// running tests
rot13("SERR PBQR PNZC") should decode to FREE CODE CAMP
rot13("SERR CVMMN!") should decode to FREE PIZZA!
rot13("SERR YBIR?") should decode to FREE LOVE?
rot13("GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT.") should decode to THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
// tests completed
// console output

FREE CODE CAMP
FREE LOVE?
FREE PIZZA!
FREE LOVE?
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.

New code:

function rot13(str) { // LBH QVQ VG!

  let unicodes = [];
  let result = "";

for(let i = 0; i < str.length; i++) {
  if(str.charCodeAt(i) >= 0 && str.charCodeAt(i) <= 64) {
    unicodes.push(str.charCodeAt(i));
  } else if(str.charCodeAt(i) >= 65 && str.charCodeAt(i) <= 77) {
    unicodes.push(str.charCodeAt(i) + 13);
  } else if(str.charCodeAt(i) <= 90) {
    unicodes.push(str.charCodeAt(i) - 13);
  } 
}

for(let x = 0; x <= unicodes.length; x++) {
    result += String.fromCharCode(unicodes[x]);
}
console.log(result);
return result;
}

// Change the inputs below to test
rot13("SERR PBQR PNZC");

Just to triple check, I’ve also logged the type of result which is showing as string, so it is the right data type.

Congrats on the progress!

You just have a small error that is causing issues here:

what is console.log(result.length); verse the expected result length?

1 Like

I have finally completed the challenge, has been a tough week :sweat_smile:

for(let x = 0; x < unicodes.length; x++) {
    result += String.fromCharCode(unicodes[x]);
}

The final error was that the final loop was adding a whitespace character to the end of the string so changed the iteration to < rather than <=.

Thanks for all your help guys :slight_smile:

Final solution:

function rot13(str) { // LBH QVQ VG!

  let unicodes = [];
  let result = "";

for(let i = 0; i < str.length; i++) {
  if(str.charCodeAt(i) >= 0 && str.charCodeAt(i) <= 64) {
    unicodes.push(str.charCodeAt(i));
  } else if(str.charCodeAt(i) >= 65 && str.charCodeAt(i) <= 77) {
    unicodes.push(str.charCodeAt(i) + 13);
  } else if(str.charCodeAt(i) <= 90) {
    unicodes.push(str.charCodeAt(i) - 13);
  } 
}

for(let x = 0; x < unicodes.length; x++) {
    result += String.fromCharCode(unicodes[x]);
}
//console.log(result);
return result;
}

// Change the inputs below to test
rot13("SERR PBQR PNZC");
1 Like