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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.