1

I'm trying to pass Odin Projects Caesars Cipher and the test is asking to be able to convert negative shifts. Based off of my current code I am able to shift lower case but I am having some issues with B or W.

it('works with negative shift', function() {
    expect(caesar('Mjqqt, Btwqi!', -5)).toEqual('Hello, World!');

However on return my code spits out

'Hello, =orld!'

So close! I've been trying to figure out what it is but I'm not sure what I'm doing wrong here since the 'H' is working

I've rewritten this thing multiple times and I always end up here. I'm sure it's just a number away or something. However it's beyond what I've known or can comprehend at this point.

Thank you all in advance and sorry for such a simple question.

const caesar = function(message, shift) {
    return message 
    .split("") //splits it into an array
    .map(message => { //does the following to each element in the array
        normalStr = String.fromCharCode(message.charCodeAt())
        prePoint = message.charCodeAt() //gets the charcode of element  
    //if/else checks to see if upper or lower case
    if (prePoint >= 65 && prePoint <= 90) { //upper case
        return String.fromCharCode(((prePoint - 65 + shift) % 26) + 65);
    } else if (prePoint >= 97 && prePoint <= 122){ //lower case
        return String.fromCharCode((prePoint -97 + shift % 26) + 97) 
    }  else {
        return normalStr

        //1 func proc uppoer case
        //1 func proc lowercase
        //1 func proc non upper/lower case
    }})
    .join("")

}
Chris King
  • 95
  • 1
  • 10

1 Answers1

0

Your code only works for positive caesar shifts, because in
String.fromCharCode(((prePoint - 65 + shift) % 26) + 65);
the prePoint - 65 + shift might be below zero (with prePoint = B = 66 and shift = -5 you would get -4)

You could either fix this by checking if the result of (prePoint - 65 + shift) is negative, and if so, adding 26 to it:

let newPoint = (prePoint - 65 + shift) % 26;
if(newPoint < 0) newPoint += 26;
return String.fromCharCode(newPoint + 65);

(the same for lowercase letters)

Alternatively you can convert the negative shift into a positive one at the start of your function (a -5 caear shift is the same as a 21 caesar shift):

if(shift < 0) { shift = 26 + (shift % 26);}

Full example:

function caesar(message, shift) {
  if (shift < 0) {
    shift = 26 + (shift % 26);
  }
  return message
    .split("") //splits it into an array
    .map(message => { //does the following to each element in the array
      normalStr = String.fromCharCode(message.charCodeAt())
      prePoint = message.charCodeAt() //gets the charcode of element  
      //if/else checks to see if upper or lower case
      if (prePoint >= 65 && prePoint <= 90) { //upper case
        return String.fromCharCode(((prePoint - 65 + shift) % 26) + 65);
      } else if (prePoint >= 97 && prePoint <= 122) { //lower case
        return String.fromCharCode(((prePoint - 97 + shift) % 26) + 97)
      } else {
        return normalStr;
      }
    })
    .join("");
}

console.log(caesar('Mjqqt, Btwqi!', -5)); // Hello World!
Turtlefight
  • 9,420
  • 2
  • 23
  • 40
  • Hey this is the one! I didn't even realize that a 21 shift would be the same thing as a -5! This is because theres 26 characters in the alphabet, and that 26-5 = 21 right? Thank you so much for the help that you've provided me! – Chris King Jul 31 '19 at 17:50
  • @ChrisKing you're right, you can do the negative -> positive shift transformation because the alphabet loops around, like your 26-5 example :) glad i could help ;) – Turtlefight Jul 31 '19 at 17:58