I am trying to complete a codewars challenge as my practice coding since I will have a beginner tech test to enter a coding training program. In case you would like to know what the challenge is: https://www.codewars.com/kata/530e15517bc88ac656000716/train/javascript
I have written code which does what is expected. I will quote Codewars.com below:
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. If there are numbers or special characters included in the
string, they should be returned as they are. Only letters from the
latin/english alphabet should be shifted, like in the original Rot13
"implementation".
My code grabs the test string "grfg" and converts it to the word "test" which would be the equivalent to 13 letters ahead in the alphabet, however, if I pass the string as "Grfg" with the capital "G"it returns "gest" meaning that it will not replace capital letters.
If I pass "test" in lower case it will return "grfg", so it works backwards too, however, if I pass "Test" it will return "trfg" not replacing the capital again but returning the same letter.
Please find the code I wrote below:
function rot13(message){
let abc = ["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", "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 msg = message.split("");
for (let i = 0; i < abc.length; i++){
for (let j = 0; j < abc.length; j++) {
if (msg[j] === abc[i]) {
ind = parseInt(abc.indexOf(i), 0) + 13;
msg[j] = abc.slice(i + 13, i + 14);
};
};
};
return msg.join("").toLowerCase();
};
rot13("test");
What is my mistake or what I should know to make sure that my code will convert the strings regardless of capitals or lowercase?
Have you tried making the message all lower-case first, before splitting it?
let msg = message.toLowerCase().split("");
Related
I'm new to fairly new to Javascript and I need some help solving the 804. Unique Morse Code Words - Leetcode problem.
I figured how to search return the morse code by using the index of each letter from a word and using it to concatenate the codes at those specific index in the morse code array. The problem is I can't store the results into an Set array excluding the duplicates and returning the length of the Set array.
var letters = ["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"];
var morseCode = [".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."];
var words = ["gin", "zen", "gig", "msg"]
var uniqueMorseRepresentations = function(words) {
for (i = 0; i < words.length; i++) {
let word = words[i];
var result = "";
for (j = 0; j < word.length; j++) {
let letter = word.charAt(j);
let index = letters.indexOf(letter);
result += morseCode[index];
};
console.log(result);
};
};
uniqueMorseRepresentations(words);
The console.log method return the results in 4 separate strings but I don't know how to store them into an array while verifying if there are duplicate.
I'm sorry if the question is sloppy. It's my first one.
Thanks in advance!
Inside your function, create a Set:
const resultSet = new Set();
Then when each result is built up (when you log it), add the resulting morse code to that Set:
resultSet.add(result);
Then you can finally return that Set, or its .size.
I think this should solve your problem. Take an obj, and store the result in that and check if the result is repeating then don't push that result into that array. And the time complexity in this operation would be O(1), so you don't have to worry about it if you want to scale your algorithm.
var letters = ["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"];
var morseCode = [".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."];
var words = ["gin", "zen", "gig", "msg","gig"]
var array = [];
var uniqueMorseRepresentations = function(words) {
let obj = {};
for (i = 0; i < words.length; i++) {
let word = words[i];
var result = "";
for (j = 0; j < word.length; j++) {
let letter = word.charAt(j);
let index = letters.indexOf(letter);
result += morseCode[index];
};
if(!obj[result]){
obj[result] = result;
array.push(result);
}
console.log(result);
};
console.log(array)
};
uniqueMorseRepresentations(words);
I was trying to convert alphabets into ASCII using the following:
var subArr = [["S", "E", "R", "R"], ["C", "V", "M", "M", "N", "!"]];
for (var i in subArr) {
var newStr = subArr[i].map( function(val) {
return val.charCodeAt()
})
}
console.log(newStr)
But it seemed that only the second subarray was converted while the first one was not even considered. Would anyone please help me understand the issue here?
This is the problem with scope of your print statement. Note that you are iterating for each sublist and reassigning the map result to the same variable newStr so when you console.log it at the end it only contains the value corresponding to the last sublist!
var subArr = [["S", "E", "R", "R"], ["C", "V", "M", "M", "N", "!"]];
for (var i in subArr) {
var newStr = subArr[i].map(function(val) {
return val.charCodeAt();
});
console.log(newStr);
}
console.log(newStr) is outside the loop. You need to create a list and push new values to it.
like this:
var subArr = [["S", "E", "R", "R"], ["C", "V", "M", "M", "N", "!"]];
var resultArr = [];
for (var i in subArr) {
resultArr.push(subArr[i].map(function(val) {
return val.charCodeAt();
}));
}
console.log(resultArr);
you re not escaping the first array you just crushing the first array with the second one
var subArr = [
["S", "E", "R", "R"],
["C", "V", "M", "M", "N", "!"]
];
var newStr = [];
for (var i in subArr) {
newStr = newStr.concat(subArr[i].map(function(val) {
return val.charCodeAt()
}))
}
console.log(newStr);
console.log() should be inside(in scope of) for...in loop. In map() function you are converting the array to the character code and assigning it to the variable newStr. So, when the map is executed for the second array element, newStr contains the code of the second element. Thus, printing only for the second array element of subArr.
var subArr = [["S", "E", "R", "R"], ["C", "V", "M", "M", "N", "!"]];
for (var i in subArr) {
var newStr = subArr[i].map( function(val) {
return val.charCodeAt()
});
console.log(newStr)
}
Your log statement is outside the loop, which means it'll print the value of newStr once after the loop has finished executing.
In your loop, you are using the same variable newStr to store value in each iteration. This means the second iteration will overwrite the first one and so on.
If your intention is to have ASCII codes for each character in place of the character itself, you should be doing the following
var arrays = [
["S", "E", "R", "R"],
["C", "V", "M", "M", "N", "!"]
];
let asciiArrays = arrays.map(subArray =>
subArray.map(val => val.charCodeAt())
);
console.log(asciiArrays);
This question already has answers here:
What are alternatives to document.write?
(11 answers)
Closed 5 years ago.
(I am new to programming)
The program: I have made a relatively simple JavaScript program, that generates a password when you click on a button.
The problem: Displaying the password with document.write, the whole page is overwritten, meaning that the button is removed and you have no opportunity to generate a new password. Therefore, I would like the password to go inside the paragraph with Id "pw".
Note that document.write is disabled in JSFiddle, so the result is set to display in console.
JSFiddle: https://jsfiddle.net/3qh01ctp/1/
Thank you very much in advance, any help/advice appreciated!
var arr = ["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"];
function generate () {
for (i = 0; i < 10; i++) {
randomLetter = arr[Math.floor(arr.length * Math.random())];
console.log(randomLetter);
}
}
<!DOCTYPE html>
<html>
<head>
<button onclick="generate();">Generate password</button>
</head>
<body>
<p id="pw">
<!-- password should go here -->
</p>
</body>
</html>
You shouldn't use document.write(). Nowadays, you usually select an element, and then push the content into it. You can select an element by e.g. one of the following methods:
document.getElementById(): selects an element by its ID, it is very fast
document.querySelector(): selects an element by its CSS selector (not that fast, but good enough)
So here is an example:
var pw = 'password';
document.getElementById('pw').textContent = pw;
Or with the querySelector:
var pw = 'password';
document.querySelector('#pw').textContent = pw;
I've used .textContent on the node, because it prevents accidental HTML injection. If you explicitly want to allow HTML, you can also use .innerHTML.
And finally, here the complete example (including a button to execute the function):
var arr = ["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"];
function generate () {
var password = "";
for (i = 0; i < 10; i++) {
var randomLetter = arr[Math.floor(arr.length * Math.random())];
password += randomLetter;
}
document.getElementById("pw").textContent = password;
}
document.querySelector('#button-clicker').addEventListener('click', function (event) {
event.preventDefault();
generate();
});
<p id="pw"></p>
<button id="button-clicker">click</button>
var arr = ["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"];
function generate () {
var randomLetter="";
for (i = 0; i < 10; i++) {
randomLetter += arr[Math.floor(arr.length * Math.random())];
//console.log(randomLetter);
}
document.getElementById("pw").innerText =randomLetter ;
}
<!DOCTYPE html>
<html>
<head>
<button onclick="generate();">Generate password</button>
</head>
<body>
<p id="pw">
<!-- password should go here -->
</p>
</body>
</html>
I updated your code please check. using id of you p tag you can place text on that. In you loop keep appending to randomLetter after looping just give it to innerHTML of your p tag document.getElementById("pw").innerHTML = randomLetter;
var arr = ["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"];
var randomLetter ='';
function generate () {
for (i = 0; i < 10; i++) {
randomLetter += arr[Math.floor(arr.length * Math.random())];
}
document.getElementById("pw").innerHTML = randomLetter;
randomLetter ='';
}
<!DOCTYPE html>
<html>
<head>
<button onclick="generate();">Generate password</button>
</head>
<body>
<p id="pw">
<!-- password should go here -->
</p>
</body>
</html>
what you have to do is , Populate the content i.e Random Generated Password in Seprate HTML Body content , it can be Paragraph or Div, Use the java script code as :
document.getElementById('YOUR FIELD ID').innerHTML = "YOUR TEXT";
Do this in your script tag.
var arr = ["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"];
function generate () {
var randomLetter = "";
for (i = 0; i < 10; i++) {
randomLetter += arr[Math.floor(arr.length * Math.random())];
}
var paraElem = document.getElementById("pw");
var t = document.createTextNode(randomLetter);
paraElem.appendChild(t)
}
I am working on creating a program to encrypt a message. One of the functions I was planning on running the code through is a circle cipher. It hasn't been working and I'm unsure as to why. At certain times the program will return the correct letters and at others it won't change anything and returns the same character that was input. Any suggestions are appreciated.
function circle(message, rotate) {
var 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"];
for(i = 0; i < message.length; i++) {
for (i = 0; i < alphabet.length; i++) {
if (message[i] == alphabet[i]) {
message[i] = alphabet[i + rotate];
break;
}
}
}
return message;
}
I spot at least three bugs in your code:
You use the variable i twice. You should use another variable name for the inner loop.
You have to use remainder (modulus) operator to get the value i + rotate modulo 26.
Strings are immutable. So you can't change individual characters of a string.
For those familiar with this quiz, I'm trying to take a string argument and convert each letter to the letter that follows in the alphabet. EG, the argument "abc" should become "bcd".
The first portion of my code works. It takes the first letter of the argument and converts it. Now I'm trying to do this for each letter of the argument and then concatenate the results into one string as the output. This part isn't working. I'm getting the error, "SyntaxError: Unexpected token ;"
function LetterChanges(str) {
var string = str.toLowerCase()
var 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"];
var n = 0;
var output = "";
var currentLetter = string[n];
var currentAlphaPos = alphabet.indexOf(currentLetter);
var nextAlphaPos = currentAlphaPos + 1;
var nextAlpha = alphabet[nextAlphaPos];
//the code above this works. The code below results in an error
while (i = 1;i < string.length; i++){
output += nextAlpha;
n += 1;
};
return output;
}
I'm a beginner, so thanks in advance.
You have confused the while and for loops.
You are trying to do for (iterator; condition; step); the while syntax is simply while (condition).