3

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.

  • 3
    Shuffle the array according to http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array , then iteratively cycle through the array. – le_m May 18 '17 at 22:50
  • you need to store selected page in cookie before you redirect to it, next time you generate random location, check whether you've visited it already – Iłya Bursov May 18 '17 at 22:51

6 Answers6

2

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.

Dmitry Poroh
  • 3,705
  • 20
  • 34
  • This doesn't ensure non-duplicates of the random numbers. The OP already has a random function, but their problem is that it will generate duplicates. – Clonkex May 19 '17 at 00:32
  • @Clonkex Please read my answer attentively. Algorithm parameters are selected to exclude duplicates (get full loop). I select random.length as m. Standard algorithm has m set to something like 2^32 so it can't be used to exclude repetitions. You may run my code if you don't believe. – Dmitry Poroh May 19 '17 at 06:10
  • Ah true, my apologies. I didn't notice you were returning a function. If you edit your post I will be able to remove my downvote (SO won't let me do it now since I vote 11 hours ago). – Clonkex May 19 '17 at 12:27
  • @Clonkex Edited – Dmitry Poroh May 19 '17 at 20:21
  • Done :) And these are extra characters to let me post the comment :P – Clonkex May 20 '17 at 00:06
1

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>
Michał Sałaciński
  • 2,256
  • 1
  • 11
  • 10
1

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>
dana
  • 17,267
  • 6
  • 64
  • 88
0
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>
Ananth A
  • 331
  • 2
  • 5
0

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>
Rohit Kumar
  • 776
  • 3
  • 21
-1

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.

Clonkex
  • 3,373
  • 7
  • 38
  • 55
  • How would I go about making a button for this? I have this code : – Kevin Nguyen May 19 '17 at 00:34
  • @KevinNguyen You must be new to Javascript. No worries, it's easy: ``, exactly the same as @AnanthA's answer :) – Clonkex May 19 '17 at 00:36
  • Ive copied and pasted everything but the button doesnt seem to work at all. Thank you for all the help so far! – Kevin Nguyen May 19 '17 at 00:52
  • @KevinNguyen Just tagging you cuz I'm not sure if you get notified for a comment on my answer. – Clonkex May 19 '17 at 00:54
  • I do not see any. – Kevin Nguyen May 19 '17 at 01:11
  • @KevinNguyen Where are you pasting the code? I've updated my answer to include the button (and remove the call to randomlink() that I had there for testing) and it works fine for me. To test it yourself, just create a new text document and rename it to `test.html` (or whatever), then paste my code into it and open it in Firefox (because Chrome won't save cookies when the page is opened directly on your computer). Oh, you'll also need to get download the js.cookie script from the GitHub link in my answer and put that in the same folder as test.html. – Clonkex May 19 '17 at 03:16
  • Why do we require cookies if this can be done without it. – Rohit Kumar May 20 '17 at 15:56
  • @RohitKumar Why downvote? This code is just as correct as any of the others, and offers a way to leave the page the code is run on and come back, as is implied by the OP's example code. I.e. it sounds to me like he wants a button that will go to some other random page on his site (like an "Explore my Site" button or something). None of the other answers except for dana's will work for this (so your answer would not work either). If you're downvoting for cookies why not downvote for localstorage as well. (I assume you downvoted, apologies if you didn't) – Clonkex May 20 '17 at 23:57
  • @KevinNguyen If any of these answers worked for you, you should select one of them as the answer so that other people know this question is answered. If several worked for you, just pick the one that worked the best. – Clonkex May 21 '17 at 00:00