A random number between 1 and 4 that's not another random number

后端 未结 6 1286
失恋的感觉
失恋的感觉 2021-01-17 05:47

For some reason the following code doesn\'t work.

var a1 = Math.floor(Math.random()*4+1); 

//Answer2
for(a2 = 0; a2 != a1 && a2 != 0; a2 = Math.floo         


        
相关标签:
6条回答
  • 2021-01-17 06:06

    How about a while loop instead? Initialise a2 = a1 and then:

    while(a2 == a1) {
        a2 = Math.floor(Math.random() * 4 + 1);
    }
    
    0 讨论(0)
  • 2021-01-17 06:06

    Just add one if the number is greater than or equal to the one you want to exclude:

    var a2 = Math.floor(Math.random() * 3 + 1);
    
    if(a2 >= a1) {
        a2++;
    }
    
    0 讨论(0)
  • 2021-01-17 06:14

    The logic of your test is inverted. For loops continue to execute while the test is true, not if it fails. Rather than: a2 != a1 && a2 != 0 you should have (a2 == a1) || (a2 == 0). Though also keep in mind that the alert will also only be executed in that case when a2 is an invalid state, though an alert following the for should be valid.

    Or if you're looking for the fun math-y way to do it using modular arithmetic (no retries necessary):

    a2 = (Math.floor(Math.random() * 3 + (a1 + 1)) % 4) || 4
    
    0 讨论(0)
  • 2021-01-17 06:17

    You are choosing a new a2 value when a2 is not the same as a1 or zero. This is backwards - you set a2 to zero before the loop, so it never executes.

    You need to loop while a2 is either zero, or equal to a1:

    var a1 = Math.floor(Math.random()*4+1); 
    
    //Answer2
    for(a2 = 0; a2 == a1 || a2 == 0; a2 = Math.floor(Math.random()*4+1)){
        // nothing here
    }   
    alert(a2);
    
    0 讨论(0)
  • 2021-01-17 06:22

    Try with this function. It'll give you an array with numbers from 1 to max in random order. Then you can use it to assign a value to a variable and it'll never repeat:

    Edit: I found a purely functional way to do it:

    function randomRange(min, max) {
      return (new Array(++max-min))
        .join('.').split('.')
        .map(function(v,i){ return min+i })
        .sort(function(){ return 0|Math.random()*max });
    }
    
    console.log(rand(1,4)); //-> [4,2,1,3] random array from 1 to 4
    
    var arr = rand(1,4);
    var a = arr[0];
    var b = arr[1];
    ...
    

    Edit 2: Seems like the above has problems with some browsers, check out Random but just in Chrome for a better solution.

    Demo: http://jsbin.com/ohohum/1/edit (run multiple times to see the randomness)

    0 讨论(0)
  • 2021-01-17 06:24

    There are two standard ways of doing this kind of thing. I'm considering a slightly more general framework though

    Sample from a filtered list

    1. Create the array of base values to select from

      var values = [1,2,3,4]
      
    2. Remove the values you're not interested in

      values = Array.filter( values, function(x) { return x!=a1; } )
      
    3. Select a value at random from the list

      var a2 = values[Math.floor(Math.random()*values.length)];
      

    Use rejection sampling

    1. Create the array of values to select

       var values = [1,2,3,4]
      
    2. Select a value at random and retry until it succeeds

       var a2 =  values[Math.floor(Math.random()*values.length)];
       while( a2==a1 )
       {
         a2 = values[Math.floor(Math.random()*values.length)];
       }
      

    Comparison

    If we consider n to be the length of the initial list and m to be the number of elements removed, then the filtered version does n comparisons to build the filtered list of length n-m, but only one random number generation. In comparison the rejection method does on average n/(n-m) comparisons and random number generations.

    0 讨论(0)
提交回复
热议问题