How to Increment numbers in an array to populate UIPickerView - ios

I have a UIPickerView that I am populating with an array. It has two columns and i need the first column to go from 50-500. the second column to go from 0.01 to 1. The point is for the user to pick their weight. For doing the 50-500 I have this,
-(void)populateWeightPickerArray{
weightPickerArray = [[NSMutableArray alloc] init];
for (int weight = 50; weight <=500; weight++) {
NSString *weightString = [NSString stringWithFormat:#"%d%",weight];
[weightPickerArray addObject:weightString];
}
}
I tried doing that with the decimal, however when i use ++ it goes up by whole number and I end up getting 1.01, 2.01, 3.01 etc. here is what I have for code.
-(void)populateWeightPickerArray2{
weightPickerArray2 = [[NSMutableArray alloc] init];
for (float weightDecimal = .01; weightDecimal <= 10; weightDecimal++) {
NSString *weightDecimalString = [NSString stringWithFormat:#"%0.2f",weightDecimal];
[weightPickerArray2 addObject:weightDecimalString];
}
}
(I know i said I only needed it to go to 1 not 10, but i put 10 because at first it was only displaying 1.01, so i put 10 to test the output until I can get it right.)
So i need to somehow increment it to make it go from .01 to 1 (0.02, 0.03,0.04 etc). Anyone know how to do this?

for (float weightDecimal = .01; weightDecimal <= 10; weightDecimal = weightDecimal + 0.01)
or more succinctly:
for (float weightDecimal = .01; weightDecimal <= 10; weightDecimal += 0.01)
In Objective C: x += y is a shorthand for x = x + y.
Although you often see for loops with something++ or something-- you can use any expression.

Related

How to create random numbers for multiple images to show randomly in Grid without repetition in iOS?

I create GridView in SpriteKit.my requirement is to shuffle images randomly in Grid View.
Here is my code to show images randomly without repetition.but this code is working for only two images.for multiple images this code is not working.
int RandomRowMainImage = arc4random_uniform(3);
int RandomColumnMainImage = arc4random_uniform(3);
//
int RandomRowOtherImage = arc4random_uniform(3);
int RandomColumnOtherImage = arc4random_uniform(3);
NSLog(#"RandomRowMain:%d \n Random Column :%d \n RandomRow1:%d \n randomColumn1 :%d",RandomRowMainImage,RandomColumnMainImage,RandomRowOtherImage,RandomColumnOtherImage);
//
BOOL checkStatus = [self checkRandomNumberColumRowLogic:RandomRowMainImage withMainRow:RandomColumnMainImage withOtherColumn:RandomColumnOtherImage withOtherRow:RandomRowOtherImage];
if (checkStatus) {
imgIcons.position = [self GridPosition:MainRowCount Column:MainColumnCount];
imgOtherImage.position = [self GridPosition:otherRowCount Column:otherColumnCount];
}
than Code for Position of Images
//Grid Position
-(CGPoint)GridPosition:(int)Row Column:(int)Column
{
CGFloat offset = SizeOfGrid / 2.0 + 0.5;
CGFloat x = Column * SizeOfGrid - (SizeOfGrid*TotalCol)/2.0 + offset;
CGFloat y = (TotalRows-Row-1) * SizeOfGrid -(SizeOfGrid*TotalRows)/2.0 + offset;
return CGPointMake(x, y);}
//Code to check prevent duplication of repeat random number for Two Images.
- (BOOL)checkRandomNumberColumRowLogic:(int)MainColumn withMainRow:(int)mainRow withOtherColumn:(int)otherColumn withOtherRow:(int)otherRow {
BOOL CompareRow = false;
BOOL CompareColumn = false;
if (mainRow == otherRow) {
int otherRow = 0;
for (int i = 0; i < TotalCol; i++ ) {
otherRow = [self checkRandomNumberCompare:otherRow];
if (MainColumn == otherRow) {
CompareRow = true;
break;
}
}
MainColumnCount = mainRow;
otherColumnCount = otherRow;
}
else {
CompareRow = true;
MainRowCount = mainRow;
otherRowCount = otherRow;
}
if (MainColumn == otherColumn) {
int otherCol = 0;
for (int i = 0; i < TotalCol; i++ ) {
otherCol = [self checkRandomNumberCompare:otherColumn];
if (MainColumn == otherCol) {
CompareColumn = true;
break;
}
}
MainColumnCount = MainColumn;
otherColumnCount = otherCol;
}
else {
CompareColumn = true;
MainColumnCount = MainColumn;
otherColumnCount = otherColumn;
}
if(CompareRow == CompareColumn) {
return true;
} else {
return false;
}
}
-(int)checkRandomNumberCompare:(int)compareRow {
int compareDiff = arc4random_uniform(TotalRows);
return compareDiff;
}
can you please help to display multiple images without repeat? like one time one image in Node
Sorry, but the logic of your checkRandomNumberColumRowLogic: method baffles me. Given two coordinates (x1, y1) and (x2, y2) then they represent the same point if and only if x1 == x2 and y1 == y2, and if this is not fall then they represent different points.
Here is the outline of a possible algorithm to solve your problem. First consider that given a rectangular grid of cells where the rows and columns are numbered starting from 0 then each cell can be assigned a unique number by multiplying its row index by the number of columns and adding in its column index. A diagram is worth a thousand words, given a 3 x 3 grid you get the numbering:
0 1 2
3 4 5
6 7 8
Note that given a cell number the row & column it represents can be calculated using integer division and remainder.
Doing the above reduces your problem to producing the numbers from 0 to rowCount x colCount - 1 in some random order.
There are a number of ways in which you can do this, here is one:
Set upperLimit to rowCount x colCount - 1
Generate a random number r between 0 and upperLimit
Check if cell r is occupied, if it is add 1 to r and repeat this step
Place next image into cell r
Subtract 1 from upperLimit and goto step 2 if the result is greater than 0 (of course "goto" here translates to a "while" in code)
They key to avoiding duplicates is step 3, and the algorithm guarantees that step 3 will always find an unoccupied cell – proving that is left as an exercise.
HTH
I'd agree with the answer above that your logic is overly complicated. If you give an index to each image as suggested, e.g. for a 3x4 grid:
0 1 2
3 4 5
6 7 8
9 10 11
You could then randomise the grid and exchange those images. The following code would achieve this:
-(void)createRandomGridArrays
{
NSInteger columnLength = 3;
NSInteger rowLength = 4;
// Create an array of NSNumbers up to the max then randomise
NSMutableArray *indexes = [NSMutableArray new];
for (NSInteger i=0; i<columnLength*rowLength; i++) {
[indexes addObject:#(i)];
}
NSArray *randomIndexes = [self shuffleArray:indexes];
NSLog(#"%# -> %#", indexes, randomIndexes);
// (0,1,2,3,4,5,6,7,8,9,10,11) -> (1,0,6,10,4,2,7,11,9,5,8,3)
// Convert indexes back to row/columns
for (NSNumber *randomIndex in randomIndexes) {
NSInteger index = [randomIndex integerValue];
NSInteger row = index % rowLength;
NSInteger column = index % columnLength;
NSLog(#"%ld row:%ld, column:%ld", index, row, column);
}
}
-(NSArray*)shuffleArray:(NSArray*)array
{
NSMutableArray *shuffledArray = [array mutableCopy];
for (NSInteger i=shuffledArray.count-1; i>0; i--) {
[shuffledArray exchangeObjectAtIndex:i withObjectAtIndex:arc4random_uniform(i+1)];
}
return shuffledArray;
}
If you had an NSMutableArray of images you would then just exchange the image at index with the image at [randomIndexes[index] integerValue].

conversion of decimal to binary output

I am facing problem with the objective c code to convert decimal to binary. When I enter small values it shows me the output.
For e.g. 12 -> 1010
But when I enters large numbers, it shows me the output as "10..." (includes dots in the output)
Please help me.
My program is as follows:
NSUInteger x = [newDec integerValue];
//int y[30];
int i=0;
int m =1;
while (x != 0) {
int mod = x % 2;
x /= 2;
i = i + mod * m;
m = m * 10;
string = [NSString stringWithFormat:#"%d", i];
}
There are two problems with your code.
1) Your label size is perhaps not able to accommodate your string. So check the length of it.
2) Your code will not support the conversion if value of x is large. The reason is that int has limited capacity. Check this question regarding memory size of in-built variable. So, consider making your string mutable and add 0s or 1s in it. I am attaching my snippet of code.
NSMutableString *string = [[NSMutableString alloc] init];
while (x != 0) {
int mod = x % 2;
x /= 2;
[string insertString:[NSString stringWithFormat:#"%d", mod] atIndex:0];
}
NSLog(#"String = %#", string);

Storing functions in an array and applying them to an array of numbers

I've prototyped an algorithm for my iOS game in Python, and I need to rewrite in in ObjC. Basically, I have a board of 16 numbers, and I want to loop through every number three times and the four functions I'm using (add, subtract, multiply, exponentiate). 1+2+3, 2*3-4, 3^4-5, 9-4^3, etc., but without order of operations (first operation is always done first).
What I would like is an overview of how this might be implemented in Objective-C. Specifically, what is the equivalent of an array of functions in Objective-C? Is there an easy way to implement it with selectors? What's the best structure to use for loops with numbers? Array of NSIntegers, array of ints, NSArray/NSMutableArray of NSNumbers?
import random as rand
min = 0
max = 9
max_target = 20
maximum_to_calculate = 100
def multiply(x, y):
return x * y
def exponate(x, y):
return x ** y
def add(x, y):
return x + y
def subtract(x, y):
return x - y
function_array = [multiply, exponate, add, subtract]
board = [rand.randint(min, max) for i in xrange(0, 16)]
dict_of_frequencies = {}
for a in board:
for b in board:
for first_fun in function_array:
first_result = first_fun(a, b)
for c in board:
for second_fun in function_array:
final_result = second_fun(first_result, c)
if final_result not in dict_of_frequencies:
dict_of_frequencies[final_result] = 0
dict_of_frequencies[final_result] += 1
The most convenient way in Objective-C to construct an array of functions would be to use Blocks:
typedef NSInteger (^ArithmeticBlock)(NSInteger, NSInteger);
ArithmeticBlock add = ^NSInteger (NSInteger x, NSInteger y){
return x + y;
};
ArithmeticBlock sub = ^NSInteger (NSInteger x, NSInteger y){
return x - y;
};
NSArray * operations = #[add, sub];
Since there's no great way to perform arithmetic on NSNumbers, it would probably be best to create and store the board's values as primitives, such as NSIntegers, in a plain C array. You can box them up later easily enough, if necessary -- #(boardValue) gives you an NSNumber.
If you want to do it with straight C function pointers, something like this will do it:
#include <stdio.h>
#include <math.h>
long add(int a, int b) {
return a + b;
}
long subtract(int a, int b) {
return a - b;
}
long multiply(int a, int b) {
return a * b;
}
long exponate(int a, int b) {
return pow(a, b);
}
int main(void) {
long (*mfunc[4])(int, int) = {add, subtract, multiply, exponate};
char ops[4] = {'+', '-', '*', '^'};
for ( int i = 0; i < 4; ++i ) {
printf("5 %c 9 = %ld\n", ops[i], mfunc[i](5, 9));
}
return 0;
}
and gives the output:
paul#MacBook:~/Documents/src$ ./rndfnc
5 + 9 = 14
5 - 9 = -4
5 * 9 = 45
5 ^ 9 = 1953125
paul#MacBook:~/Documents/src$
Function pointer syntax can be slightly convoluted. long (*mfunc[4])(int, int) basically translates to defining a four-element array, called mfunc, of pointers to functions returning long and taking two arguments of type int.
Maddy is right. Anyway, I'll give it a try just for the fun of it.
This has never seen a compiler. So please forgive me all the typos and minor syntax errors in advance.
#include <stdlib.h>
...
const int MIN = 0;
const int MAX = 9;
const int MAX_TARGET = 20;
const int MAX_TO_CALCULATE = 100;
...
- (int) multiply:(int)x with:(int)y { return x * y; }
- (int) exponate:(int)x with:(int)y { return x ^ y; }
- (int) add:(int)x to:(int)y { return x + y; }
- (int) substract:(int)x by:(int)y { return x - y; }
// some method should start here, probably with
-(void) someMethod {
NSArray *functionArray = [NSArray arrayWithObjects: #selector(multiply::), #selector(exponate::), #selector(add::), #substract(multiply::), nil]; // there are other ways of generating an array of objects
NSMutableArray *board = [NSMutableArray arrayWithCapacity:16]; //Again, there are other ways available.
for (int i = 0; i < 16; i++) {
[board addObject:#(arc4random() % (MAX-MIN) + MIN)];
}
NSMutableDictionary dictOfFrequencies = [[NSMutableDictionary alloc] init];
for (NSNumber a in board)
for (NSNumber b in board)
for (SEL firstFun in functionArray) {
NSNumber firstResult = #([self performSelector:firstFun withObject:a withObject:b]);
NSNumber countedResults = [dictOfFrequencies objectForKey:firstResult];
if (countedResults) {
[dictOfFrequencies removeObjectForKey:firstResult];
countedResults = #(1 + [countedResults intValue]);
} else {
countedResults = #1; // BTW, using the # followed by a numeric expression creates an NSNumber object with the value 1.
}
[dictOfFrequencies setObject:countedResults forKey:firstResult];
}
}
Well, let me add some comments before others do. :-)
There is no need for objective c. You python code is iterative therefore you can implement it in plain C. Plain C is available where ever Objective C is.
If you really want to go for Objective-C here then you should forget your python code and implement the same logic (aiming for the same result) in Objective-C in an OOP style. My code really tries to translate your code as close as possible. Therefore my code is far far away from neither beeing good style nor maintainable nor proper OOP. Just keep that in mind before you think, ObjC was complicated compared to python :-)

Take average of segments of NSArray

I have an NSArray of 100 numbers. I would like to create an NSArray of 5 numbers. The first number in the second array is the average of the first 20 numbers in the first array. The second number is the average of the second set of 20 numbers in the first array. And so on.
I'm curious to hear people's ideas for an efficient algorithm.
One idea I had was to do a for-loop on each set of 20 numbers, creating a temp NSArray of 20 numbers. Then perform a KVO average operation and add to the final NSArray.
Note: I always award THE answer to someone, and I'm not shy to up vote your answers. I encourage many answers. Thanks!
Just add the values in each 20 number section, divide by 20 and put in the appropriate output array location. It is one pass through the array, Big O(n), what more could you ask for? The time to compute this is minuscule.
The following is simple and efficient:
NSArray *numbers = ... // array of 100 numbers
NSMutableArray *averages = [NSMutableArray array];
for (int = 0; i < 5; i++) {
float total = 0.0;
int base = i * 20;
for (int j = 0; j < 20; j++) {
float num = [numbers[base + j] floatValue];
total += num;
}
float avg = total / 20.0f;
[averages addObject:#(avg)];
}
NSLog(#"Averages = %#", averages);
you could try something like this...
NSArray *_array = // with the 100 numbers... (I used NSNumber object for each number)
NSMutableArray *_averages = [NSMutableArray array];
for (int i = 0; i < 5; i++) [_averages addObject:#([[[_array subarrayWithRange:NSMakeRange(i * 20, 20)] valueForKeyPath:#"#avg.floatValue"] floatValue])];
the _averages will contain 5 values with the averages of the five different sections of the 100 numbers.
UPDATED:
this part is just for eyes with extra curiosity.
if you tries to avoid the NSObjects and the double for loops, you could achieve a really fast algorithm, and of course when you go lower levels, you can improve the current speed as well, the question is: does it really need?
NSInteger _segments = 1000; // it means 20.000 numbers;
Float64 _numbers[(_segments * 20)]; // fill this array as you'd like.
Float64 _averages[_segments];
for (int i = 0; i < _segments; i++) {
NSInteger _offset = (_segments<<4)+4;
_averages[i] = (_numbers[_offset] + _numbers[_offset+1] + _numbers[_offset+2] + _numbers[_offset+3] + _numbers[_offset+4] + _numbers[_offset+5] + _numbers[_offset+6] + _numbers[_offset+7] + _numbers[_offset+8] + _numbers[_offset+9] + _numbers[_offset+10] + _numbers[_offset+11] + _numbers[_offset+12] + _numbers[_offset+13] + _numbers[_offset+14] + _numbers[_offset+15] + _numbers[_offset+16] + _numbers[_offset+17] + _numbers[_offset+18] + _numbers[_offset+19]) / 20.f;
}
it is 10 times faster than the solution with double for loops and NSObject classes.
(un)fortunately, it is not even the ugliest solution, but there is no question it is fast as hell, I won't recommend it except the speed really matter because that kind of solutions can provide really good efficiency.

What is the proper way to calculate knot vector for the Cox De Boor algorithm?

I am currently trying to implement the Cox De Boor algorithm for drawing bezier curves. I've managed to produce something acceptable with a set degree, number of control points and a predefined knot vector, but I want to adapt my code so that it will function given any number of control points and any degree. I'm 90% certain that the problems I am currently encountering, i.e. that the path goes wandering off to point 0/0, are due to me not properly calculating knot vectors. If anyone can give me a hint or two I'd be grateful. Note that I am presently calculating each dimension (in this case just x and y) individually; I will eventually adapt this code to use the same precalculations for all dimensions. I may also adjust it to use C arrays rather than NSArrays, but from what I've seen there's no real speed advantage to doing so.
I am currently producing a degree 3 curve using 5 control points with a knot vector of {0, 0, 0, 0, 1, 2, 2, 2, 2}.
- (double) coxDeBoorForDegree:(NSUInteger)degree span:(NSUInteger)span travel:(double)travel knotVector:(NSArray *)vector
{
double k1 = [[vector objectAtIndex:span] doubleValue];
double k2 = [[vector objectAtIndex:span+1] doubleValue];
if (degree == 1) {
if (k1 <= travel && travel <= k2) return 1.0;
return 0.0;
}
double k3 = [[vector objectAtIndex:span+degree-1] doubleValue];
double k4 = [[vector objectAtIndex:span+degree] doubleValue];
double density1 = k3 - k1;
double density2 = k4 - k2;
double equation1 = 0.0, equation2 = 0.0;
if (density1 > 0.0) equation1 = ((travel-k1) / density1) * [self coxDeBoorForDegree:degree-1 span:span travel:travel knotVector:vector];
if (density2 > 0.0) equation2 = ((k4-travel) / density2) * [self coxDeBoorForDegree:degree-1 span:span+1 travel:travel knotVector:vector];
return equation1 + equation2;
}
- (double) valueAtTravel:(double)travel degree:(NSUInteger)degree points:(NSArray *)points knotVector:(NSArray *)vector
{
double total = 0.0;
for (NSUInteger i = 0; i < points.count; i++) {
float weight = [self coxDeBoorForDegree:degree+1 span:i travel:travel knotVector:vector];
if (weight > 0.001) total += weight * [[points objectAtIndex:i] doubleValue];
}
return total;
}
Never mind, I found this very useful webpage:
http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/INT-APP/PARA-knot-generation.html
Hence anyone with the same problem can use the following method to generate a suitable knot vector, where 'controls' is the number of control points affecting the line segment, and 'degree' is... well, the degree of the curve! Don't forget that degree cannot equal or exceed the number of control points in the curve:
- (NSArray *) nodeVectorForControlCount:(NSUInteger)controls degree:(NSUInteger)degree
{
NSUInteger knotIncrement = 0;
NSUInteger knotsRequired = controls + degree + 1;
NSMutableArray *constructor = [[NSMutableArray alloc] initWithCapacity:knotsRequired];
for (NSUInteger i = 0; i < knotsRequired; i++) {
[constructor addObject:[NSNumber numberWithDouble:(double)knotIncrement]];
if (i >= degree && i < controls) knotIncrement++;
}
NSArray * returnArray = [NSArray arrayWithArray:constructor];
[constructor release];
return returnArray;
}

Resources