Caesars Cipher using nested for loop

Hi, why wont my function below return white space and other non-alpha numeric characters from input?

function rot13(str) {
  let outPut = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
// return inPut

let inPut = ["N","O","P","Q","R","S","T","U","V","W","X","Y","Z","A","B","C","D","E","F","G","H","I","J","K","L","M","n","o","p","q","r","s","t","u","v","w","x","y","z","a","b","c","d","e","f","g","h","i","j","k","l","m"];
// return  outPut
// return str;

let arr3 = [];

let arr = [...str.toLowerCase().toUpperCase().replace(/\s+/g, "_")];
// return arr;

for (let k=0; k < arr.length; k++){
  for (let j=0; j < inPut.length; j++){
    for (let i=0; i < outPut.length; i++){

    if ((arr[k] === inPut[j]) && (arr[k] !== /\W/g)){
      let replacer = outPut[j][i];
      arr3.push(replacer)
    }
    
    // replace underscore with white space
    else if((arr[k] !== inPut[j]) && (arr[k] === /\s+/g)){
      arr3.push(arr[k].replace("_", /\s+/g))
      }
    // push non-alpha numeric to array
    else if((arr[k] !== inPut[j]) && (arr[k] === /[^A-Za-z0-9]/g)){
      arr3.push(arr[k])
      }
    }

  }

}

// return arr3;
return arr3.join("");
}

console.log(rot13("SERR PBQR PNZC")); 
console.log(rot13("SERR CVMMN!")); 
console.log(rot13("SERR YBIR?")); 
console.log(rot13("GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT."));

The main logic is simply to go through the input string character by character. If the character is alphabet, add an encoded character to the answer string. If the character is not alphabet, then add the character to the answer array. There’s only one loop. Depending on how you implement the encoding, you might have another loop, but you want to do that is a separate helper function. Here’s a pseudo code.

str = str.toUpperCase();
let answer = "";

for each character ch in str {
   if ch is alphabet {
      answer += encode(ch);
   } else {
      answer += ch;  //non-alpha so pass it through to the answer
   }
}

I don’t see why the logic of trying to convert space to underscore and trying to convert it back to space.

hi there,

Instead of using a regex, you may try thinking of another way like:

  1. first, why not create a single ‘rotArray’ composed of (length: 26 x 2) uppercase alphabetic characters; use it as your ‘rot13’ decoder;

  2. think of splitting the given ‘str’ so you can iterate through each substring characters in the ‘rawStringArray’;

  3. then, use the ‘array.indexof()’; if 'searchIndex >= 0, add 13 to it to get the decoded character;

  4. about the punctuations or any other non-alphabetic characters, ‘indexof()’ will return a (-1) based on the ‘rotArray’ ; in that case , just slide it to your ‘decodedArray’;

  5. then, think of using ‘join()’ on the ‘decodedArray’ to create a ‘newString’;

  6. this time, think of pushing the decoded substring ‘newString’ to a ‘newStringArray’; do this until the entire ‘rawStringArray’ has been iterated through;

  7. finally, you may think of joining the ‘newStringArray’ to see your final decoded string.

Happy coding!

Thanks both of you for presenting alternatives to answer the question. Reading your suggestions reminded me that I just needed to include a filter in the nested loop to decode only alpha-numeric characters and pass non-alpha numeric characters.

function rot13(str) {
let outPut = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
// return inPut

let inPut = ["N","O","P","Q","R","S","T","U","V","W","X","Y","Z","A","B","C","D","E","F","G","H","I","J","K","L","M","n","o","p","q","r","s","t","u","v","w","x","y","z","a","b","c","d","e","f","g","h","i","j","k","l","m"];
// return  outPut
// return str;

let arr3 = [];

let arr = [...str.toLowerCase().toUpperCase().replace(/\s+/g, "_")];
// return arr;

for (let k=0; k < arr.length; k++){
  if (arr[k].match(/[A-Za-z0-9]/gi)){
    // return arr3.push(arr[k])
  for (let j=0; j < inPut.length; j++){
    for (let i=0; i < outPut.length; i++){
      // return arr3.push(arr)
    if ((arr[k] === inPut[j]) && (arr[k] !== /\W/g)){
      let replacer = outPut[j][i];
      arr3.push(replacer)
      }
    }
  }

  } else{
    arr3.push(arr[k])
  } 

}

// return arr3;
arr3 = arr3.join("");
let arr4 = arr3.toString()
let arr5 = arr4.replace(/\_/gi, " ");
return arr5;
}

console.log(rot13("SERR PBQR PNZC")); 
console.log(rot13("SERR CVMMN!")); 
console.log(rot13("SERR YBIR?")); 
console.log(rot13("GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT."));

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

Pre-formatted-text

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (’).

1 Like

Thanks for letting me know.

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.