Random number in Objective-C [duplicate] - ios

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
Generating random numbers in Objective-C
iOS Random Numbers in a range
Generate non-repeating, no sequential numbers
I am looking for method that give me random numbers between two numbers, and the first number will be number that I choose between the numbers.
for example, if I give this random function 5 and 10 and 9 as the first number, so it will give me: 9,10,7,6,5,8
I tried to use it:
NSUInteger count = [array count];
for (NSUInteger i = 1; i < count; ++i) {
int nElements = count - i;
int n = (random() % nElements) + i;
while (n==`firstnumber`) {
n = (random() % nElements) + i;
}
}

int r = arc4random() % 9 + 5 will give you numbers between 5 and 13 including both of them.

the first number is set by me and the other numbers by the method ,and
every number is shown only one time
It looks like you are after a shuffling algorithm. The following category on NSMutableArray will do the job:
#interface NSMutableArray (Shuffling)
- (void)shuffle;
#end
#implementation NSMutableArray (Shuffling)
- (void)shuffle
{
// Fisher–Yates shuffle (modern algorithm)
// To shuffle an array a of n elements (indexes 0..n-1):
// for i from n − 1 downto 1 do
// j <-- random integer with 0 <= j <= i
// exchange a[j] and a[i]
// http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
for (int i = [self count] - 1; i >= 1; i--) {
int j = arc4random() % (i + 1);
[self exchangeObjectAtIndex:j withObjectAtIndex:i];
}
}
#end
Your requirement is that the number in the first position of the array is fixed (given by you). Then, you can do something like this:
Populate the array with all numbers between minValue and maxValue (both included) except for firstValue.
Shuffle the array.
Insert firstValue at the first position in the array.
Resulting in the following code:
NSInteger minValue = 5;
NSInteger maxValue = 10;
NSInteger firstValue = 9;
// minValue <= firstValue <= maxValue
// populate the array with all numbers between minValue
// and maxValue (both included) except for firstValue
NSMutableArray *ary = [NSMutableArray array];
for (int i = minValue; i < firstValue; i++) {
[ary addObject:[NSNumber numberWithInt:i]];
}
for (int i = firstValue + 1; i <= maxValue; i++) {
[ary addObject:[NSNumber numberWithInt:i]];
}
// --> (5,6,7,8,10)
// shuffle the array using the category method above
[ary shuffle];
// insert firstValue at the first position in the array
[ary insertObject:[NSNumber numberWithInt:firstValue] atIndex:0];
// --> (9,x,x,x,x,x)

Related

NSNumber in arrays, ios

I am trying to learn about how to put numbers into an array with nsnumber. The exact thing I'm stuck with is, To build the sequence in the array, we're going to need a loop. Between creating the sequence array and returning it, declare a for loop whose counter is limited by index + 1 and increments by one.
Since the sequence requires the two previous numbers to calculate the next one, we need to prime the sequence. We're going to need to manually pass in #0 and #1 on the first two iterations of the loop. This is what I have so far.
(NSArray *)arrayWithFibonacciSequenceToIndex:(NSUInteger)index
{
NSMutableArray *sequence = [NSMutableArray array];
for(NSUInteger i = 0; i < 1; i++)
{
index = i+1;
}
return sequence;
}
Am I on the right track? I'm not sure if my for loop is correct. Do I put sequence into the for loop and add the nsnumber #0 and #1 there or do I put those numbers into the sequence outside the loop?
To insert a number in an NSArray, you have to wrap them in a NSNumber:
NSInteger a = 5;
NSNumber number = #(a); // ou #5;
to perform mathematical operations on 2 NSNumbers, you have to convert them to integer (or double, float...) before
NSNumber * number1 = #1;
NSNumber * number2 = #6;
NSInteger sum = [number1 integerValue] + [number2 integerValue];
for the fib problem, youre loop is correct. The way I would think of this is : I add my value in the for loop, and if I'm adding the 1st or 2nd element, then I put a 0, else I sum the last 2 elements:
- (NSArray *) fibbonacciSequenceWithSize:(NSInteger)size
{
NSMutableArray * result = [NSMutableArray new];
for(NSInteger idx = 0; i < size ; i ++)
{
// first 2 numbers of fib sequence are 1
if(idx == 0 || idx == 1)
{
[result addObject:#1];
}
else
{
// Add the 2 previous number
// F2 = F1 + F0
NSinteger next = [result[idx - 2] integerValue] + [result[idx - 1] integerValue];
[result addObject:#(next)];
}
}
return [result copy]; // copy the NSMutableArray in a NSArray
}
You can clean up the code by having a Fibonacci function that provides the sum of the last two elements.
- (NSNumber *)nextFibInArray:(NSArray *)array {
if (array.count < 2) return #1;
NSInteger lastIndex = array.count - 1;
return #([array[lastIndex-1] intValue] + [array[lastIndex] intValue]);
}
Then the loop is cleaner, too.
- (NSArray *)fibonacciWithLength:(NSInteger)length {
NSMutableArray *result = [#[] mutableCopy];
for (NSInteger i=0; i<length; i++) {
[result addObject:[self nextFibInArray:result]];
}
return result;
}
We could trim some execution time fat from this, but for short enough sequences, this should be clear and quick enough.

Concatenate a NSInteger to NSInteger

i'm making my own calculator and i came to the question.
Sorry for newbie question , but I didn't find it.
How can i append a NSInteger to another NSInteger in Objective-C;
for example:
5 + 5 = 55
6 + 4 + 3 = 643
etc.
You have to convert them to strings. Here's one way:
NSNumber *i1 = #6;
NSNumber *i2 = #4;
NSNumber *i3 = #3;
NSMutableString *str = [NSMutableString new];
[str appendString:[i1 stringValue]];
[str appendString:[i2 stringValue]];
[str appendString:[i3 stringValue]];
NSLog(#"result='%#", str);
However, having said all that, it's not clear to me why you are concatenating at all.
If they are a single digit (as in a calculator) you can simply do:
NSInteger newNumber = (oldNumber * 10) + newDigit;
or in a method:
- (NSInteger)number:(NSInteger)currentNumber byAdding:(NSInteger)newDigit {
//Assumes 0 <= newDigit <= 9
return (currentNumber * 10) + newDigit;
}
If they have more than one digit you can make them into strings, concatenate them and convert back to integers or use simple arithmetic to find out the power of 10 you must multiply by.
EDIT: 6 + 4 + 3 Assuming a digit is provided at a time:
NSInteger result = [self number:[self number:6 byAdding:4] byAdding:3];
Purely arithmetic solution:
- (NSInteger)powerOfTenForNumber:(NSInteger)number {
NSInteger result = 1;
while (number > 0) {
result *= 10;
number /= 10;
}
return result;
}
- (NSInteger)number:(NSInteger)currentNumber byAdding:(NSInteger) newNumber {
return (currentNumber * [self powerOfTenForNumber:newNumber]) + newNumber;
}

How to prevent duplication when picking objects in array from random indexes [duplicate]

This question already has answers here:
Getting a random object from NSArray without duplication
(3 answers)
Closed 8 years ago.
Hi I am picking objects from one array and adding it into another. Using the below method
I am doing this in a for loop.
FirstArray = [#"object1",#"object2",#"object3",#"object4",#"object5"];
SecondArray = [#"abc",#"pqr",#"xyz",#"123"];
NSUInteger FirstArrayIndex = arc4random() % [FirstArray count];
NSUInteger SecondArrayIndex = arc4random() % [SecondArray count];
[mainArray addObject:[FirstArray objectAtIndex:FirstArrayIndex]];
[mainArray addObject:[SecondArray objectAtIndex:SecondArrayIndex]];
But when I am using this - some times the objects will get duplicated in mainArray. How to prevent this ?
Without saving the index, is there any other method to achieve this ?
Check if it exists in the destination array before adding it:
MyArray = [#"object1",#"object2",#"object3",#"object4",#"object5"];
for (NSUInteger i = 0; i < 3; i++) { // Assuming you are adding 3 objects
NSUInteger RandomIndex;
do {
RandomIndex = arc4random() % [MyArray count];
} while ([mainArray indexOfObject:[MyArray objectAtIndex:RandomIndex]] == NSNotFound)
[mainArray addObject:[MyArray objectAtIndex:RandomIndex]];
}
If you are just trying to randomize the array you use this method which this answer provides https://stackoverflow.com/a/56656/1916721:
NSUInteger count = [MyArray count];
for (NSUInteger i = 0; i < count; ++i) {
NSInteger remainingCount = count - i;
NSInteger exchangeIndex = i + arc4random_uniform(remainingCount);
[MyArray exchangeObjectAtIndex:i withObjectAtIndex:exchangeIndex];
}
You could then just pull elements one by one out of the shuffled array or copy it entirely.
The alternative would be to just check if it already exists, otherwise find another random index.
You should remove the object that you are selecting from the initial array so that you do not pick it again.

fill array with random numbers different from each others? [duplicate]

This question already has answers here:
List of random numbers - arc4random
(2 answers)
Closed 9 years ago.
I would like to have an array with 12 numbers -> 0 to 11
the array must be random, and i don't want to have twice the same number
thanx
Sounds like a shuffling problem.
Just declare an array like follows
NSMutableArray * numbers = [NSMutableArray array];
for (int i = 0; i < 12; i++) {
[numbers addObject:#i];
}
Then you can shuffle that array using the Fisher-Yates algorithm
for (NSUInteger i = numbers.count - 1; i > 0; --i) {
NSUInteger n = arc4random_uniform(i+1);
[numbers exchangeObjectAtIndex:i withObjectAtIndex:n];
}
I suggest you create an array and fill it in a loop with the numbers 0 to 11. In a second step, you shuffle that array: What's the Best Way to Shuffle an NSMutableArray?
You could try something like:
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int i = 0; i < 12; i++) {
int randomNumber = min + rand() % (max-min);
[array addObject:[NSNumber numberWithInt:randomNumber]];
}
Not sure if the syntax is correct, im on a Windows machine now

Efficient way to generate a random alphabet string?

I want a string of all the characters of the alphabet randomized. Right now, I create a mutable array of the 26 characters, shuffle them with the exchangeObjectAtIndex: method and then add each character to a string that I return.
There has to be a better way to do this. Here is my code:
- (NSString *)shuffledAlphabet {
NSMutableArray * shuffledAlphabet = [NSMutableArray arrayWithArray:#[#"A",#"B",#"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",#"K",#"L",#"M",#"N",#"O",#"P",#"Q",#"R",#"S",#"T",#"U",#"V",#"W",#"X",#"Y",#"Z"]];
for (NSUInteger i = 0; i < [shuffledAlphabet count]; ++i) {
// Select a random element between i and end of array to swap with.
int nElements = [shuffledAlphabet count] - i;
int n = (random() % nElements) + i;
[shuffledAlphabet exchangeObjectAtIndex:i withObjectAtIndex:n];
}
NSString *string = [[NSString alloc] init];
for (NSString *letter in shuffledAlphabet) {
string = [NSString stringWithFormat:#"%#%#",string,letter];
}
return string;
}
Here's an efficient Fisher-Yates shuffle, adapted to your use case:
- (NSString *)shuffledAlphabet {
NSString *alphabet = #"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Get the characters into a C array for efficient shuffling
NSUInteger numberOfCharacters = [alphabet length];
unichar *characters = calloc(numberOfCharacters, sizeof(unichar));
[alphabet getCharacters:characters range:NSMakeRange(0, numberOfCharacters)];
// Perform a Fisher-Yates shuffle
for (NSUInteger i = 0; i < numberOfCharacters; ++i) {
NSUInteger j = (arc4random_uniform(numberOfCharacters - i) + i);
unichar c = characters[i];
characters[i] = characters[j];
characters[j] = c;
}
// Turn the result back into a string
NSString *result = [NSString stringWithCharacters:characters length:numberOfCharacters];
free(characters);
return result;
}
This is the more efficient way to perform a correctly shuffled alphabet generation.
- (NSString *)shuffledAlphabet
{
const NSUInteger length = 'Z' - 'A' + 1;
unichar alphabet[length];
alphabet[0] = 'A';
for ( NSUInteger i = 1; i < length; i++ )
{
NSUInteger j = arc4random_uniform((uint32_t)i + 1);
alphabet[i] = alphabet[j];
alphabet[j] = 'A' + i;
}
return [NSString stringWithCharacters:alphabet length:length];
}
It uses the "inside-out" version of the Fischer Yates shuffle and avoids modula bias by generating the pseudorandom numbers with arc4random_uniform. Also, it requires a single allocation as all the permutations are performed in a temporary buffer.
Generating random numbers in Objective-C does this help?
*generate random number
*divide by 26 and take reminder
*index array[reminder]
You could pick random elements from the (remaining) alphabet while you build your string instead of shuffling it first:
NSMutableArray *alphabet = [NSMutableArray arrayWithObjects:#"A",#"B",#"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",#"K",#"L",#"M",#"N",#"O",#"P",#"Q",#"R",#"S",#"T",#"U",#"V",#"W",#"X",#"Y",#"Z", nil];
NSMutableString *result = [NSMutableString string];
NSUInteger numberOfLetters = alphabet.count;
for (NSUInteger i = 0; i < numberOfLetters; i++) {
int n = arc4random() % alphabet.count;
[result appendString:[alphabet objectAtIndex:n]];
[alphabet removeObjectAtIndex:n];
}
NSLog(#"%#", result);
This makes the code a bit shorter. Note also that using NSMutableString is more efficient than creating a new NSString each time a letter is added.

Resources