Caesars Cipher - other approaches?

Caesars Cipher - other approaches?
0
#12

Hey guys, just wanted to show my solution, I think it’s pretty simple and does the job! Hopefully some of you might find it useful.

function rot13(str) {
  var resp = [];
  var code = str.split('');
 
  for(var i=0;i<code.length;i++){
      var index = code[i].charCodeAt();
    
      if(index>77){
             resp.push(String.fromCharCode(index-13));
      }  else if(index<=77&&index>=65){
             resp.push(String.fromCharCode(index+13));
         }else if(index<65){
             resp.push(String.fromCharCode(index));
          }
  }      
        return resp.join('');
}

Cheers!

2 Likes

#13

Here is my code as well; definitely need to work on regex. It would have made this a whole lot simpler like the example way above ^^

function rot13(str) { // LBH QVQ VG!
  var arr = [];
  var newString = '';
  for (var i = 0; i<str.length; i++){
      var val = str.charCodeAt(i);
    if (val >= 65 && val <= 90 ){
        if (val < 78){
          val += 13;
          var hold = String.fromCharCode(val);
          newString += hold; 
          }
        else if (val >= 78) {
          val -= 13;
          var holdE = String.fromCharCode(val);
          newString += holdE;
          }
     }
    else{
      newString += str[i];
     }
  }
   return newString;
}
0 Likes

#14

Well, it took a long time to write this code without any hints. It may look quite dirty, but works perfectly. :heart_eyes:

function rot13(str) {
 var myStr = "";
 var charNum = 0;
  var arr = str.split(" ");

    for(j=0;j<arr.length;j++){
    var word = arr[j];
    var empcon = "";
     
        for(i=0;i<word.length;i++){         
        var new_sym ='';
        charNum = word.charCodeAt(i);

              if(charNum < 65 || charNum >90){
                new_sym = String.fromCharCode(charNum);
              }
              else if (charNum+13<=90){
              new_sym = String.fromCharCode(charNum+13);
              }else if(charNum+13>90){
              new_sym = String.fromCharCode(64 + (charNum+13-90));
              }
          
          empcon += new_sym ;
         }
     myStr += empcon + " ";
    }

return myStr.replace(/\s*$/,'');
} 

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

#15

Here is mine in repl.it

0 Likes

#16

Here is mine. It’s not pretty but I think it may be fairly legible to people with basic knowledge.


function rot13(str) { // LBH QVQ VG!
  
  var regEx = /[A-M]/;
  var regEx2 = /[N-Z]/;
  var holder = [];
  
   for (var i = 0; i < str.length; i++) { 
      if (regEx.test(str[i])) {           //test if str[i] is A-M
        holder[i] = str.charCodeAt(i)+13; //if true, push ASCII+13 to holder
      } else if (regEx2.test(str[i])) {   //test if str[i] is N-Z
        holder[i] = str.charCodeAt(i)-13; //if true, push ASCII-13 to holder
      } else if (!regEx.test(str[i]) && !regEx2.test(str[i])) { //test if str[i] is neither A-M nor N-Z, i.e non-alphabetic
        holder[i] = str.charCodeAt(i); //if true, push to holder as is
      }
     } return String.fromCharCode.apply(null, holder); //return holder array as string by using .apply method
  
}

// Change the inputs below to test
rot13("FREE PIZZA!");

0 Likes

#17

I had to take a break from this one, disappointing being right at the end of those challenges. When I came back to it though, it was really fun to work through. I used a fairly simple solution without RegEx though:

function rot13(str) { // LBH QVQ VG!
  var tst = []; var i = 0;            // tst is array of inputs, i is iteration through strings
  var arr = [];                       // arr is array to return(?), l is length of strings to find
  ////////////////////////////////////////////////////////////////////////////////////////////////
  
  tst = str.split('');              // split string into array of strings no seperator counts each
                                    // element  
  
  function change(num) {                // function to get unicode of decoded letter
    if ((num > 90) || (num < 65)) { return num; }    // leave alone if not capital letter
    else if ((num + 13) > 90) {         // subtract if adding goes beyond Z
         return num - 13;
       }
    else return num + 13;               
  }
  
  while ( i < tst.length ) {            // iterate through array of strings to find uni vals
    var word = tst[i]; var uni = [];    // word is current string, uni is temp array of unicode
    var dec = [];                       // dec is array (yes another) to decypher unicode vals
      for ( var n=0; n < word.length; n++) {
        uni.push(word.charCodeAt(n));        // get array of unicode for decyphering
      }
    for (var p= 0; p< uni.length; p++) {    // loop through cyphered unicode
      dec.push(change(uni[p]));             // using change function, find decyphered unicode values
      arr.push(String.fromCharCode(dec[p]));  // create array of letters from decyphered unicode
      }
    i++;
  }
  /*x = arr.toString(); var re = (/,/g);
  x = x.replace(re, " ");*/
  //return String.fromCharCode(91);            //testing
  
  return arr.join('');                         // join to string (remove commas with (''))
  
}

// Change the inputs below to test              A=65, Z=90
rot13("XYNGH ORENGN AVXGH!");

I also find it fun to comment the crap out of challenges I finished afterward (can ya tell?)

TL;DR - Basically I made a function to translate unicode into letters and told it to leave anything that wasn’t a capital letter alone, that way I didn’t have to worry about putting spaces and exclamations back in. I’m happy with how it turned out.

0 Likes

#18

Hey Campers!

I thought it’d be nice to share my solution with ya’ll. I took a simpler approach in solving this. I’m open for suggestions. Thanks!


function rot13(str) { // LBH QVQ VG!
  var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  str = str.split('');
  var res = '';

  for (var i = 0; i < str.length; i++) {
    if (alphabet.indexOf(str[i]) !== -1) {     // if letter exists in alphabet do the following
      if (alphabet.indexOf(str[i]) < 13) {      // if letter is positioned before the first 13 characters
        res += String.fromCharCode(str[i].charCodeAt(0) + 13);  // decode letter by adding 13 more ie 'E'->'R'
      } else {
        res += String.fromCharCode(str[i].charCodeAt(0) - 13); // if not, decode letter by subtracting 13 letter ie 'S'->'F'
      }
    } else {
      res += str[i];       // if character is not part of alphabet, simply append to solution string
    }
  }
  
  return res;
} 

// Change the inputs below to test
rot13("SERR PBQR PNZC");
// console.log(rot13("LBH QVQ VG!"));

Happy Coding~

0 Likes

#19

what is the test method ?

0 Likes

#20

Another nice thing about @joesmith100’s solution: you can make it case-insensitive by just adding i flags to both the regexes:

Spoiler
  return str.replace(/[A-Z]/ig, function(c) { 
    return String.fromCharCode(c.charCodeAt() + (/[A-M]/i.test(c) ? 13 : -13));
  });
}

rot13("serr PBQR PNZC");
1 Like

split this topic #21

A post was split to a new topic: Caesars Cipher questions

0 Likes

#22

@joesmith100

Creative, never would of thought of that.

0 Likes

#23

Hi Everyone,

So I just finished Caesars Cipher. Mine was much different from the solutions provided in the guide, so I thought I would post it here to get some feedback. Let me know what you think. Thanks!

function rot13(str) { // LBH QVQ VG!
  var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  var cipher = "NOPQRSTUVWXYZABCDEFGHIJKLM";
  
  var replacer = [];
  for (var x = 0; x < str.length; x++)  { //loops through the given string
  var index = alphabet.indexOf(str[x]);  //sets the index of letter from the coded string
  if (cipher.charCodeAt(index) > 0) {  //check to see if the letter is alphanumeric
     replacer.push(String.fromCharCode(cipher.charCodeAt(index))); //add to array
  }
    else replacer.push(str[x]); //adds non-alphanumeric to the array
  }
  return replacer.join(""); //combines it all back together
}

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

0 Likes

#24

This is my solution. Someday maybe I’ll be able to made more efficient code. :frowning:

function rot13(str) { // LBH QVQ VG!
  
  var finish = str.length;
  var result = "";
  var letterA;
  var letterB;
 
  for (i = 0; i < finish; i++) {
    
    letterA = (str.charCodeAt(i));
    
    if (letterA >= 78 & letterA <= 90) {
      letterA = letterA - 13;
      letterB = String.fromCharCode(letterA);
      result = result + letterB;
    }
    else if (letterA >= 65 & letterA < 78) {
      letterA = letterA + 13;
      letterB = String.fromCharCode(letterA);
      result = result + letterB;
    }
    else if (letterA >= 32 & letterA <= 64) {
      letterA = letterA;
      letterB = String.fromCharCode(letterA);
      result = result + letterB;
    }
  }
  
  
  return result;
}

// Change the inputs below to test
rot13("LBH QVQ VG!");
0 Likes

#25

My code is very similar to yours, as all beginners are since we only know if statements.

I have seen 3 line solutions which i don’t understand:

–> freeCodeCamp Algorithm Challenge Guide: Caesars Cipher

function rot13(str) { // LBH QVQ VG!
  return str.replace(/[A-Z]/g, L => String.fromCharCode((L.charCodeAt(0) % 26) + 65));
}
2 Likes

#26

I studied this. They are the Arrow functions: MDN

But I need more practice. The % 26 is very clever!

0 Likes

#27

here is mine :slightly_smiling_face:

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

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

if (str.charCodeAt(i) >= 65 && str.charCodeAt(i)+13 <= 90) {
  newstrarray = newstrarray + String.fromCharCode(str.charCodeAt(i)+13);
}
  else if (str.charCodeAt(i)+13 > 90) {
    var newchar = str.charCodeAt(i)+13 - 90 + 64;
    newstrarray = newstrarray + String.fromCharCode(newchar);
  }
  else {
    newstrarray = newstrarray + str[i];
  }

}

str = newstrarray;
return str;
}

0 Likes

#28

Here is my solution. I’m not using charCodeAt. Nevertheless it seems to work for the assertions of FCC.

Any tips?

function rot13(str) {

  var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  var result = "";

  function shift(letter) {
    var shiftNum = 13;
    var index = alphabet.indexOf(letter);
    if (index >= shiftNum) {
     return alphabet[index - shiftNum];
    } else if (index < shiftNum) {
      return alphabet[index - shiftNum + alphabet.length];
    }
  }

  for (let i = 0; i < str.length; i++) {
    if (str[i].match(/\w/)) {
        result = result.concat(
            shift(str[i])
            );
    } else if (str[i].match(/\s/) || str[i].match(/\W/)) {
      result = result.concat(str[i]);
    }
  }
  return result;
}

0 Likes

#29

If you’re going to do it that way and define the alphabet, why not define the alphabet after it’s been transformed as well (var rot13alphabet = "NOPQRSTUVWXYZAB..."), which gets rid of the first block of logic?

Check the index of the current character in the real alphabet. If the index is -1, ie it isn’t there (eg, it’s a space), just add that character to result. If it is there, add the character in the rot13 alphabet to result. Then no need for regex either (or character codes).

0 Likes

#30

Good point, thanks for taking your time to review my code!

0 Likes

closed #31
0 Likes