 # freeCodeCamp Algorithm Challenge Guide: Caesars Cipher

freeCodeCamp Algorithm Challenge Guide: Caesars Cipher
0
#41

I did the exact same thing 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 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 ```
``` 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.”);