freeCodeCamp Algorithm Challenge Guide: Caesars Cipher

freeCodeCamp Algorithm Challenge Guide: Caesars Cipher
0
#41

I did the exact same thing :slight_smile:

I asked a question about going a different route than what’s suggested, I hope people respond.

Honestly I make more sense out of the solution that you and I came up with, but that’s only because the suggested methods were unfamiliar and I didn’t dive into learning about them.

Technically we’re not wrong, but I’m not sure which solution is faster / more practical (I think ours lol) / etc.

Cheers to solving it our own way :stuck_out_tongue:

2 Likes
#42

Hi, here’s my solution:

function rot13(str) { // LBH QVQ VG!
  var utf = [];
  var retour = [];
  // push unicode to utf-array
  for ( var i = 0; i < str.length; i++) {
    utf.push(str.charCodeAt(i));   
  }
  // convert utf array from ciphertext
  for (var j = 0; j < str.length; j++) {
    if(utf[j] >= 78)
      utf[j] -= 13;
    else if(utf[j] >= 65)
      utf[j] += 13;
    else
      utf[j] += 0;
    //push calculated solution to retour-array
    retour.push(String.fromCharCode(utf[j]));
  }
  return retour.join("");
}

// Change the inputs below to test
rot13("SERR PBQR PNZC");
2 Likes
#43

My current working solution. If anyone has suggestions on how I can tighten this up I would appreciate it :

function rot13(str) {
  var arr = str.split(''); 
  var unicode = [];
  var shifted = [];
 for(var i = 0; i < arr.length; i++) {
      var toUnicode = arr[i].charCodeAt(arr[i]);
      unicode.push(toUnicode);
    }
for(var j = 0; j < unicode.length; j++) {
    if(unicode[j] == 32) {
      shifted.push(unicode[j]);
    } else if(unicode[j] == 32) {
      shifted.push(unicode[j]);
    } else if(unicode[j] == 33) {
      shifted.push(unicode[j]);
    } else if(unicode[j] == 63) {
      shifted.push(unicode[j]);
    } else if(unicode[j] == 46) {
      shifted.push(unicode[j]);
    } else if (unicode[j] >= 65 && unicode[j] <= 77 ) {
        shifted.push(unicode[j] + 13);
    } else {
        shifted.push(unicode[j] - 13);
   }
  }
  var result = shifted.map(function(item) { return String.fromCharCode(item) }).join('');  

return result;

}

rot13("SERR PBQR PNZC");

1 Like
#44

This is my solution, could not find any bugs :slight_smile:


function rot13(str) { // LBH QVQ VG!
console.log(String.fromCharCode(34));
result = β€œβ€;
code = 0;
for (i=0; i<str.length; i++) {
code = str[i].charCodeAt(0);
if (code >= 65 && code <= 77) {
result += (String.fromCharCode(code+13));
} else if (code >= 78 && code <= 90) {
result += (String.fromCharCode(code-13));
} else {
result += str[i];
}
}
return result;
}

// Change the inputs below to test
rot13(β€œNF GNIR ZLYVH”);

1 Like
#45

Using replace:

function rot13(str) { // LBH QVQ VG!
 
  function replacer(match, p1) {
    var idx = match.charCodeAt(0); 
    return idx > 90 - 13 ? String.fromCharCode(idx - 26 + 13) : String.fromCharCode(idx + 13); 
  }
  return str.replace(/[A-Z]/g, replacer);
}

// Change the inputs below to test
rot13("SERR PBQR PNZC");
2 Likes
#46

I took a more β€œfun” approach to the problem; once I realised the basic algorithm behind it, I decided to write it using everyone’s favourite bit-wise conditional operator and clean it up a little.

Just to ensure no-one uses this type of approach in the workplace, I’m going to say NEVER use chains of ternary operators because it can be hard to read for other programmers & slow down your program, which in responsive JavaScript webpages or real-time systems, is bad.

2 Likes
#47

here it is with a switch statement:

function rot13(str) {
var cipher =str.split(""); //first you turn the string into an array
for (i=0;i<cipher.length;i++){ //make a for loop that runs through the whole array
switch(cipher[i]) { //you need a switch statement for every letter.
case β€œA”:
cipher[i]= β€œN”;
break;
case β€œB”:
cipher[i]= β€œO”;
break;
case β€œC”:
cipher[i]= β€œP”;
break;
case β€œD”:
cipher[i]= β€œQ”;
break;
case β€œE”:
cipher[i]= β€œR”;
break;
case β€œF”:
cipher[i]= β€œS”;
break;
case β€œG”:
cipher[i]= β€œT”;
break;
case β€œH”:
cipher[i]= β€œU”;
break;
case β€œI”:
cipher[i]= β€œV”;
break;
case β€œJ”:
cipher[i]= β€œW”;
break;
case β€œK”:
cipher[i]= β€œX”;
break;
case β€œL”:
cipher[i]= β€œY”;
break;
case β€œM”:
cipher[i]= β€œZ”;
break;
case β€œN”:
cipher[i]= β€œA”;
break;
case β€œO”:
cipher[i]= β€œB”;
break;
case β€œP”:
cipher[i]= β€œC”;
break;
case β€œQ”:
cipher[i]= β€œD”;
break;
case β€œR”:
cipher[i]= β€œE”;
break;
case β€œS”:
cipher[i]= β€œF”;
break;
case β€œT”:
cipher[i]= β€œG”;
break;
case β€œU”:
cipher[i]= β€œH”;
break;
case β€œV”:
cipher[i]= β€œI”;
break;
case β€œW”:
cipher[i]= β€œJ”;
break;
case β€œX”:
cipher[i]= β€œK”;
break;
case β€œY”:
cipher[i]= β€œL”;
break;
case β€œZ”:
cipher[i]= β€œM”;
break;
default:
cipher[i]=cipher[i]; //default (not A-Z) return same character
}

}
decoded= cipher.join(""); //now turn the array into a string
return decoded; //and there it is!
}

// Change the inputs below to test
rot13(β€œSERR PBQR PNZC”);

1 Like
#48

here it is with a switch statement:

function rot13(str) {
var cipher =str.split(""); //first you turn the string into an array
for (i=0;i<cipher.length;i++){ //make a for loop that runs through the whole array
switch(cipher[i]) { //you need a switch casefor every letter.
case β€œA”:
cipher[i]= β€œN”;
break;
case β€œB”:
cipher[i]= β€œO”;
break;
case β€œC”:
cipher[i]= β€œP”;
break;
case β€œD”:
cipher[i]= β€œQ”;
break;
case β€œE”:
cipher[i]= β€œR”;
break;
case β€œF”:
cipher[i]= β€œS”;
break;
case β€œG”:
cipher[i]= β€œT”;
break;
case β€œH”:
cipher[i]= β€œU”;
break;
case β€œI”:
cipher[i]= β€œV”;
break;
case β€œJ”:
cipher[i]= β€œW”;
break;
case β€œK”:
cipher[i]= β€œX”;
break;
case β€œL”:
cipher[i]= β€œY”;
break;
case β€œM”:
cipher[i]= β€œZ”;
break;
case β€œN”:
cipher[i]= β€œA”;
break;
case β€œO”:
cipher[i]= β€œB”;
break;
case β€œP”:
cipher[i]= β€œC”;
break;
case β€œQ”:
cipher[i]= β€œD”;
break;
case β€œR”:
cipher[i]= β€œE”;
break;
case β€œS”:
cipher[i]= β€œF”;
break;
case β€œT”:
cipher[i]= β€œG”;
break;
case β€œU”:
cipher[i]= β€œH”;
break;
case β€œV”:
cipher[i]= β€œI”;
break;
case β€œW”:
cipher[i]= β€œJ”;
break;
case β€œX”:
cipher[i]= β€œK”;
break;
case β€œY”:
cipher[i]= β€œL”;
break;
case β€œZ”:
cipher[i]= β€œM”;
break;
default:
cipher[i]=cipher[i]; //default (not A-Z) return same character
}

}
decoded= cipher.join(""); //now turn the array into a string
return decoded; //and there it is!

3 Likes
#49

hi,

I immediately thought of the function β€œreplace ()” associated with a β€œregex”. But I found it difficult to find the logic of β€œ+13” or β€œ-13” until I found a table that showed that the letters ranged from β€œA = 65” to β€œZ = 90”.

So, my solution:

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

function remplace(letter) {
var mod = letter.charCodeAt();
var plus;

if(mod > 77) {
  plus = - 13;
}

if(mod <= 77) {
   plus = + 13;
}

return String.fromCharCode(mod + plus);

}

return str.replace(/[A-Z]/g, remplace);
}

// Change the inputs below to test
rot13(β€œLBH QVQ VG!”);

#50
function rot13(str) { // LBH QVQ VG!
  var n=str.split(''),m="";
  for(var i=0;i<n.length;i++){
    var x = str.charCodeAt(i);
    if(x < 65 || x>90){
      m+=String.fromCharCode(x);
    } else if(x < 78){
      m+=String.fromCharCode(x + 13);
    } else {
      m+=String.fromCharCode(x - 13);
    }
  }
  return m;
}
#51

I did it with Regexp instead of charcode checks. Basically the same though.

  function rot13(str) {
      var uniStr = [];
      var decode = "";
      for (var i = 0; i < str.length; i++) {
        if (str[i] == str[i].match(/[a-m]/gi)) {
          uniStr.push(str.charCodeAt(i) + 13);
        } else if (str[i] == str[i].match(/[n-z]/gi)) {
          uniStr.push(str.charCodeAt(i) - 13);
        } else {
        uniStr.push(str.charCodeAt(i));
        }
      }
      for (var j = 0; j < uniStr.length; j++) {
        decode = decode.concat(String.fromCharCode(uniStr[j]));
      }
      return decode;
    }
1 Like
#52

I figured out an alternative solution for the problem :

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

var newStr = [];

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

if (str.charCodeAt(i) < 65 || str.charCodeAt(i) > 90) {
  
  newStr[i] = str[i];
  
} else  {
  
  if (str.charCodeAt(i) + 13 <= 90) {

  newStr[i] = String.fromCharCode(str.charCodeAt(i) + 13);

} else {

      newStr[i] = String.fromCharCode(str.charCodeAt(i) - 13);

}

}    

}

return newStr.join(’’);
}

// Change the inputs below to test
rot13(β€œSERR CVMMN!”);

#53

It was very hard, I needed to read and study a lot! kkkkkkkkk

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

// Change the inputs below to test
rot13(β€œSERR PBQR PNZC”);

2 Likes
#54

Hello, my solution is as follows. I have converted into an array to be able to use map first.

function rot13(str) { // LBH QVQ VG!
      return Array.prototype.map.call(str, function(x){
        return (x.charCodeAt(0) >= 65) ? 
          (x.charCodeAt(0) < 78 ) ?
            String.fromCharCode(x.charCodeAt(0)+13) : (x.charCodeAt(0) <= 90 ) ?
             String.fromCharCode(x.charCodeAt(0)-13) : x : x;
      }).join('');
      
    }

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

I am not proud of my solution at all, but it works

function rot13(str) {
  let temp = '';
  for(let i = 0; i < str.length; i++) {
    let charCodeLetter = str[i].charCodeAt();
    if(charCodeLetter < 65 || charCodeLetter > 90) {
      let encodedLetter = String.fromCharCode(charCodeLetter);
       temp += encodedLetter;
    } else {
      if(charCodeLetter > 77) {
        charCodeLetter = charCodeLetter - 13;
      } else if (charCodeLetter < 78) {
        charCodeLetter = charCodeLetter + 13;
      }
       encodedLetter = String.fromCharCode(charCodeLetter);
       temp += encodedLetter;
    }
  }
  return temp;
}
rot13("SERR YBIR?");

another solution, this time more fancy

function rot13(str) { 
  let chars = str.split('');

  return chars.map(char => {
    char = char.charCodeAt();
    
    if(char < 78 && char > 64 ) char += 13;
    else if (char < 91 && char > 77) char -= 13;
    
    return String.fromCharCode(char);
  }).join('');
}

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

hrere is my solution .

function rot13(str) {
var str1=str.split(" β€œ);
var t=[];
for(var i=0;i<str1.length;i++)
{
var r=”";
for(var j=0;j<str1[i].length;j++)
{
var c=0;
c=str1[i].charCodeAt(j);
if(c>64&&c<78)
c+=13;
else if(c>=78&&c<92)
c-=13;
r+=String.fromCharCodeΒ©;
}
t[i]=r;
}
return t.join(" ");
}
rot13(β€œGUR DHVPX OEBJA QBT WHZCRQ BIRE GUR YNML SBK.”);

#57

###here’s a refactored solution:

function rot13(str){
return str.split(’’).map(functionΒ© {
if (/[A-Z]/.testΒ©) {
return String.fromCharCode((c.charCodeAt() % 26) + 65);
} else {
return c;
}
}).join(’’);
}

#58

I annotated my code notes so its hopefully easy to understand

explanations below it

function rot13(str) {
  //Convert to array simpler to calculate no string immutability
  var newArr = str.split('');
  
  //Loop each array val apply decrypt func
  for (let i =0; i<newArr.length;i++){
    newArr[i]= shiftValues(newArr[i]);
  }
  
  //return answers
  return newArr.join('');
  
  
  //---------------------------------------
  //Decrypt function
  function shiftValues(val){
    
    //Ignore spaces
    if (val.match(/\W/i)) {
      return val;
    }

    //Define shift
    var shift=13;
    
    //Convert to ASCII values
    val=val.charCodeAt(0);

    //Equalize to base 0 index, 'A' of 65 is 0
    val=val-65;
    
    //If val-shift is negative, add 26 so it counts backwards
    if ((val-shift)>=0){
      val=val-shift;
    } else {
      val=val-shift+26;
    }
    
    //Unequalize it now
    val=val+65;
    
    //Convert to Character
    val = String.fromCharCode(val);
    
    return val;
  }
  //-------------------------------------
  
}

rot13("SERR PBQR PNZC");

brief Explanation of main program:

  • Convert to an array so its easy to work with
  • Loop through each value in array
  • Use custom function to do decrypting of each letter
  • Combine resulting array into string
  • Output results

Explanation of function: (as it loops each value in array)

  • Ignore any spaces using regex
  • Convert to ASCII number
  • Make 65 so now it index0 (A=0, B=1, C=2, D=3…Y=24, Z=25)
  • Do the decryption 13 shift more on this in a bit
  • Unmake 65 so no longer index0
  • Convert back to char
  • Send char back

explaining complicated part:

[spoiler]

Explanation of the more on this in a bit part:

I use shift = 14 as example, since its less confusing than 13 example

  • Say we have β€œL”. Its the 11th letter in alphabet (where β€œA” is 0 index)
  • Now let’s say our shift is 14.
  • 11-14 = -3. We have a negative number. Now what?
  • What value is it supposed to be?
  • Its supposed to be β€œX” , or 3 positions away from the end of alphabet,
  • X = 26-3

So we know β€œL” with a shift of 14 is supposed to be β€œX”

  • β€œX” has a value of 23.
  • β€œL” has a value of 11
  • The shift is 14

So how do you get from a value of 11 to 23?

  • 11 - 14 + ??? = 23
  • ??? is 26
  • There’s 26 letters in the alphabet

In summary;

If your going to have a negative number when you do your shift add 26. Otherwise, leave it as is

There’s other solutions around this using modulo operators %, but I didn’t use that though [/spoiler]

1 Like
#59

my solution I do not know if this is true in every case or not?

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

  var st="";
  for (var i=0;i<str.length;i++){
    
    st+=String.fromCharCode(str.charCodeAt(i)<65?str.charCodeAt(i):str.charCodeAt(i)+13>90?str.charCodeAt(i)-13:str.charCodeAt(i)+13);
  }
  return st;
}
#60

abusing map()

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

var arr = str.split(" ");

var split = arr.map(function (x){

return x.split('').map(function (y){
return y.charCodeAt(x);

});
});

var convert = split.map(function (x){
return x.map(function (y){
if (y < 65 || y > 90){
return String.fromCharCode(y);
}
else if (y < 78) {
return String.fromCharCode (y + 13);
}
else {
return String.fromCharCode (y - 13);
}

});
});

return convert.map(function (x){
return x.join(’’);
}).join(" ");

}

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