Kevin Nguyen
Kevin Nguyen

Reputation: 39

How to generate random links with no repeats

I am trying to generate random links with no duplicates. I have the following code so far:

<script type="text/javascript">
var random = new Array();

random[0]="page1.html"
random[1]="page2.html"
random[2]="page3.html"
random[3]="page4.html"
random[4]="page5.html"
random[5]="page6.html"
random[6]="page7.html"
random[7]="page8.html"
random[8]="page9.html"
random[9]="page10.html"
random[10]="page11.html"
random[11]="page12.html"
random[12]="page13.html"



function randomlink() {
window.location = random[Math.floor(Math.random()*12+1)];
}

The code works fine but after some time, it will choose a page that has been shown already and I dont want that. I want it to go through each page once randomly and then restart.

Upvotes: 3

Views: 1506

Answers (6)

Dmitry Poroh
Dmitry Poroh

Reputation: 3825

If you want to see pages in pseudo-random way you can use linear congruential generator.

It defines formula:

X = (a * X + c ) % m

Where following constraints must be met to get full loop:

  • m is number of elements in array (number of URLs)
  • c and m must be relatively prime (you can select any prime as c)
  • a-1 is divisible by all prime factors of m
  • a-1 is divisible by 4 if m is divisible by 4.

For a you can use something like this: m*8+1.

Putting all together:

function createGen() {
    // select first value as random
    var a = random.length * 8+1;
    var current = Math.floor(Math.random()*random.length);
    return function() {
        current = (current * a  + 137) % random.length;
        return current;
    }
}

var next = createGen();
function randomlink() { 
   window.location = random[next()];
}

To achieve better "randomness" you can get random prime number as c each loop (when you met first value).

Disclaimer: it is not easy to get good random, but you may get "well enough" for you case using aforementioned algorithm and adjusting its parameters.

Upvotes: 2

dana
dana

Reputation: 18155

Since user is being redirected to the different pages, you need some way to keep track of which pages they have seen across pages to avoid sending them to the same one twice. There are a couple of ways to do this and in my solution I am using localStorage.

This feature has been disabled in StackOverflow's code snippets for security reasons, but I have tested the following to be working.

var random = new Array();

random[0]="page1.html"
random[1]="page2.html"
random[2]="page3.html"
random[3]="page4.html"
random[4]="page5.html"
random[5]="page6.html"
random[6]="page7.html"
random[7]="page8.html"
random[8]="page9.html"
random[9]="page10.html"
random[10]="page11.html"
random[11]="page12.html"
random[12]="page13.html"

function nextPage() {
  // state variable contains order and last index
  var state = null;
  // read state from localStorage
  if (localStorage.randomState) {
    state = JSON.parse(localStorage.randomState);
    // the # of items has changed, need to re-generate
    if (state.order.length != random.length) {
      state = null;
    }
  }
  // missing or invalid state in localStorage
  if (!state) {
    // uninitialied state
    state = { order: [], index: 0 };
    // build a random order
    for (var i = 0; i < random.length; i++) {
      state.order.splice(Math.floor(Math.random() * (i + 1)), 0, i);
    }
  }
  // get the current page based on saved state 
  var page = random[state.order[state.index]];
  // increment the index, wrapping on overflow
  state.index = (state.index + 1) % random.length;
  // save the updated state to localStorage
  localStorage.randomState = JSON.stringify(state);
  // redirect the user
  location.href = page;
};

The general idea is to generate a random sequence of numbers from 0 to n - 1 where n is the number of pages. Send the user to the pages based on the order of the random sequence. There is also an index variable which tracks the index of the next page that the user should visit. As mentioned above, localStorage is used to persist this data across page loads.

You can send the user to the next page using either the <a> or <button> tag as follows:

<a href="javascript:nextPage()">Next Page</a>
<button type="button" onclick="nextPage()">Next Page</button>

Upvotes: 1

Michał Sałaciński
Michał Sałaciński

Reputation: 2266

This should work:

var random = new Array();

random[0]="page1.html"
random[1]="page2.html"
random[2]="page3.html"
random[3]="page4.html"
random[4]="page5.html"
random[5]="page6.html"
random[6]="page7.html"
random[7]="page8.html"
random[8]="page9.html"
random[9]="page10.html"
random[10]="page11.html"
random[11]="page12.html"
random[12]="page13.html"


var used = JSON.parse(localStorage.used||'[]')

function randomlink() {
if (used.length == 12) used = [];
var r;
do {
  r = Math.floor(Math.random()*12+1);
} while (used.indexOf(r) != -1)
used.push(r)
localStorage.used = JSON.stringify(used)

//window.location = random[r];
console.log(r)
}
<button type="button" onclick="randomlink()">randomize</button>

Upvotes: 1

Clonkex
Clonkex

Reputation: 3637

Assuming you want to be able to actually leave the page doing the link generation and come back, I would do it like this (using cookies to keep track of which pages have been visited so far):

<script src="js.cookie.js"></script>
<script>
    var random = []; //imo neater than 'new Array()'

    random[0]="page1.html"
    random[1]="page2.html"
    random[2]="page3.html"
    random[3]="page4.html"
    random[4]="page5.html"
    random[5]="page6.html"
    random[6]="page7.html"
    random[7]="page8.html"
    random[8]="page9.html"
    random[9]="page10.html"
    random[10]="page11.html"
    random[11]="page12.html"
    random[12]="page13.html"

    function randomlink() {
        var usedLinks = [];
        var cookie = Cookies.get('usedLinks');
        if(cookie) {
            usedLinks = cookie.split(',');
            if(usedLinks.length >= random.length) {
                usedLinks = [];
                Cookies.set('usedLinks','');
                cookie = '';
            }
        }
        var availableLinks = [];
        for(var i=0; i<random.length; i++) {
            var used = false;
            for(var u=0; u<usedLinks.length; u++) {
                if(usedLinks[u] == i) {
                    used = true;
                    break;
                }
            }
            if(used === false) {
                availableLinks[availableLinks.length] = i;
            }
        }
        var index = availableLinks[Math.floor((Math.random()*(availableLinks.length)))];
        if(cookie) {
            Cookies.set('usedLinks',cookie+','+index);
        } else {
            Cookies.set('usedLinks',index);
        }
        window.location = random[index];
    }
</script>
<button type="button" onclick="randomlink()">randomise</button>

Using js-cookie because vanilla cookies are kinda hard to use.

Upvotes: -1

Rohit Kumar
Rohit Kumar

Reputation: 806

Try This...

 var NoOFPages=0;
var json =[];
$(document).ready(function() 
{
  NoOFPages=13;
  var random = new Array();

  random[0]="page1.html"
  random[1]="page2.html"
  random[2]="page3.html"
  random[3]="page4.html"
  random[4]="page5.html"
  random[5]="page6.html"
  random[6]="page7.html"
  random[7]="page8.html"
  random[8]="page9.html"
  random[9]="page10.html"
  random[10]="page11.html"
  random[11]="page12.html"
  random[12]="page13.html"
   $('#btnTwo').click(function() 
   {
      // Action goes here
      if(NoOFPages<=0 )
      {
          alert('Reload the page.');
          return;
      }
      else
      {
            r = Math.floor(Math.random()*NoOFPages+1);
            // Check If Random No Already Generated;
            for(i=0;i<NoOFPages.length;i++)
            {
            
                 if(json[i].usedIndex==r)
                 {
                    	 r = Math.floor(Math.random()*NoOFPages+1);
                       i=0;
                 }
            }
            
            NoOFPages=NoOFPages-1;
            json.push({"usedIndex": r.toString()});
            alert(random[r]);
      }
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<button type="button" id='btnTwo' >randomize</button>

Upvotes: 0

Ananth A
Ananth A

Reputation: 331

var arr = []
function randomlink() {
    var randomUrl = random[Math.ceil(Math.random()*12+1)]
    if(arr.indexOf(randomUrl) > -1) continue;
    window.location = randomUrl;
    arr[arr.length] = randomUrl;
}

You can try this

var random = new Array();

random[0]="page1.html"
random[1]="page2.html"
random[2]="page3.html"
random[3]="page4.html"
random[4]="page5.html"
random[5]="page6.html"
random[6]="page7.html"
random[7]="page8.html"
random[8]="page9.html"
random[9]="page10.html"
random[10]="page11.html"
random[11]="page12.html"
random[12]="page13.html"



var arr = []
function randomlink() {
    var randomUrl = random[Math.ceil(Math.random()*12+1)]
    console.log(arr.indexOf(randomUrl))
    if(arr.indexOf(randomUrl) > -1) {
      randomlink();
    };
    console.log(randomUrl);
    window.location = randomUrl;
    arr[arr.length] = randomUrl;
}
<button type="button" onclick="randomlink()">randomize</button>

Upvotes: 0

Related Questions