Quote Machine Project using React

Yeah, that’s the generic idea. There’s also a popular book called Clean Code by Martin.

I just wonder how @kevinSmith would handle this problem in the easiest possible way?

I assume you’re talking about the random number problem? Specifically, how to avoid getting the same number twice in a row.

Again, I would avoid props on functions. And I tend to avoid recursion when I can. It doesn’t do much harm here, but there’s often a simpler, quicker solution. (Don’t get me wrong - there are some problems where recursion is a lot sexier than an iterative solution.)

So, the brute force method would be to have a while loop and just keep getting random numbers until you get one that’s different. That’s basically an iterative version of your recursive solution. It works, but it’s ugly.

I was taking a walk through the woods smoking my pipe after we’d talked about this before. I occurred to me that there is an elegant solution if you need a new (not the same) random value in a range. (In all fairness, it’s undoubtedly occurred to a lot of people before me.) If we have 10 quotes, really we need an offset, a distance to the next index, we need a random number between 0 and 9. For visualization, we currently have a value of x and we want a new random value - anything but x. Imagine these 10 numbers (0 to 9) on a continuous ring. If we move clockwise from x, we will run into all the candidates, first 1 move away, then 2, etc. until we get to 9 moves away. At 10 moves around the circle we get back to x. So, we need a random number (call it y) between 1 and 9 which we can add to x so we can get to a random number that will not be x. Of course, we are not on a circle. But we can add the offset and then use a modulus: (x + y) % 10. I came up with something like this:

const getRandomIndex = (currentIndex, size) => {
  const offset = Math.ceil(Math.random() * (size - 1));
  return (currentIndex + offset) % size;
};

or it could just be:

const getRandomIndex = (currentIndex, size) => (currentIndex + Math.ceil(Math.random() * (size - 1))) % size;

You can mess around with it in a pen here.

1 Like