Related
I'm developing a website for fun that adds a random character to a div element on every key press. I have that part working, but what I need is for the program to check if an English word has been created out of the random characters and highlight that word. I've tried many things, and none have worked. Preferably this would highlight it regardless of whether or not there are spaces surrounding the word, but I will be very happy with really any working code.
This is my current JS for random character generation and autoscrolling, also with some code that doesn't work that is meant to search the code.
var letter = 1
var number = 1
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', '\u0020']
function typingfunction() {
number = Math.floor(Math.random() * 27)
letter = alphabet[number]
document.getElementById("typing").innerHTML = `${document.getElementById("typing").innerHTML}${letter}`
window.scrollTo(0, document.body.scrollHeight * document.body.scrollHeight);
var input = document.getElementById("typing").innerHTML;
var fs = require('fs');
fs.readFile("words_alpha.txt", function(words) {
var words = words.toString().split('\n').filter(function(word) {
return word.length >= 4;
})});
var output = [];
words.forEach(word); {
if (input.match(word)) {
output.push(word);
}
};
console.log(output);
}
window.addEventListener('keydown', typingfunction)
The code for testing a word basically is OK but there was a syntax error in your code (incorrect format for an anonymous function) and also the words array was only declared inside a function but you tried to use it outside the function.
This code slightly reorganises things to take account of this.
I have no way of testing the nodejs filereading (assuming it is nodejs) so if that causes a problem add the tag to your question to get more help in that area.
The code listens for a click on the window and sets the input HTML empty so several trials can be run.
var letter = 1
var number = 1
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', '\u0020']
function typingfunction() {
number = Math.floor(Math.random() * 27)
letter = alphabet[number]
document.getElementById("typing").innerHTML = `${document.getElementById("typing").innerHTML}${letter}`
window.scrollTo(0, document.body.scrollHeight * document.body.scrollHeight);
var input = document.getElementById("typing").innerHTML;
var output = [];
words.forEach(word => {
if (input.match(word)) {
output.push(word);
}
});
console.log(output);
}
// first set up the array of words from the file containing them
let words; //declare words here so it can be used later on
let fs = require('fs');
fs.readFile("words_alpha.txt", function(allWords) {
words = allWords.toString().split('\n').filter(function(word) {
return word.length >= 4;
})});
window.addEventListener('keydown', typingfunction);
window.addEventListener('click', function () {document.getElementById("typing").innerHTML = '';});
For example say you have the string 'ab?d?f' and you must grab the string and replace it with any random letters in the '?' like 'abcdef' or 'abjdlf' but it cannot be 'abbdef' or 'abcdff'.
I have attempted this below:
const 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'];
const randomLeter = () => letters[Math.floor(Math.random() * 26)];
const riddle = 'ab?d?f';
let pickedLetter;
let solvedRiddle;
function solve(riddle) {
for (let i = 0; i < riddle.length; i++) {
if (riddle[i] === '?' && !(riddle[i-1] === randomLeter) && !(riddle[i+1] === randomLeter)){
console.log('Changing to letter');
solvedRiddle = riddle.replace('?', pickedLetter);
}
pickedLetter = randomLeter();
console.log(i, riddle[i], pickedLetter);
}
return solvedRiddle;
}
// The above only returns the first '?' changed but leaves the second one unchanged ... ??? Why can I not change the value of solvedRiddle a second time inside the loop? I can see by my log that it reads at true, but the value won't be re-written.
console.log(solve(riddle));
function solve(riddle) {
for (let i = 0; i < riddle.length; i++) {
if (riddle[i] === '?'){
console.log('Changing to letter');
let pickedLetter = randomLeter();
while (riddle[i-1] === pickedLetter || riddle[i+1] === pickedLetter) {
pickedLetter = randomLeter();
}
riddle = riddle.replace('?', pickedLetter);
}
}
return riddle;
}
Also, it's because u update and return solvedRiddle. Your original riddle string is not updated, so in the second run, it is still changing the first ?
I modified your code so that it suits the needs, however there may be some bugs or exceptions not handled yet, but it can give you a hint that how you are going to solve the problem.
const 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'];
let randomLeter = (excluded) =>
{
let letter = false;
do
{
letter = letters[Math.floor(Math.random() * 26)];
}
while(excluded.includes(letter));
return letter;
}
let getIndices = (s, t) => {
return [...s].flatMap((char, i) => (char === t ? i : []));
};
let Solve = (riddle) =>
{
riddle = [...riddle];
//get the locations of all ? in the string
let all = getIndices(riddle, '?');
for(let i = 0; i < all.length; i++)
{
//exluding characters before and after the ?
let excluded = [riddle[all[i] - 1], riddle[all[i] + 1]];
riddle[all[i]] = randomLeter(excluded);
}
return riddle.join("");
};
let riddle = 'ab?d?f';
document.getElementById('riddle').innerHTML = 'The Riddle ' + riddle;
document.getElementById('solution').innerHTML = "Solution " + Solve(riddle);
<h2 id="riddle"></h2>
<h4 id="solution"></h4>
I'm working on some quiz here and I'm wondering how do I write a function to form a string: HEY JUDE?
I have the initial array which looks like this [ 'H', 'E', 'Y', '', '', 'J', 'U', 'D', 'E' ]
I understand this is a simple quiz but I don't know how do I leave only one space instead of 2 between the words.
This can be done in many ways but the simplest way would be to use a for loop.
Logic
Create a temp variable that will hold last appended character.
Loop over array and set this variable.
If current char is blank,
And if last char is not space, set it as space.
If is is space, keep it as it is.
Else, set value as current char
Not append this char to your string.
var data = [ 'H', 'E', 'Y', '', '', 'J', 'U', 'D', 'E' ];
var str = '';
var lastChar = null;
for(var i = 0; i< data.length; i++) {
if(!data[i] && lastChar !== ' '){
lastChar = ' ';
}
else {
lastChar = data[i];
}
str += lastChar;
}
console.log(str)
You could join the array with space and delete a single space or multiple spaces.
var array = ['H', 'E', 'Y', '', '', 'J', 'U', 'D', 'E'];
console.log(array.join(' ').replace(/ (?= |\S)/g, ''));
You can use join property of array.
Reference for array join
var arr = [ 'H', 'E', 'Y', '', '', 'J', 'U', 'D', 'E' ] then
arr.join('') will give you "HEYJUDE"
If you add one whitespace in between
var arr = [ 'H', 'E', 'Y', ' ', 'J', 'U', 'D', 'E' ] then
arr.join('') will give you "HEY JUDE"
I am trying to translate all alphabets in a message to p alphabet(s) in the sequence. for example: Translate("bbcd", 2) will return "ddef". I am stuck at the array part where alphabets[j+p] returns undefined. If I do alphabets[j-p], it will work.
Here is my code:
function Translate(Message, p) {
var alphabets = ['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 message_array = Message.split('');
for(var i in message_array){
for(var j in alphabets){
if(message_array[i]==alphabets[j]){
message_array[i]=alphabets[j+p];//returns undefined
}
}
}
return message_array;
}
console.log(Translate("bbcd", 2));
The problem is j+p which is doing a string concatenation, typeof j will return string as you are reading the array index using for...in
function Translate(message, p) {
var alphabets = ['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.split('').map(function(c) {
var idx = alphabets.indexOf(c);
return idx == -1 ? c : alphabets[(idx + p) % alphabets.length]
});
}
var value = Translate("azpq", 2);
result.innerHTML = JSON.stringify(value);
<div id="result"></div>
alphabets[j+p]; returns undefined for j == 26 that it will reach for the inner loop iteration.
use indexOf method of array and change your loop structure to
for(var i in message_array)
{
var index = alphabets.indexOf( message_array[ i ] );
message_array[ i ] = alphabets[ index + 2 ];
}
This also will reach 'undefined' if your Message has a y or z in it.
so, you might want to cycle it back to the beginning
for(var i in message_array)
{
var index = alphabets.indexOf( message_array[ i ] );
message_array[ i ] = alphabets[ (index + 2) % alphabets.length ];
}
function Translate(Message, p) {
var alphabets = ['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 messageLength = Message.length;
var returnMessage = '';
for(var i=0; i< messageLength; i++) {
var myChar = Message.charAt(i);
var placeChar = alphabets.indexOf(myChar);
myChar = alphabets[placeChar + p];
returnMessage += myChar;
}
return returnMessage;
}
console.log(Translate("bbcd", 2));
You need to break once the value is found. Otherwise the inner loop will find a match again on the coming cycles.
function Translate(Message, p) {
var alphabets = ['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 message_array = Message.split('');
for (var i in message_array) {
for (var j in alphabets) {
if (message_array[i] == alphabets[j]) {
console.log(alphabets[parseInt(j) + parseInt(p)])
message_array[i] = alphabets[parseInt(j) + parseInt(p)]; //returns undefined
break;
}
}
}
return message_array;
}
alert(Translate("bbcd", 2));
You need to make sure that j+p is never bigger than the length of alphabets. This will result in a "out of bounds" error. e.g. p = 30.
A fix is to just check the length compared to p and returns something that is defined.
message_array[i] = (j+p > alphabets.length) ? alphabets[j+p] : alphabets[j]; // returns element at j if out of bounds
This suggestion works with an alphabet string instead of an array.
You can access a string like an array for a single character. For the lookup i suggest to use indexOf(), a method availabele at string objects String#indexOf() as well as array objects Array#indexOf(). Both methods returns the position of the found item/string/character or -1 if not found.
For the result I took an empty string and concatinated it with the new character.
For the correct range of the index, while adding some value, the method of choice is to use the modulo operator. It returns the reminder of a division by the second number. Here it is the length of the alphabet string.
function translate(message, p) {
var alphabet = 'abcdefghijklmnopqrstuvwxyz',
i, pos, result = '';
for (i = 0; i < message.length; i++) {
pos = alphabet.indexOf(message[i]);
result += alphabet[(pos + p) % alphabet.length];
}
return result;
}
document.write(translate("bbcd", 2));
I'm trying to create a simple javascript password generator that spits out the number of characters the user puts in. So, lets say you enter the number 7. I want the program to then spit out 7 random characters from the possibilities variable. Below is my code so far:
var possibilities = ['A', 'B', 'C', 'D', 'E', 'F', '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', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
];
var special_chars = "~`!#$%^&*+=-[]\\\';,/{}|\":<>?"; //no special characters
function generator() {
if (document.getElementById("input").value == '' || document.getElementById("input").value > 61) {
alert("Enter under 61 characters");
} else if (isNaN(document.getElementById("input").value) || document.getElementById("input").value == special_chars) {
alert("Enter numbers only");
} else {
//var userInput = document.getElementById("input").value -- get value of this when clicked, spit out number of items from this array based on the value collected
for (var x = 0; x < possibilities.length; x++) {
var content = possibilities[Math.floor(Math.random() * possibilities.length)];
}
document.getElementById("random_password").innerHTML = content;
}
}
I'm a bit new to JavaScript and am kind of stuck here so any help is appreciated :) Thx in advance!
Here is a working demo. This is uses an existing answer found here. I have added minor changes to fit this question.
function makeid(){
var IdLength=document.getElementById('IdLength');
//Strip anything but 0 to 9
var UserInput=IdLength.value.replace(/[^0-9.]/g, "");
//Update input value
IdLength.value=UserInput;
var Results=document.getElementById('results');
var text = "";
var shuffle = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
//Is input is empty?
if(IdLength!==''){
for( var i=0; i < IdLength.value; i++ ){
text += shuffle.charAt(Math.floor(Math.random() * shuffle.length));
}
Results.innerHTML=text;
}
}
<input type="text" id="IdLength" oninput="makeid()" placeholder="Enter 0-9"/>
<span id="results"></span>
I hope this helps. Happy coding!
If you are looking for something basic then you should try the Jen library (works both on browsers and nodejs/io.js).
And actually it is not recommended to use Math.random() for crypto application (such as password generation)
This is a small script that I wrote. I do use this on a day to day basis to generate passwords. It is not perfect but it will do the small tasks. Feel free to play around with it and make it more perfect.
This is the JavaScript code plus the HTML code so you can try it. Basically, you can give Length anything that is a string(I haven't make an error checking for that). If the length is equal to 'rand' then the generator will generate a random password with a length between 19 to 30 characters. If length can't be converted to a number or is lower than 13 then the password generator will generate a password with a length of 13.
For the variable "not" and the feature of "Not". The password generator will not generate a password that contained any character that you placed in the Not field.
When it comes to generating the password, the generator will generate one character for each variable of s, n, u, l(4 in total). It will then generate the rest of it length randomly using the characters from variable a. After that, the generator will shuffle the string that it just generated randomly. It will then alert you the length of the password and give the output of the password in the shadowed box.
Also, it is just easier to obtain a random character at a random position in the string then taking a character from a random index in an array. It is easier when it comes to reconfiguring the script.
<html>
<head>
<script type="text/javascript">
function rand( len, not ){
if ( len === undefined ) len = 13;
if ( typeof not !== 'string' ) not = '';
if ( len === 'rand' ) len = Math.floor(Math.random() * (30 - 19) + 19);
if ( typeof len === 'string' ) len = parseInt(len, 10);
if ( len < 13 || isNaN(len) ) len = 13;
var s = '!#~!##$%^&*()-_=+',
n = '0123456789',
u = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
l = 'abcdefghijklmnopqrstuvwxyz',
a = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#~!##$%^&*()-_=+',
out = '';
if ( (nl = not.length) > 0 ){
var regex = '';
for ( var i = 0; i < nl; i++ ){
regex = not.charAt(i).replace(/[.*+?^${}()|[\]\\]/, '\\$&');
regex = new RegExp( regex , 'g');
if ( s.length > 0 ) s = s.replace( regex, '');
if ( n.length > 0 ) n = n.replace( regex, '');
if ( u.length > 0 ) u = u.replace( regex, '');
if ( l.length > 0 ) l = l.replace( regex, '');
a = a.replace( regex, '');
}
}
if ( s.length > 0 ) out += s.charAt( Math.floor(Math.random() * s.length) );
if ( n.length > 0 ) out += n.charAt( Math.floor(Math.random() * n.length) );
if ( u.length > 0 ) out += u.charAt( Math.floor(Math.random() * u.length) );
if ( l.length > 0 ) out += l.charAt( Math.floor(Math.random() * l.length) );
for ( var i = out.length; i < len; i++) out += a.charAt( Math.floor(Math.random() * a.length) );
out = out.split('').sort(function(a, b){return 0.5 - Math.random()}).join('');
alert(out.length);
return out;
}
function generate(){
document.getElementById("result").value = rand( document.getElementById("length").value, document.getElementById("not").value );
}
</script></head>
<body>
<label for="length">Length:</label><input type="text" id="length" maxlength="5" size="5">
<label for="not">Not:</label><input type="text" id="not" size="12">
<button onclick="generate();" type="button">Generate</button><br />
<input type="text" id="result" size="35" value="Result" disabled><br />
</body>
</html>
Memorable password generator
// Also you can use a custom function to get random numbers instead
const _ = require('lodash/number');
/*
* Generate comfortable to remember password
*
* #param integer length - length of generated password
*
* #return string password
*/
function my_create_password(length)
{
let vowel = [
'a',
'e',
'i',
'o',
'u',
];
let consonant = [
'b',
'c',
'd',
'f',
'g',
'h',
'j',
'k',
'l',
'm',
'n',
'p',
'q',
'r',
's',
't',
'v',
'w',
'x',
'y',
'z',
];
result = '';
for (let i = 0; i < length; i++) {
if (i % 2 === 0) {
result += consonant[_.random(0, 15)];
} else {
result += vowel[_.random(0, 4)];
}
}
return result;
}
Result:
password(8);//kutekaku
password(11);//rahubabatun