Caesars Cipher challenge [SOLVED]

I can’t see what the char methods to transform from/to ASCII has to do with rotating the char positions. I’m just stuck on that to begin with. Why’s important? I mean. Why do I have to do that in the first place?

Thank you for your answer. Still, the instructions are confusing to me, and I quote:

One of the simplest and most widely known ciphers is a Caesar cipher, also known as a shift cipher. In a shift cipher the meanings of the letters are shifted by some set amount.

A common modern use is the ROT13 cipher, where the values of the letters are shifted by 13 places. Thus ‘A’ ↔ ‘N’, ‘B’ ↔ ‘O’ and so on.

Write a function which takes a ROT13 encoded string as input and returns a decoded string.

All letters will be uppercase. Do not transform any non-alphabetic character (i.e. spaces, punctuation), but do pass them on.

And then, you have to dig into this:

Here are some helpful links:

String.prototype.charCodeAt()
String.fromCharCode()

Seriously? I study those methods and I realize- what they’re good for in this challenge? So, I get stuck. I press the “emergency” Get a hint button, which tells me this:

Use String.charCodeAt() to convert the English character to ASCII.

Use String.fromCharCode() to convert ASCII to English character.

Leave anything that doesn’t come between A-Z as it is.

Which is of no help to me, hence this post. And although, I appreciate your answer, the truth is that it confuses me even more (I’m sorry). Because, somehow, I see that none of the above is useful. So, how shall I continue?

And before you ask me about the written in natural language the algorithm, let me answer that it should be pretty straight forward: I’ve to rotate each character 13 positions. So, again, what the charCodeAt and fromCharCode methods has to do with that?

Needless to say, your didactic ways helped me.
I’ve got it. I’m just struggling with the spaces for the time being.
Thank you.

I’m here:

function rot13(str) {
  
  var arr=str.split("");
 
  var arr1=[];
  var arr2=[];
 
  for (i=0;i<arr.length;i++){    
   
   var item=arr[i];
   
   if (item.match(/[A-Z]/)) {   
   
     if ( item.charCodeAt() >=65 && item.charCodeAt() <=77 ) {
    
       arr1.push(item.charCodeAt()+13);
    
      }
      else {
            
        arr1.push(item.charCodeAt()-13);
      }
  }
  }
 
 for (j=0;j<arr1.length;j++){
 
   var item2=arr1[j];
   arr2.push(String.fromCharCode(item2));
 
 }
 
 var test=arr2.join("");
  return test;
}

But this returns some ascii as spaces, so, it doesn’t validate.

I was thinking in splitting the array on each word, then split again, and create new arrays as much words as were split? Sounds too convoluted.

Of course.
Your suggestions made the code cleaner and, the missing else did the trick. Really appreciated.

Of course I’m interested. But I feel kind of embarrassed for receiving so much help. Also, is not like cheating if I don’t realize myself of the lacking and improving details?

function rot13(str) { 
   
  var arr=str.split("");
 
  var arr1=[];
  var arr2=[]; 
 
  for (i=0;i<arr.length;i++){    
   
   var item=arr[i];
   var ascii=item.charCodeAt();
   
   if (item.match(/[A-Z]/)) {   
   
     if ( ascii >=65 && ascii <=77 ) {
    
       ascii += 13;
    
      }
      else {
            
        ascii -= 13;
      }
    
    arr1.push(ascii);
  }
   else {
   
   arr1.push(item.charCodeAt());
  }
   
  } 
 
 for (j=0;j<arr1.length;j++){
 
   var item2=arr1[j];
   arr2.push(String.fromCharCode(item2));
 
 }
 
 var test=arr2.join("");
  
return test;

I only helped explain how to use some functions and gave you a basic algorithm. The rest you came up with on your (minus the else statement suggestion). The whole point is you solved the challenge without someone just writing all the code out for you.

Now, since you have solved the problem, any advice I or anyone gives you on your solution is just extra learning you can store away in your brain for a later challenge.

OK, now for some solution suggestions. Since you already have the line:

var ascii=item.charCodeAt();

you really don’t need the following else (I suggested)

   else {
   
   arr1.push(item.charCodeAt());
  }

as long as you move the arr1.push(ascii); line outside of the if (item.match(/[A-Z]/)) { code block. Currently, it is on the last line of the true block.

Also, the following code:

 for (j=0;j<arr1.length;j++){
   var item2=arr1[j];
   arr2.push(String.fromCharCode(item2)); 
 }

creates an extra iteration of the arr1, when this can all be handled on a line right before the arr1.push(ascii); Create another variable (i.e. converted) and assign String.fromCharcode(ascii) to it.Then you would use arr1.push(converted) and avoid the extra for loop (an increase in efficiency).

Finally, instead of returning a joined version of arr2, you could simply write:

return arr1.join(""); // putting the join within the return statement avoids using the test variable.
2 Likes

Thank you. That indeed cleaned even more. I’m the master of redundancy.
Well, I left a couple of challenges behind that I got stuck. I’ll get back to them.

You’re a great asset to this commnity.

1 Like