generating random numbers

Discussion in 'iOS Programming' started by mahaboob, Aug 5, 2009.

  1. mahaboob macrumors member

    Joined:
    Jul 10, 2008
    #1
    I need to produce 15 random numbers between 1 to 16 without repeating any number. I used the code like

    Code:
        int i,j;    
        for(i=0;i<15;i++){    
            j =random() % 15 +1;
            NSLog(@"No: %d => %d \n",i,j);
            srandom(time(NULL)+i);
        }
    
    But some numbers are repeating.
    How can I do it without repeating the numbers?

    Thanks in advance
    Mahaboob
     
  2. gekko macrumors 6502

    Joined:
    Mar 20, 2009
    #2
    You should only call srandom once and before calls to random, like so:
    Code:
        int i,j;    
        srandom(time(NULL));
        for(i=0;i<15;i++){    
            j =random() % 15 +1;
            NSLog(@"No: %d => %d \n",i,j);
        }
    
    srandom initialises the random number generator.

    Sorry, I read it too fast. You can't produce random numbers that don't repeat using this method. You have to select the numbers and keep track of which ones have already been picked in some way.
     
  3. zacheryjensen macrumors 6502a

    zacheryjensen

    Joined:
    May 11, 2009
    #3
    Isn't this somewhat off topic?

    Anyway, what you want is not 15 random numbers. What you want is the numbers 1-16 in a random order. So you would have an array or similar with all 15 numbers in it, then shuffle their order. There are a variety of shuffling algorithms but you could start with something simple. Fill a 15 length array with 0-15. Loop over each element in the array, swap its value with another randomly selected index of the array.

    Then google around for some more effective shuffling algorithms with less likelihood of sequence and grouping.
     
  4. colmaclean macrumors 68000

    colmaclean

    Joined:
    Jan 6, 2004
    Location:
    Berlin
    #4
    A number of ways to do that.

    You could store the list of numbers already generated and compare each newly-generated number against this list to ensure it's not already there. If it is, generate another number, if it isn't add it to the list.

    Or you could set up an array of 15 elements. Each element could represent a number from 1-15. Each time you generate a new number, the corresponding element is checked off. If you generate a number which is already checked off, move to the next available element and check it off.

    And so on...
     
  5. animefx macrumors regular

    Joined:
    May 10, 2005
    Location:
    Illinois
    #5
    i think you could check for the number generated and somehow mark it off your list in memory. one thing you should be using is the != (not equal to) operator.

    so maybe each time it goes through the loop it makes sure the result of the random number is != to one of the previous random numbers that has chosen already.
     
  6. firewood macrumors 604

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #6
    You need to get a book on computer algorithms. The common way to do this is to create a list of numbers, and shuffle the list randomly, then you can read the list in any order and never see a repeat.
     
  7. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #7
    Code:
    
    	int i, j, t, array[16];
    
    	for ( i = 0; i < 15; i++ ) {
    		array[i] = i;
    	}
    
    	srandom( time(NULL) );
    	for ( i = 0; i < 15; i++ ) {
    		j = random() % 15;
    
    		t = array[i];
    		array[i] = array[j];
    		array[j] = t;
    	}
    	
    	for ( i = 0; i < 15; i++ ) {
    		NSLog(@"No: %d => %d \n", i, array[i]);
    	}
    
    
    If you don't mind mixing in some C++

    Code:
    
    #import <Cocoa/Cocoa.h>
    
    #include <algorithm>
    #include <vector>
    
    int main(int argc, char* argv[])
    {
    	// allocate vector of 16 int's named "array"
    	std::vector<int>	array(16);
    
    	// init vector "array" to contain the sequence: 0 - 15
    	for ( std::vector<int>::iterator itr = array.begin(); itr != array.end(); itr++ )
    	{
    		*itr = (itr - array.begin());
    	}
    
    	// shuffle (random order) the vector "array"
    	std::random_shuffle(array.begin(), array.end());
    
    	// output the now shuffled sequence of the vector "array"
    	for ( std::vector<int>::iterator itr = array.begin(); itr != array.end(); itr++ )
    	{
    		NSLog(@"No: %d => %d \n", (itr - array.begin()), *itr);
    	}
    }
    
    
     
  8. Kingbombs macrumors member

    Joined:
    Jun 24, 2009
    #8
    have a look at arc4random()
    You may find it a bit better without having to seed the time
     
  9. PhoneyDeveloper macrumors 68040

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #9
    Out of curiosity, why do you think arc4random() is better than random() for generating a list of 15 numbers in random order?
     
  10. Kingbombs macrumors member

    Joined:
    Jun 24, 2009
    #10
    he doesn't seem to know where to seed the time, so having arc4random() will mean he won't have to worry about that
     
  11. Kingbombs macrumors member

    Joined:
    Jun 24, 2009
    #11
    infact, why wouldn't you use arc4random() ?
    From what i can find out, its not really any slower, its more precision and can be used to creating floating point numbers
    so why use anything else but arc4random for generating random numbers
     

Share This Page