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("")
}
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!