javascriptcaesar-cipher

Why the ! commas and spaces are not being returned as output if it was on the argument?


here's my code

const caesar = function(x, y) {
    let alphaListLower = ["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 alphaListUpper = [  '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 userInput = x.split("")

    let result = []

    for(let i = 0; i < userInput.length; i++){
        for(let e = 0; e < alphaListUpper.length; e++){
           

        if (userInput[i] === alphaListLower[e] ){

            if(e+y < 26){
                result.push(alphaListLower[e+y])
            }else{
                result.push(alphaListLower[e+y-26])
            }

        }else if(userInput[i] === alphaListUpper[e] ){

            if(e+y < 26){
                result.push(alphaListUpper[e+y])
            }else{
                result.push(alphaListUpper[e+y-26])
            }
            

        }else if(userInput[i] === "!" || "," || " "){
            result.push(userInput[i])
        }
        }

    
    }

    result = result.join("")

    return result

};

If I gave an argument of 'Hello, World!' it should return 'Mjqqt, Btwqi!'


Solution

  • There are a few changes I have made to your code. Firstly, we have to look at this condition:

    console.log(Boolean(2 === "!" || "," || " "))

    The above will always return true no matter what you replace 2 with. The reason being even though the first condition can be false || "," || " " will always evaluate to true. "," is not a real condition at all but a truthy expression and hence using it between pipe operators always returns true. So I guess you would be adding more and more characters to your list without realisin (<= 25 times extra per letter in the string).

    Ideally you should move out that condition from your inner loop as it has nothing to do with alphabets. Just put it outside.

    I have made minimal changes to your code so improvement is still up to you. But the below works:

    const caesar = function(x, y) {
        let alphaListLower = ["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 alphaListUpper = ["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 userInput = x.split("");
        let result = [];
    
        for(let i = 0; i < userInput.length; i++){
            let added = false;
            for(let e = 0; e < alphaListUpper.length; e++){
                if (userInput[i] === alphaListLower[e]){
                    result.push(alphaListLower[(e + y) % 26]);
                    added = true;
                    break;
                } else if (userInput[i] === alphaListUpper[e]){
                    result.push(alphaListUpper[(e + y) % 26]);
                    added = true;
                    break;
                }
            }
    
            // If the character is not a letter and is a special character like !, , or space, add it directly to the result
            if (!added && ["!", ",", " "].includes(userInput[i])) {
                result.push(userInput[i]);
            }
        }
    
        return result.join("");
    }
    
    console.log(caesar("Hello, World!", 2)); // Shift by 2

    Btw: you need to shift by 5 to get your desired result