DEV Community

Cover image for One of my favorite JS challenges on Stack Overflow
Gass
Gass

Posted on • Edited on

One of my favorite JS challenges on Stack Overflow

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.

Not possible

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"/>
Enter fullscreen mode Exit fullscreen mode

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))
Enter fullscreen mode Exit fullscreen mode

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))
]
Enter fullscreen mode Exit fullscreen mode

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'
  ];
Enter fullscreen mode Exit fullscreen mode

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()
  }  
}
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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))
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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] + '/>'
Enter fullscreen mode Exit fullscreen mode

Top comments (0)