0

I am working on a Codewars problem and have been able to solve the majority of this problem except the final part. The challenge is "rot13"

ROT13 is a simple letter substitution cipher that replaces a letter with the letter 13 letters after it in the alphabet. ROT13 is an example of the Caesar cipher. Create a function that takes a string and returns the string ciphered with Rot13.

function rot13(message){
  message = message.split('');
  
  let alphabet = ['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'];

  let indexes = message.map(char => alphabet.indexOf(char));

  let result = indexes.map(i => {
    let val = i + 13;
    let max = 26;
    if (val > max) {
      let temp = val - max;
      val = temp;
    }
    return val;
  });

  //result = [6, 17, 5, 6];
  //i want to use the elements in my result array, and
  //grab the letters from my alphabet array whose indexes associate with those elements from my result array

}
rot13('test') // 'grfg'

This is my current state in this problem. I have tried checking if any of the indexes of the elements in alphabet === the elements in my result array and if so, pushing those characters from the my alphabet array into an empty array but I am receiving -1

Any suggestions for approaching this problem/altering my thought process will be helpful. Thanks!

6
  • 1
    You need another map: result.map(i => alphabet[i]) Commented Jun 30, 2020 at 20:10
  • Or, if you don't want a second map, do it in the one you already have: return val; -> return alphabet[val]; You do need to return result; at the end of your function, though Commented Jun 30, 2020 at 20:11
  • Hi @Lain , when I return result I get the array [6, 17, 5, 6] however I want ['g','r','f','g'] so I can .join('') and get my final result which should be 'grfg' Commented Jun 30, 2020 at 20:12
  • Be aware that this currently does not work with capital letters. Commented Jun 30, 2020 at 20:13
  • 1
    @blex thank you very much, that resolved my issue! I went with return alphabet[val] in my existing map and did a return result.join(''); Commented Jun 30, 2020 at 20:14

4 Answers 4

1

To answer your question directly, you can just add:

return results.map(i => alphabet[i]).join('')

at the end of the function.

As a side note, instead of having an array of letters you can utilize the String.fromCharCode function. It translates a number into ASCII char equivalent (capital letters start at 65).

function rot13(message){
  message = message.split('');
  
  let alphabet = ['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'];

  let indexes = message.map(char => alphabet.indexOf(char));

  let result = indexes.map(i => {
    let val = i + 13;
    let max = 26;
    if (val > max) {
      let temp = val - max;
      val = temp;
    }
    return val;
  });
  
  return result.map(i => alphabet[i]).join('');
}
console.log(rot13('test')) // 'grfg'

Sign up to request clarification or add additional context in comments.

Comments

1

Use another map() to convert result back to characters by indexing alphabet. Then use join('') to make it a string. Then return it to the caller.

You can simplify the ROT13 calculation using modulus.

function rot13(message) {
  message = message.split('');

  let alphabet = ['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'];

  let indexes = message.map(char => alphabet.indexOf(char));

  let result = indexes.map(i => {
    let val = (i + 13) % 26;
    return val;
  });

  return result.map(i => alphabet[i]).join('');
}
console.log(rot13('test'));

Note that this will only work correctly if the string only contains lowercase letters. Anything else will return -1 from indexOf, and you'll need to check for that.

2 Comments

Maybe simpler to remove the second map and just have one?
@blex I think it's easier to see all the steps by splitting it up.
1

Try this

function rot13(message) {
  message = message.split('');

  let alphabet = ['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 message.map(char => {
    let i = alphabet.indexOf(char);
    i = (i + 13) % alphabet.length;
    return alphabet[i];
  }).join("");
}

console.log(rot13('test')); // 'grfg'

Comments

0

Try this:

function rot13(message){
  message = message.split('');
  let finalResult = "";
  const alphabet = ['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'];

  message.forEach(item => {
    const index =  alphabet.indexOf(item);
    let cipherIndex = index + 13;
    if(cipherIndex > 25)
        cipherIndex = index - 13

    finalResult = finalResult + alphabet[cipherIndex]
  })
  return finalResult;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.