This one got me hooked for hours. I love when I find uncommon questions and have the time to attempt to solve them.
After one year and four months of been active on Stack Overflow and having answered almost 300 questions, this one is one of my favorite challenges.
The question
How does one randomly change an element across the board for all users without using a back-end ?
Well, to be honest the question was not exactly like that, the user wasn't discarding the use of a back-end but it just made it more interesting.
How did I solve it?
The first time I read the question I thought it was not possible without a back-end.
But after some time thinking I realized that the key to unlock this mistery was in the value that new Date().getTime() provides, due to the fact that returns a number that is the same across all computers around the world and is unique!
You can see the ⚙️ working snippet here
Code explanation
First things first..
<div id="root"/>
I retrieve the milliseconds since January 1, 1970 and then I convert it to hours:
const hours = Math.round(new Date().getTime()/(1000*60*60))
Slice hours
six digit number into three numbers and add them inside an array.
I'm creating this array with the purpose of having multiple unique numbers to create a random number depending on the time, which will be the same across all computers.
const numbers = [
Number(hours.toString().slice(0,2)),
Number(hours.toString().slice(2,4)),
Number(hours.toString().slice(4,6))
]
Now, I need images to display, depending on the random number that the code will generate. I get some URLs from Lorem Picsum and add them inside an array:
images = [
'https://picsum.photos/id/237/200/300',
'https://picsum.photos/id/236/200/300',
'https://picsum.photos/id/235/200/300',
'https://picsum.photos/id/234/200/300',
'https://picsum.photos/id/233/200/300',
'https://picsum.photos/id/232/200/300',
'https://picsum.photos/id/231/200/300',
'https://picsum.photos/id/230/200/300',
'https://picsum.photos/id/229/200/300',
'https://picsum.photos/id/228/200/300'
];
Okay, is time to create the function that will return a random number by the hour.
So how do we do it ?
I'll show you step by step..
Inside hourlyRand()
the first thing I build is an arrow function that will return a pseudo random number as a string depending on the numbersArr
(array of numbers) passed to it.
This does not make much sense now 😵💫 but it will a few lines down the road.
function hourlyRand(){
const pseudoRandString = (numbersArr) => {
let rand = 1
numbersArr.forEach((n, i) => {
if(n !== 0) rand = rand * n
})
return rand.toString()
}
}
Now using pseudoRandString(numbersArr)
function I pass the numbers
array initialized at the top like so pseudoRandString(numbers)
and I assign the value to randString
variable:
let randString = pseudoRandString(numbers)
By slicing the randString
I can get a two digit number. But these numbers have a typeof string
so I need to convert back to Number
and assign the value to n
:
// length of the pseudo random number string
let L = randString.length
let n = Number(randString.slice(L-3,L-1))
And the function hourlyRand()
is almost ready. The only thing pending is to return n
The finished function hourlyRand()
looks like so:
function hourlyRand(){
const pseudoRandString = (numbersArr) => {
let rand = 1
numbersArr.forEach((n, i) => {
if(n !== 0) rand = rand * n
})
return rand.toString()
}
// get a pseudo random number and convert to string
let randString = pseudoRandString(numbers)
// length of the pseudo random number string
let L = randString.length
// slice the string and convert to number
let n = Number(randString.slice(L-3,L-1))
// return the double digit hourly random number
return n
}
Now that we have all we need, we get the two digit random number from hourlyRand()
and divided by 10 (because we have 10 images) and round it:
// pseudo-random number between 0 and 9
let n = Math.round(hourlyRand()/10)
Finally to display the hourly random image just add n
as an index of the images array:
const element = document.getElementById('root')
element.innerHTML = '<img src=' + images[n] + '/>'
Top comments (0)