-1

Good morning, i'm trying to generate a sequence of N pairs of numbers, for example 1-0, 2-4, 4-3. These numbers must range between 0 and 8 and the pair must be different for all the numbers.

I don't want that: 1-3 1-3

I found that if a and b are the numbers, (a+b)+(a-b) has to be different for all couples of numbers.

So I manage to do that, but the loop never ends. Would you please correct my code or write me another one? I need it as soon as possible.

NSNumber*number1;
int risultato;
int riga;
int colonna;
NSMutableArray*array=[NSMutableArray array];
NSMutableArray*righe=[NSMutableArray array];
NSMutableArray*colonne=[NSMutableArray array];

for(int i=0; i<27; i++)
{
    riga=arc4random()%9;
    colonna=arc4random()%9;
    risultato=(riga+colonna)+(riga-colonna);
    number1=[NSNumber numberWithInt:risultato];
    while([array containsObject:number1])
    {
        riga=arc4random()%9;
        colonna=arc4random()%9;
        risultato=(riga+colonna)+(riga-colonna);
        number1=[NSNumber numberWithInt:risultato];
    }

    NSNumber*row=[NSNumber numberWithBool:riga];
    NSNumber*column=[NSNumber numberWithInt:colonna];
    [righe addObject:row];
    [colonne addObject:column];
    [array addObject:number1];

}

for(int i=0; i<27; i++)
{
    NSNumber*one=[righe objectAtIndex:i];
    NSNumber*two=[colonne objectAtIndex:i];

    NSLog(@"VALUE1 %ld VALUE2 %ld", [one integerValue], (long)[two integerValue]);
}

edit:
I have two arrays (righe, colonne) and I want them to have 27 elements [0-8]. I want to obtain a sequence like it: righe: 1 2 4 6 7 8 2 3 4 8 8 7 colonne: 1 3 4 4 2 1 5 2 7 6 5 6 I don't want to have that: righe: 1 2 4 6 2 colonne: 1 3 5 2 3 Where you see that 2-3 is repeated once. Then I'd like to store these values in a primitive 2d array (array[2][27])

cristakey IT
  • 53
  • 1
  • 9
  • 2
    please use `arc4random_uniform` instead of `arc4random % something`. See https://stackoverflow.com/questions/160890/ . What do you mean with *"(a+b)+(a-b) has to be different for all couples of numbers."*? And using english variable names would be a big improvement because right now you could simply call them `a`, `b`, `c` and `d` and your code would be equally readable. – luk2302 Mar 15 '17 at 08:43
  • Well, maybe I wasn't clear about that. I have two arrays (righe, colonne) and I want them to have 27 elements [0-8]. I want to obtain a sequence like it: righe: 1 2 . 4 . 6 . 7 8 . 2 . 3 . 4 . 8 . 8 7 colonne: 1 3 . 4 . 4 . 2 .1 . 5 . 2 . 7 . 6 . 5 . 6 I don't want to have that: righe: 1 . 2 . 4 . 6 . 2 colonne: 1 . 3 . 5 . 2 . 3 Where you see that 2-3 is repeated once. Then I'd like to store these values in a primitive 2d array (array[2][27]) Could you please tell me about a code that does that? Thank you for answering – cristakey IT Mar 15 '17 at 13:11
  • I've edited my first post – cristakey IT Mar 15 '17 at 13:22

2 Answers2

0

Your assumption about (a+b)+(a-b) is incorrect: this formula effectively equals 2*a, which is obviously not what you want. I suggest storing the numbers in a CGPoint struct and checking in a do...while loop if you already have the newly generated tuple in your array:

// this array will contain objects of type NSValue,
// since you can not store CGPoint structs in NSMutableArray directly
NSMutableArray* array = [NSMutableArray array];
for(int i=0; i<27; i++) {
    // declare a new CGPoint struct
    CGPoint newPoint;
    do {
        // generate values for the CGPoint x and y fields
        newPoint = CGPointMake(arc4random_uniform(9), arc4random_uniform(9));
    } while([array indexOfObjectPassingTest:^BOOL(NSValue* _Nonnull pointValue, NSUInteger idx, BOOL * _Nonnull stop) {
        // here we retrieve CGPoint structs from the array one by one
        CGPoint point = [pointValue CGPointValue];
        // and check if one of them equals to our new point
        return CGPointEqualToPoint(point, newPoint);
    }] != NSNotFound);
    // previous while loop would regenerate CGPoint structs until
    // we have no match in the array, so now we are sure that
    // newPoint has unique values, and we can store it in the array
    [array addObject:[NSValue valueWithCGPoint:newPoint]];
}

for(int i=0; i<27; i++)
{
    NSValue* value = array[i];
    // array contains NSValue objects, so we must convert them
    // back to CGPoint structs
    CGPoint point = [value CGPointValue];
    NSInteger one = point.x;
    NSInteger two = point.y;

    NSLog(@"VALUE1 %ld VALUE2 %ld", one, two);
}
pckill
  • 3,709
  • 36
  • 48
0

I found that if a and b are the numbers, (a+b)+(a-b) has to be different for all couples of numbers.

This is just 2 * a and is not a valid test.

What you are looking for are pairs of digits between 0 - 8, giving a total of 81 possible combinations.

Consider: Numbers written in base 9 (as opposed to the common bases of 2, 10 or 16) use the digits 0 - 8, and if you express the decimal numbers 0 -> 80 in base 9 you will get 0 -> 88 going through all the combinations of 0 - 8 for each digit.

Given that you can can restate your problem as requiring to generate 27 numbers in the range 0 - 80 decimal, no duplicates, and expressing the resultant numbers in base 9. You can extract the "digits" of your number using integer division (/ 9) and modulus (% 9)

To perform the duplicate test you can simply use an array of 81 boolean values: false - number not used, true - number used. For collisions you can just seek through the array (wrapping around) till you find an unused number.

Then I'd like to store these values in a primitive 2d array (array[2][27])

If that is the case just store the numbers directly into such an array, using NSMutableArray is pointless.

So after that long explanation, the really short code:

int pairs[2][27];
bool used[81];     // for the collision testing

// set used to all false
memset(used, false, sizeof(used));

for(int ix = 0; ix < 27; ix++)
{
  // get a random number
   int candidate = arc4random_uniform(81);
   // make sure we haven't used this one yet
   while(used[candidate]) candidate = (candidate + 1) % 81;
   // record
   pairs[0][ix] = candidate / 9;
   pairs[1][ix] = candidate % 9;
   // mark as used
   used[candidate] = true;
}

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86