0

In my app, you get a start button first, when you hit "start" the app will randomize the ints fraga1-fraga40 between 0 and 23(which will be used as questions). fraga1 to fraga12 can't be the same. fraga13 to fraga22 can't be the same. fraga23 to fraga28 can't be the same. fraga29 to fraga40 can't be the same.

then after a while, you get another start button.. when you press that one, fraga41-fraga81 will be randomized between 0 and 23. fraga41 to fraga52 can't be the same.`` fraga53 to fraga62 can't be the same. fraga63 to fraga68 can't be the same. fraga69 to fraga80 can't be the same.

but when you click the start button the second time, the button stays"clicked"(or "highlighted") and the app simulator freezes.

i am using a code like this...

 -(void) v1
 {
     fraga1=arc4random()%24;
    [self v2];
  }
  -(void) v2

 {
      fraga2=arc4random()%24;
      if(fraga2==fraga1)
       {
         [self v2];
      }
      [self v3];
  }
 -(void) v3
 {
      fraga3=arc4random()%24;
     if(fraga3==fraga2||fraga3==fraga1)
     {
         [self v3];
     }
           [self v4];
     }

all the way to 40 from the first button... and from v41 to v80 from the other button!

Do you think I can fix this? Should I change my strategy for randomizing the questions?

I have tried to change it so it will randomize like 30 numbers, but it is still the same.. when I try like 100 numbers on each question.. it works, but is kind of slow!

Thanks in advance!

/a noob

EDIT: I did this, but every fraga is set to 0:

void fillUniqueRand(uint32_t arr[], uint32_t l, uint32_t n)

{ uint32_t in, il = 0;

for(in = 0; in < n && il < l; ++in)
{
    uint32_t rn = n - in;
    uint32_t rl = l - il;
    if(arc4random() % rn < rl)
        arr[il++] = in;
}

//We now have random numbers in order and
//need to shuffle them
uint32_t j, tmp;
for(uint32_t i = l - 1; i > 0; i--)
{
    j = arc4random() % (i + 1);
    tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

} //Calling this from a method -(void) vnr { uint32_t fraga1, fraga2, fraga3,fraga4, fraga5,fraga6,fraga7,fraga8,fraga9,fraga10,fraga11,fraga12, fraga13,fraga14,fraga15,fraga16,fraga17,fraga18,fraga19,fraga20,fraga21,fraga22, //... fraga23, fraga24, fraga25,fraga26,fraga27,fraga28,fraga29,fraga30,fraga31,fraga32,fraga33,fraga34,fraga35,fraga36,fraga37,fraga38,fraga39,fraga40; //,... ;

//Max fraga range I noticed was 12
uint32_t unique[12] = { 0 };
fillUniqueRand(unique, 12u, 24u);

fraga1 = unique[0];
fraga2 = unique[1];
fraga3 = unique[2];
fraga4 = unique[3];
fraga5 = unique[4];
fraga6 = unique[5];
fraga7 = unique[6];
fraga8 = unique[7];
fraga9 = unique[8];
fraga10 = unique[9];
fraga11 = unique[10];
fraga12 = unique[11];
//...
fillUniqueRand(unique, 10, 24u);

fraga13 = unique[0];
fraga14 = unique[1];
fraga15 = unique[2];
fraga16 = unique[3];
fraga17 = unique[4];
fraga18 = unique[5];
fraga19 = unique[6];
fraga20 = unique[7];
fraga21 = unique[8];
fraga22 = unique[9];
//Only 6 elements between fraga23-fraga28
fillUniqueRand(unique, 6, 21u);

fraga23 = unique[0];
fraga24 = unique[1];
fraga25 = unique[2];
fraga26 = unique[3];
fraga27 = unique[4];
fraga28 = unique[5];

fillUniqueRand(unique, 12u, 24u);

fraga29 = unique[0];
fraga30 = unique[1];
fraga31 = unique[2];
fraga32 = unique[3];
fraga33 = unique[4];
fraga34 = unique[5];
fraga35 = unique[6];
fraga36 = unique[7];
fraga37 = unique[8];
fraga38 = unique[9];
fraga39 = unique[10];
fraga40 = unique[11];
//...
//You get the picture

}

Mangy92
  • 621
  • 1
  • 10
  • 25
  • 1. Yes change your strategy 2. If you pause the debugger what line is it stopped on? – Joe May 15 '12 at 17:59
  • I can't see what line it is :O Or how can I see it? :O – Mangy92 May 15 '12 at 18:03
  • can you recommend a strategy? I would love that! :) – Mangy92 May 15 '12 at 18:03
  • [Unique random numbers in an integer array in the C programming language](http://stackoverflow.com/questions/1608181/unique-random-numbers-in-an-integer-array-in-the-c-programming-language). For the [debugger](http://developer.apple.com/library/mac/#documentation/IDEs/Conceptual/Xcode4TransitionGuide/Debugging/Debugging.html) part you need to pause the debugger and look at the call stack to see where the code suspends at. – Joe May 15 '12 at 18:07
  • do you mean the fraga1 and so on? then yes I need them. if you mean the v1 and so on, then no I dont need them. how do you mean? :O – Mangy92 May 15 '12 at 18:11
  • Check the answer I posted below. I would recommend an approach similar to that since each fraga variable is necessary. – Joe May 15 '12 at 20:41

2 Answers2

1

Based on the answer to Unique random numbers in an integer array in the C programming language you should implement a more efficient algorithm so that you do not end up in a infinite loop and avoid expensive computation time towards the end of the range. Here is an example of an implementation that may work for you.

/*!
 @param arr Array to be filled with unique random numbers
 @param l Number of elements to fill in the array
 @param n The max of range the random number
    (if there is a minimum range then just add it to each resulting arr index)
 */
void fillUniqueRand(uint32_t arr[], uint32_t l, uint32_t n)
{
    uint32_t in, il = 0;

    for(in = 0; in < n && il < l; ++in)
    {
        uint32_t rn = n - in;
        uint32_t rl = l - il;
        if(arc4random() % rn < rl)
            arr[il++] = in;
    }

    //We now have random numbers in order and
    //need to shuffle them
    uint32_t j, tmp;
    for(uint32_t i = l - 1; i > 0; i--)
    {
        j = arc4random() % (i + 1);
        tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
}

//Calling this from a method
-(void) v1
{
    uint32_t 
        fraga1, fraga2, fraga3, //...
        fraga23, fraga24, fraga25 //,...
    ;

    //Max fraga range I noticed was 12
    uint32_t unique[12] = { 0 };
    fillUniqueRand(unique, 12u, 24u);

    //fill fraga1 - fraga12
    fraga1 = unique[0];
    fraga2 = unique[1];
    fraga3 = unique[2];
    //...

    //Only 6 elements between fraga23-fraga28
    fillUniqueRand(unique, 6, 24u);

    //fill fraga23 - fraga28
    fraga23 = unique[0];
    fraga24 = unique[1];
    fraga25 = unique[2];
    //...
    //You get the picture
 }
Community
  • 1
  • 1
Joe
  • 56,979
  • 9
  • 128
  • 135
  • Thanks! I tried to change to your method, but every fragas is set to 0! I wrote my code in my question above! :) – Mangy92 May 15 '12 at 20:43
  • I definitely tested it and it worked fine, after each call to `fillUniqueRand` `unique` should contain random numbers. – Joe May 15 '12 at 20:58
  • Hmm it seems like every fraga isn't "green" after the uint32_t in (void) v1.. So I guess it can't find them for some reason! Anyway, so for example fraga41 will be in the first filluniquerand with fraga1-fraga12? Like this fraga41=unique[13] right? :) – Mangy92 May 15 '12 at 21:09
  • In the example I am reusing the array, so before you populate fraga41 to fraga52 you will need to call `fillUniqueRand(unique, 12u, 24u)`, then you will populate `fraga41 = unique[0]; fraga42 = unique[1]; fraga43 = unique[2]; ... fraga52 = unique[11];`. Remember call `fillUniqueRand` before each unique set and pass the number of elements (in that example it was 12u). 13 would be out of bounds since I declared the array to only hold 12 elements, if you need more just increase it in the declaration. – Joe May 15 '12 at 21:21
  • Ok, but none of the fragas between fraga1-fraga12 can't be the same as any fraga between fraga41-fraga52 :O I will use fillUniqueRand(unique, 24u, 24u) then right? Any ideas why xcode can't "recognize" the fragas? :S – Mangy92 May 15 '12 at 21:26
  • I understand, yes that is correct, just make sure you make the array 24 elements in the declaration (`uint32_t unique[24] = { 0 };`) and you will be fine, and then `fraga41 = unique[12]; fraga42 = unique[13]; ...` – Joe May 15 '12 at 21:27
  • Yeah nice! :) Im so confused, I can't get xcode to recognize the fragas :S Cuz they should be "green" right? They are declared as ints in the beginning of the code – Mangy92 May 15 '12 at 21:30
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/11282/discussion-between-user1344659-and-joe) – Mangy92 May 15 '12 at 21:31
0

I suggest you use a mutable array to work with your integers fragaXY. You cannot add integers directly into arrays but you can add them after doing this:

[myArray addObject:[NSNumber numberWithInt:fragaXY]];

So I would recommend that you start with your array, fill it completely with random numbers (instead of generating them as you go along), and fix any numbers that match, use a for loop

NSMutableArray *myArray = [[NSMutableArray alloc] initWithCapacity:80];

for (int i=0;i<80;i++) {
[myArray addObject:[NSNumber numberWithInt:(arc4random%24)]];
}

After that is done, to check if your requirements satisfied you can write:

if([myArray objectAtIndex:0].intValue != [myArray objectAtIndex:11].intValue) {

//checking if they fraga1 is different than fraga12 and so on... here you can change one of the values..

}

This will keep your code much cleaner.

Kaan Dedeoglu
  • 14,765
  • 5
  • 40
  • 41