How to display non-repetitive letter within 3 boxes? - javascript

The below code can display a single random letter in each box. However, a letter should not be able to appear on different boxes at the same time as one of the boxes. For example, box 1 displays "A", then box 2 and 3 cannot display "A" also.
function random() {
var letter = [];
for (var i = 65; i < 91; i++)
{
letter.push(String.fromCharCode(i));
}
return letter[Math.floor(Math.random() * letter.Length)];
}
function display()
{
document.getElementById("box1").textContent = random();
document.getElementById("box2").textContent = random();
document.getElementById("box3").textContent = random();
}

A good way to do this would be to overhaul your random function to generate all the letters at once, like so:
function randomN(n=3) {
const letters = new Set()
while (letters.size < 3) {
const i = Math.floor(Math.random() * (91-65)) + 65
letters.add(String.fromCharCode(i))
}
return [...letters]
}
function display() {
const [letter1, letter2, letter3] = randomN()
document.getElementById("box1").textContent = letter1
document.getElementById("box2").textContent = letter2
document.getElementById("box3").textContent = letter3
}
For a more modern approach you can utilize generators:
function* randomLetters() {
const letters = "QWERTYUIOPASDFGHJKLZXCVBNM".split('')
while (letters.length > 0) {
const i = Math.floor(Math.random() * letters.length)
yield letters[i]
letters.splice(i, 1)
}
}
function display() {
const letters = randomLetters()
document.getElementById("box1").textContent = letters.next()
document.getElementById("box2").textContent = letters.next()
document.getElementById("box3").textContent = letters.next()
/* and so on and so forth! */
}

function letterGenerator(n=1) {
var generated_letters = [];
var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
for (var i=0; i<n; i++){
var random = Math.floor(Math.random() * alphabet.length);
var letter = alphabet.splice(random, 1)[0];
generated_letters.push(letter)
}
return generated_letters;
}
var letters = letterGenerator(3)
gives Array(3) [ "Q", "T", "I" ], for example.
by using splice, we are making sure the randomly chosen letters are removed from the alphabet variable.
you can then go over the letters with for (letter of letters) or something like that, and add each one to the desired element.
by the way, maybe run a document.querySelectorAll('[id^="box"]'); to get all elements and add to them with a for loop.
this, alongside the n parameter, allows for any number of generated letters.
(if you really want it to be generic, create the box elements using js as well)
the solutions attached in the comments are certainly clever.
I especially liked this one

Related

How to generate a random 5 letter code and give filters

I want to generate a random 5 letter code and give filters that the code will not same to the filters. I also want filters to be in an array. If there are too many filters that the code can't generated, it will make new character in the code. Like in YouTube, in a video, a random letter of 9 characters is generated and it has given filters to not generate the same.
The generation function and the filter generate function (90%) are created but only one problem is written in the code:
var l = `abcdefghijklmnopqrstuvwxyz${"abcdefghijklmnopqrstuvwxyz".toUpperCase()}0123456789`;
function generateCode(c) {
var t = "";
for (var i = 0; i < c; i++) {
t += l.split("")[randomNumber(0, l.length)];
}
return t;
}
function filtersPreventGenerate(generated, minCharacters) {
/*
generated: array
minCharacters: number
*/
var t = "";
var characters = minCharacters;
t = generateCode(characters);
while (generated.indexOf(t) > -1) {
t = generateCode(c);
// i can't tell what is the code to check there are too many items in the generated argument that 5 letter can't generated. what will be the code?
}
return t;
}
function randomNumber(min, max) {
return Math.floor(Math.random() * max) + min;
}
Help will be appreciated.
Here is a snippet that you can use as a 5-letter code generator
function generate(len = 5){
let charset = "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!##$%^&*()"
let result = ""
for(let i = 0; i<len;i++ ){
let charsetlength = charset.length
result+=charset.charAt(Math.floor(Math.random() * charsetlength))
}
return result;
}
And below snippet is responsible to assign the random as a "code" variable, based on it you can create filter inside the function
$(document).on("click", ".generate", function(){
let code = generate()
// your filters here
})

How do I make a random value not repeat itself? (JavaScript)

So I want to make it so that every time I run the code the item of this array that shows up will be different. Here is the code I've done so far.
let array = ["apple","orange"];
randomItem = array[Math.floor(Math.random() * array.length)];
if(randomItem != document.getElementById('spaceText').innerHTML){
document.getElementById('spaceText').innerHTML = randomItem;
} else while(randomItem == document.getElementById('spaceText').innerHTML){
randomItem = array[Math.floor(Math.random() * array.length)];
}
I'm not entirely sure how to finish this .. here is how I'm looking at the problem,
You have an array that includes several strings you want to pick from
you want to generate a random number to select one item from the array
you want to check if the selected item is equal to the content of the html element of yours.
if not, then you would like to insert that item into the html element
if it is equal you want to generate another random number
There are multiple ways to achieve this:
You could build a new array without the value you don't want, and choose a random from that.
You could also make a loop which keeps going until you get a value you want.
You could also move the value you don't want to the end of the array, swapping place, and then choose a value within upperBound - 1.
You could also just remove the value you get from the array each time, if you don't want it to appear at all again.
There are multiple ways that all depend on the context and goal of the system.
In your case you don't have to generate a random number more than once, just use filter method
const array = ["Apple","Orange","Cherry","Banana","Pear"];
const spaceText = document.getElementById('spaceText');
function randomText() {
//the next fruit cannot equal the current text content
const options = array.filter(fruit => fruit !== spaceText.textContent);
const randomIndex = Math.floor(Math.random() * options.length);
console.log("Random fruit is:",options[randomIndex]);
spaceText.textContent = options[randomIndex];
}
<div id="spaceText">Apple</div>
<button onclick="randomText()">Randomize</button>
Does this help you? All it does is selecting a new item from the array and taking care that it is not the one that was selected previously
const items = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
let selectedItemIndex;
function selectNewOne() {
const randomItemIndex = Math.floor(Math.random() * items.length);
if (randomItemIndex === selectedItemIndex) {
return selectNewOne();
}
return randomItemIndex;
}
// this is just for testing purposes
for (let i = 0; i < 5; i++) {
selectedItemIndex = selectNewOne();
console.log(items[selectedItemIndex]);
}
Here is one approach, Keep the random number in object (or set) and generate new random until you found not already seen one. Generator function will be helpful to do that.
const getRandomUniqueInList = function* (arr) {
const myRandom = () => Math.floor((Math.random() * 100) % arr.length);
const list = [];
while (list.length < arr.length) {
let index = myRandom();
while (list.includes(index)) {
index = myRandom();
}
list.push(index);
yield index;
}
return -1;
};
const items = new Array(10).fill(0);
const itr = getRandomUniqueInList(items);
let next = itr.next();
while (!next.done) {
console.log('Random: ', next.value);
next = itr.next();
}
Another variant for get random upto specified max number and implement with Set and generator method.
const getRandomUpto = function* (max = 50) {
const myRandom = () => Math.ceil(Math.random() * max);
const set = new Set();
let rand = myRandom();
while (set.size < max) {
while (set.has(rand)) {
rand = myRandom();
}
set.add(rand);
yield rand;
}
};
const sample_max = 10;
const itr = getRandomUpto(sample_max);
let next = itr.next();
while(!next.done) {
const myRandom = () => Math.ceil(Math.random() * sample_max);
console.log('Random, (not repeat):', next.value, '(may repeat): ', myRandom());
next = itr.next()
}
Based on your code sample. You are using innerHTML which assumed to be string. So the approach is when you trigger the function, pull a random element/word from the array, then matches if it exists in the current innerHTML value, if it is true, it will skip it else it will append the random word into the innerHTML.
This could work with arrays as well as an alternative to innerHTML / string
let array = ["apple","orange", "banana","cherry","strawberry" ];
random = () =>{
let randomItem = array[Math.floor(Math.random() * array.length)];
let currentString = document.getElementById('spaceText').innerHTML
if( ! (parseFloat(currentString.indexOf(randomItem)) >=0) ){
currentString += ' '+randomItem
document.getElementById('spaceText').innerHTML = currentString
}else{
console.log(randomItem+' already exists')
}
}
<div id="spaceText">Inital value</div>
<button onclick="random()">Random</button>

Counting up within a function of Javascript.

I have the following javascript code:
nback.lightElement = function(index) {
var letterArray = new Array('Lorem', 'Ipsum' , 'Dolor', 'Est');
var r = Math.floor(Math.random()*4);
var letter = letterArray[r];
nback.numbers[index] = letter;
nback.numbers.innerHTML = letter;
nback.litCell = letter;
nback.current = letter;
nback.previous.push(nback.current);
};
nback.startGame = function() {
nback.round += 1;
nback.updateRound();
nback.blink_count = 0;
// Make a new game
nback.queue = new Queue();
for (i = 0; i < BLINKS; i++) {
// Populate with random data, less fun than created games
// but this is way easier to program.
nback.queue.queue(Math.floor(Math.random() * 1));
}
// Run the game loop every TIME_BETWEEN_ROUNDS
nback.intervalId = window.setInterval(nback.next, TIME_BETWEEN_BLINKS);
};
This gives my a random word output from the letterArray for TIME_BETWEEN_BLINKS milliseconds (e.g. 1000). That word is shown for 1000ms, disappears, and another word appears randomly. This loops BLINKS-times.
Now I do not want it to choose random words from the letterArray (the var r = Math.floor(Math.random()*4); is one of my main concerns). It should just show them one after another. I tried so many different approches (mainly loops of every kind) but still can't make it work. Most of the time I tried loops I got "undefined" (instead of the actual words) or just nothing (blank).
I use https://github.com/chuckha/N-back as a reference.
Help will be much appreciated.
You can use an index for that array that is initialized outside of the function. Here is some code that gives the next word from the array whenever the lightElement function gets called. It also wraps around.
var letterArrayIndex=0;
nback.lightElement = function(index) {
var letterArray = new Array('Lorem', 'Ipsum' , 'Dolor', 'Est');
var letter = letterArray[letterArrayIndex];
letterArrayIndex = (letterArrayIndex+1) % letterArray.length;
nback.numbers[index] = letter;
nback.numbers.innerHTML = letter;
nback.litCell = letter;
nback.current = letter;
nback.previous.push(nback.current);
};

JavaScript random password with specific format

I would like to generate a random password respecting the following format:
at least one uppercase character
at least one lowercase character
at least one digit
the length should be at least 6 characters
I thought about it and the only thing I could think of is some function that is quite long and ugly. Could you guys offer me a simpler, more efficient way of doing this?
PS: I'm using this function not on the client side, but on the server side, on my Node.js web application.
Here is my solution:
/**
* sets of charachters
*/
var upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
var lower = 'abcdefghijklmnopqrstuvwxyz'
var digit = '0123456789'
var all = upper + lower + digit
/**
* generate random integer not greater than `max`
*/
function rand (max) {
return Math.floor(Math.random() * max)
}
/**
* generate random character of the given `set`
*/
function random (set) {
return set[rand(set.length - 1)]
}
/**
* generate an array with the given `length`
* of characters of the given `set`
*/
function generate (length, set) {
var result = []
while (length--) result.push(random(set))
return result
}
/**
* shuffle an array randomly
*/
function shuffle (arr) {
var result = []
while (arr.length) {
result = result.concat(arr.splice(rand[arr.length - 1]))
}
return result
}
/**
* do the job
*/
function password (length) {
var result = [] // we need to ensure we have some characters
result = result.concat(generate(1, upper)) // 1 upper case
result = result.concat(generate(1, lower)) // 1 lower case
result = result.concat(generate(1, digit)) // 1 digit
result = result.concat(generate(length - 3, all)) // remaining - whatever
return shuffle(result).join('') // shuffle and make a string
}
console.log(password(6))
How about we place the formats into strings and we can place than into an array, then randomly chose one and randomly chose and item in that sub-array item:
var uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var lowers = "abcdefghijklmnopqrstuvwxyz";
var digits = "01234567890";
var all = uppers + lowers + digits;
var choices = [uppers,lowers,digits];
var checks = [];
var password = "";
var ranLength = Math.ceil(Math.random()*10)+3;
for(var i=0; i<ranLength; i++){
var choice = choices[Math.ceil(Math.random()*3)-1];
var choiceItem = choice[Math.ceil(Math.random()*(choice.length))-1]
password += choiceItem;
}
for(var i=0; i<3; i++){ // Append needed values to end
var choice = choices[i];
var choiceItem = choice[Math.ceil(Math.random()*(choice.length))-1]
password += choiceItem;
}
password = password.split('').sort(function(){
return 0.5 - Math.random();
}).join('');
alert(password);
Edited: Sorry made a small mistake. Fixed.
Try this...
var randomstring = Math.random().toString(36).slice(-8);

Generate random letters in javascript and count how many times each letter has occurred?

I want to generate a string of random letters say 10 letters from a-z one after the other i.e. the next letter should be displayed after the previous letter after a certain delay, later, I want to calculate the number of times each letter has been generated, unlike what I have done previously, i.e. I have taken a predefined array of letters and generated them accordingly.
Shorter way to generate such a string using String.fromCharCode:
for (var i = 0, letter; i < 10; i++) {
setTimeout(function() {
letter = String.fromCharCode(97 + Math.floor(Math.random() * 26));
out.appendChild(document.createTextNode(letter)); // append somewhere
}, 2000 * i);
}
And complete demo covering all the problems in this question: http://jsfiddle.net/p8Pjq/
Use the setInterval method to run code at an interval. Set up an array for counting each character from the start, then you can count them when you create them instead of afterwards:
var text = '';
var chars = 'abcdefghijklmnopqrstuvwxyz';
var cnt = new Array(chars.length);
for (var i = 0; i < cnt.length; i++) cnt[i] = 0;
var handle = window.setInterval(function(){
var ch = Math.floor(Math.random() * chars.length);
cnt[ch]++;
text += chars.charAt(ch);
$('#display').text(text);
if (text.length == 20) {
window.clearInterval(handle);
// now all characrers are created and counted
}
}, 2000);
Demo: http://jsfiddle.net/R8rDH/
I am stealing this answer, but look here: Generate random string/characters in JavaScript
function makeid()
{
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 5; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}

Categories

Resources