freeCodeCamp Algorithm Challenge Guide: Caesars Cipher

freeCodeCamp Algorithm Challenge Guide: Caesars Cipher
0

#21

I did it with OndexOf… it worked just fine.

   var abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      var answer = "";
      var a = 0;

  for(i=0;i<str.length;i++){
    if(abc.indexOf(str[i])>=0&&abc.indexOf(str[i])<=12){
      a = abc.indexOf(str[i])+13;
      answer+=abc[a];
    }
    else if(abc.indexOf(str[i])>=13&&abc.indexOf(str[i])<=25){
      a = abc.indexOf(str[i])-13;
      answer+=abc[a];
    }
    else{
      answer+=str[i];
    }
  }  
  return answer

#22

Yet another solution for your perusal

function rot13(str) { // NAFJRE GB GUR HYGVZNGR DHRFGVBA BS YVSR, GUR HAVIREFR, NAQ RIRELGUVAT
  var ALPHA='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  // split the string into array
  str = str.split('').map(function(value){
    // find the position in the alphabet
    var pos = ALPHA.indexOf(value);
    // keep the same value if a non-alpha character
    if (pos == -1) {
      return value;
    }
    // move 13 positions with wrap-around
    else {
      pos = (pos + 13) % 26;
      return ALPHA[pos];
    }
    // convert array back to a string
  }).join('');
  return str;
}

#23

This is great, seems more understandable than the "basic " solution provided above.


#24

Figured I’d add mine as it’s a little different from the above solutions:

function rot13(str) {
  // use regex to only replace A-Z
  return str.replace(/[A-Z]/g, function($) {
    // for each regex match ([A-Z]), save the charCode minus 13
    var num = $.charCodeAt()-13;
    // if the resulting charCode is less than 65 (A), minus anything less than 65 from 91 instead (90 = Z);
    if (num < 65) num = 91 + (num - 65);
    return String.fromCharCode(num);
  });
}

#25

Well not as advanced as others have done but this is what I came up with:

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

  var newString = "";
  
  for (i = 0; i < str.length; i++) {
    if (str.charCodeAt(i) >= 65 && str.charCodeAt(i) <= 90) {
      if (str.charCodeAt(i) <= 77) {
         newString += String.fromCharCode(str.charCodeAt(i) + 13);      
      } else {
         newString += String.fromCharCode(str.charCodeAt(i) - 13);  
      }  
    } else {
      newString += String.fromCharCode(str.charCodeAt(i));
    }
  }
 return newString;
}

Are there any disadvantages to this code?


#26

This is my solution. I used .match(/^[a-z0-9]+$/i) to trigger just alphabetic characters.

function rot13(str) {
  str = str.split('');
  
  for (i = 0; i < str.length; i++) {
    if (str[i].match(/^[a-z0-9]+$/i)) {
      if (str[i].charCodeAt(str[i]) + 13 > 90) {
        str[i] = str[i].charCodeAt(str[i]) - 13;
      } else {
        str[i] = str[i].charCodeAt(str[i]) + 13;
      }
    } else {
      str[i] = str[i].charCodeAt(str[i]);
    }
  }

  var newStr = '';
  for (j = 0; j < str.length; j++) {
    newStr += String.fromCharCode(str[j]);
  }

  return newStr;
}

rot13("SERR PBQR PNZC");

#27

Thanks man. It’s very helpful.


#28

The worst idea…

function rot13(str) { // LBH QVQ VG!
  var data = [["A", "N"], ["B", "O"], ["C", "P"], ["D", "Q"], ["E", "R"], 
              ["F", "S"], ["G", "T"], ["H", "U"], ["I", "V"], ["J", "W"], 
              ["K", "X"], ["L", "Y"], ["M", "Z"], ["N", "A"], ["O", "B"], 
              ["P", "C"], ["Q", "D"], ["R", "E"], ["S", "F"], ["T", "G"], 
              ["U", "H"], ["V", "I"], ["W", "J"], ["X", "K"], ["Y", "L"], 
              ["Z", "M"]];
  var arr = str.split("");
  for (var a = 0; a < arr.length; a++) {
    for (var b = 0; b < data.length; b++) {
      if (arr[a] == data[b][0]) {
        arr[a] = data[b][1];
        break;
      }
    }
  }
  return arr.join("");
}

#29

Can anyone show me how to use a switch statement for this
function . I have seen al the above awesome solutions but given the length on many…perhaps a switch is not too far fetched?

rot13(str) {
var code = “”;

switch {switch (str) {
case ‘A’:
answer = “N”;
break;
case 'B:
answer = ‘O’;
break;
// and so on
}
return str;
}


#30

Here is my solution:

function rot13(str) {
  // LBH QVQ VG!
  var convertStr = [];
  var str1;
  for(i = 0; i < str.length; i++) {
   
   str1 = str.charCodeAt(i);
    if (str1 >= 65 && str1 <= 77 ) {
      convertStr.push(String.fromCharCode(str1 + 13));
      
    }
    else if (str1 >= 78 && str1 <= 90 ) {
      convertStr.push(String.fromCharCode(str1 - 13));
      
    }
    else  {
      convertStr.push(String.fromCharCode(str1));
      
      
    }
    
  }

  return convertStr.join("");
}

After getting frustrated with the fact that I had to keep looking up solutions to some of the other challenges(do, I think, to not fully understanding some of the other challenges despite completing them) I read a few JS books, watched some videos, and did some other tutorials online to fill in the gaps in my learning.
I completed this one without looking up any solutions! I use codepen now to mess with my code as I solve the challenges and it’s made a huge difference. I look forward to working through the other challenges, and solving the old ones with more advanced techniques.


#31

Just to share a slightly different solution:

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

  var newString = "";
  function charCheck(char){
    if (char < 65){
      return char;
    } else {
      return char % 26 + 65;
    }
  }
  for(var i = 0; i < str.length; i++){
    var x = str.charCodeAt(i);
    newString += String.fromCharCode(charCheck(x));
  }
  return newString;
}

#32

Here’s my code. Interesting how it can be achieved so many different ways. This took me quite some time to figure out as I wasn’t able to pass the array to the fromCharCode() function.

  var arr = str.split('');
  var newArray = [];
  var cipheredCode = '';
  
  for(i = 0; i < arr.length; i++){
    if(arr[i].charCodeAt() > 64 && arr[i].charCodeAt() < 78 ) {
      newArray.push(arr[i].charCodeAt() + 13);
    } 
    if (arr[i].charCodeAt() > 77 && arr[i].charCodeAt() < 91 ) {
      newArray.push(arr[i].charCodeAt() - 13);
    } 
    if(arr[i].charCodeAt() < 64){
      newArray.push(arr[i].charCodeAt());
    }
  }
  
    cipheredCode += String.fromCharCode.apply(null, newArray);
       
    return cipheredCode;
}

#33

Passed it with that :

function rot13(str) { // LBH QVQ VG!
  var alpha = "abcdefghijklmnopqrstuvwxyzabcdefghijklm".toUpperCase().split(''),
      // Making an array of each letters to decode
      splited = str.split(''),
      // Spliting the string in argument of rot13
      uncoded = [];
  
  
   // --- Test Code --- //  index = alpha.indexOf(splited[3]);
  
  
      for (var i = 0; i < str.length; i++){
        var index = alpha.indexOf(splited[i]);
        // It is the index of the char to decode
        if(index !== -1){
        uncoded.push(alpha[index+13]);
          
          // If index is not -1 (meaning it's in array) we push the letter from alpha + 13
        }
        if (index === -1){
          uncoded.push(splited[i]);
          
          // If index is -1 (meaning it's not in array) we push the letter from the string instead
        }
    
  }
  
  
// --- Test Code --- //  return alpha[index+13];
  return uncoded.join('');

// Then join the array to return sentences decoded

  
 
}

// Change the inputs below to test
rot13("GUR DHVPX OEBJA QBT WHZCRQ BIRE GUR YNML SBK.");

#34

That’s great, Now I just have to copy and paste one of these solutions, Because I didn’t understand a thing about this Cesar thing.


#35

Thanks dude. Your appreciation means a lot.


#36

I know my reply is late here, but I originally thought of a similar idea, by building an array with the alphabet in order, like ["A", "B", "C", "D" ...] and then comparing to that. It would solve the problem without using the unicode methods, but decided it wouldn’t save any time. I ended up using .fromCharCode() & .charCodeAt() methods like everyone else.


#37

This was my solution! It passed all of the freeCodeCamp tests.

function rot13(str) {
  var string = "";

  for (var i = 0; i < str.length; i++){
    var char = str[i];
    var code = char.charCodeAt(0);

    if ( char.match(/[A-Z]/) ){
      if ( code > 77 ){
        char = String.fromCharCode( code - 13 );
      }else{
        char = String.fromCharCode( code + 13 );
      }
  
    }

    string += char;

  }

  return string;
}

#38

My solution was diferent, but i did it quick:

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

var alphabet0 = 'ABCDEFGHIJKLM'.split('');
var alphabet1 = 'NOPQRSTUVWXYZ'.split('');
var decoded = [];
var index = 0;

// iterate on the str  
for (i = 0; i < str.length; i++) {

    // get the index of the str on the alphabet0  
    index = alphabet0.indexOf(str[i]);

    // if the index >= 0 push it to decode from alphabet 1
    if (index >= 0) {
        decoded.push(alphabet1[index]);

        // else get the index from alphabeth1 and push from alphabet0    
    } else {
        index = alphabet1.indexOf(str[i]);

        // if its a space or symbol, push it
        if (alphabet1[index] === undefined) {
            decoded.push(str[i]);                
        }
        decoded.push(alphabet0[index]);
    }
}
return decoded.join('');

}

rot13(“SERR CVMMN!”);

is it wrong?


#39

A few-line solution:

function rot13(str) { // LBH QVQ VG!
  'esversion: 6';
  return str.split("").map(encodedChar => {
    if (encodedChar.match(/[A-Z]/)) {
      return (encodedChar.charCodeAt() - 13 >= 65) ? String.fromCharCode(encodedChar.charCodeAt() - 13) : String.fromCharCode(encodedChar.charCodeAt() + 13);  
    }
    return encodedChar;
    
  }).join("");
}

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

#40

So my solution just uses one loop and one if statement, wondering if I could get some feedback…

function rot13(str) { // LBH QVQ VG!
  var alphaPt1 = "ABCDEFGHIJKLM".split(""); 
  var alphaPt2 = "NOPQRSTUVWXYZ".split(""); 
  var strArr= str.split("");
  var newArr = [];
  
  for (var i =0; i< strArr.length; i++){
    if (alphaPt1.includes(strArr[i])){
      var index = alphaPt1.indexOf(strArr[i]);
      newArr.push(alphaPt2[index]);
    } else if (alphaPt2.includes(strArr[i])){
      var index = alphaPt2.indexOf(strArr[i]);
      newArr.push(alphaPt1[index]);
    } else {
      newArr.push(strArr[i]);
    }
  }
  return newArr.join("");
}

My solution passed all the tests which made me happy! I didn’t use the suggested methods however. I took a look at the docs and honestly I just thought I’d be able to solve without them… which I did :stuck_out_tongue:

So, what are people’s thoughts on this way of thinking? Obviously there are multiple solutions that people can come up with… and it was suggested we use the given methods but I felt more comfortable with my own solution than what I read here. There’s always more learning to be done :slight_smile: