Creating a Balancing Class to Balance Weights - objective-c

First of all I must admit that it is my assignment. But I am not asking anyone to solve it but I am working hard to solve it and need help with my algorithm.
I have an array of weights that is assigned to leftSide and rightSide of a scale. I need to balance the weights in right side and left side using the weights in the array.
I have the following code but it does not cover all the situations:
-(BOOL) isBalanced
{
_weights = [NSMutableArray arrayWithArray:#[#3,#4,#2,#1,#5,#6,#4]];
self.leftSide = [[_weights objectAtIndex:arc4random() % 7] integerValue]; // random weight
self.rightSide = [[_weights objectAtIndex:arc4random() % 7] integerValue]; // random weight
if(self.leftSide == self.rightSide) return YES; // already balanced
if(self.leftSide > self.rightSide)
{
// add weights on right side
int difference = self.leftSide - self.rightSide;
int index = [_weights indexOfObject:[NSNumber numberWithInt:difference]];
self.rightSide += [[_weights objectAtIndex:index] integerValue];
NSLog(#"%d",index);
}
else
{
int difference = self.rightSide - self.leftSide;
int index = [_weights indexOfObject:[NSNumber numberWithInt:difference]];
self.leftSide += [[_weights objectAtIndex:index] integerValue];
NSLog(#"%d",index);
}
return self.leftSide == self.rightSide;
}
UPDATE:
To simplify! I have a number 6 and now I need to search inside an array of ints if any of the numbers can be added together to get 6. Example:
1,2,3,5,4
In the above array I can take 1+2+3 which makes 6. I can also take 4+2 which is 6. The question is how do I find those individual numbers that can sum up to the number 6.

Related

Get sequence of random numbers' pairs (Objective-c)

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])
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
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);
}

Add missing years and corresponding values into arrays

I've been messing around with the JBChartView library and it seems really good for charting. It's easy enough to use but i'm having some problems getting my data in a format that i need for a particular chart.
The user can enter a value and corresponding year. This is saved using core data. The data could look like as follows:
Year: 0 Value: 100
Year:2 Value 200
Year 3 Value 150
I would create 2 arrays, 1 for the year number and another for the value. in this case though, I would get 3 bars. What i'd like is a bar with value 0 for Year 1.
I think the best way to approach this would be to look through the Year array, check to see if the first value is 0, then check if every consecutive year value is +1. If not, add 1 to the previous year and insert a value of 0 into the values array at the same index position.
I would like to know if this is the best approach and if I could get some help doing the comparison.
Thanks
Ok I got to an answer to my own question and thought i'd post it as it may help someone in the future, especially when creating charts using this, or other libraries.
I first populate 2 mutable arrays
chartLegend = [NSMutableArray arrayWithObjects:#1,#3, nil];
chartData = [NSMutableArray arrayWithObjects:#"100",#"300", nil];
So i've got years 1 and 3, each with an associated value in the chartData array.
i now need to create a year 0 and year 2 so that my bar chart has a bar for every year from 0 to my maximum year, 3.
- (void)addItemsToArray {
for (int i=0; i<[chartLegend count]; i++)
{
//get the values from our array that are required for any calculations
int intPreviousValue = 0;
int intCurrentValue = [[chartLegend objectAtIndex:i]integerValue];
if (i>0)
{
intPreviousValue = [[chartLegend objectAtIndex:(i-1)]integerValue];
}
//Deal with the first item in the array which should be 0
if (i == 0)
{
if (intCurrentValue != 0)
{
[chartLegend insertObject:[NSNumber numberWithInt:0] atIndex:i];
[chartData insertObject:[NSNumber numberWithInt:0] atIndex:i];
}
}
//Now deal with all other array items
else if (intCurrentValue - intPreviousValue !=1)
{
int intNewValue = intPreviousValue +1;
[chartLegend insertObject:[NSNumber numberWithInt:intNewValue] atIndex:i];
[chartData insertObject:[NSNumber numberWithInt:0] atIndex:i];
}
}
//create a string with all of the values in the array
NSString *dates = [chartLegend componentsJoinedByString:#","];
NSString *values = [chartData componentsJoinedByString:#","];
//display the text in a couple of labels to check you get the intended result
self.yearsLabel.text = dates;
self.valuesLabel.text = values;
}
That seems to be working for me. It should be easy enough to populate your arrays using coreData information, just make sure it's sorted first.

How to print out an integer raised to the 100th power (handling overflow)

So my friend asked me this question as interview practice:
Using Objective-C & Foundation Kit, Write a method that takes a single digit int, and logs out to the console the precise result of that int being raised to the power of 100.
Initially I thought it sounded easy, but then I realized that even a single digit number raised to the power of 100 would quickly come close to 100 digits, which would overflow.
So I tried tackling this problem by creating an NSArray w/ NSNumbers (for reflection), where each object in the array is a place in the final result number. Then I perform the multiplication math (including factoring in carries), and then print out a string formed by concatenating the objects in the array. Here is my implementation w/ input 3:
NSNumber *firstNum = [NSNumber numberWithInteger:3];
NSMutableArray *numArray = [NSMutableArray arrayWithArray:#[firstNum]];
for( int i=0; i<99; i++)
{
int previousCarry = 0;
for( int j=0; j<[numArray count]; j++)
{
int newInt = [firstNum intValue] * [[numArray objectAtIndex:j] intValue] + previousCarry;
NSNumber *calculation = [NSNumber numberWithInteger:newInt];
previousCarry = [calculation intValue]/10;
NSNumber *newValue = [NSNumber numberWithInteger:(newInt % 10)];
[numArray replaceObjectAtIndex:j withObject:newValue];
}
if(previousCarry > 0)
{
[numArray addObject:[NSNumber numberWithInteger:previousCarry]];
}
}
NSArray* reversedArray = [[numArray reverseObjectEnumerator] allObjects];
NSString *finalNumber = [reversedArray componentsJoinedByString:#""];
NSLog(#"%#", finalNumber);
This isn't a problem out of a textbook or anything so I don't have any reference to double check my work. How does this solution sound to you guys? I'm a little worried that it's pretty naive even though the complexity is O(N), I can't help but feel like I'm not utilizing a type/class or method unique to Objective-C or Foundation Kit that would maybe produce a more optimal solution-- or at the very least make the algorithm cleaner and look more impressive
Write a method that takes a single digit int, and logs out to the console the precise result of that int being raised to the power of 100.
That strikes me as a typical interview "trick"[*] question - "single digit", "logs out to console"...
Here goes:
NSString *singleDigitTo100(int d)
{
static NSString *powers[] =
{
#"0",
#"1",
#"1267650600228229401496703205376",
#"515377520732011331036461129765621272702107522001",
#"1606938044258990275541962092341162602522202993782792835301376",
#"7888609052210118054117285652827862296732064351090230047702789306640625",
#"653318623500070906096690267158057820537143710472954871543071966369497141477376",
#"3234476509624757991344647769100216810857203198904625400933895331391691459636928060001",
#"2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376",
#"265613988875874769338781322035779626829233452653394495974574961739092490901302182994384699044001"
};
return powers[d % 10]; // simple bounds check...
}
And the rest is easy :-)
And if you are wondering, those numbers came from bc - standard command line calculator in U*ix and hence OS X. You could of course invoke bc from Objective-C if you really want to calculate the answers on the fly.
[*] It is not really a "trick" question but asking if you understand that sometimes the best solution is a simple lookup table.
As you have correctly figured out, you will need to use some sort of big integer library. This is a nice example you can refer to: https://mattmccutchen.net/bigint/
Furthermore, you can calculate x^n in O(lg(n)) rather than in O(n), using divide and conquer:
f(x, n):
if n == 0: # Stopping condition
return 1
temp = f(n/2)
result = temp * temp
if n%2 == 1:
result *= x
return result
x = 5 # Or another one digit number.
n = 100
result = f(x, 100) # This is the result you are looking for.
Note that x represents your integer and n the power you are raising x to.

Prime Generator not working

I want to write a really simple prime app. But i am having some problems with the code below it should generate primes from 0 to 99. But instead it just shows 99.
One problem is that only the last number is displayed. But the other one is that the prime "check" doesn't work. How can I fix those problems.
for (i=0; i<100; i++) {
for (n=2; n<i; n++) {
if (i%n == 0) break;
else primetext.text = [NSString stringWithFormat:#"%i, ", i];
}
}
There were a number of problems, I'll try to explain them
The problem with prime checking was that you had the if-else statement inside of the for loop that iterated through the numbers to check. So if your number wasn't divisible by ANY of the numbers you check it would be registered as prime. It would also be registered n times, where n is the number of times it was found to not be divisible.
All even numbers are not prime (aside from 2), so you can do i+=2 to double your speed
You only need to check up to the square root of a number to see if it's prime.
1 isn't a prime so you don't need to include it (especially because it can make your logic more complex).
You were reassigning the string instead of adding a component to it
You were using %i instead of %d. This can sometimes cause weird errors.
Here is your method revised with these points in mind.
int maxNum = 100;
primetext.text = #"2 "; //Start knowing that 2 is the lowest prime (avoid evaluating evens)
for (i=3; i<=maxNum; i+=2) //Start at 3 and add 2 (avoid 1 and 2 as well as even numbers)
{
bool isPrime = YES; //Assume that i is prime
for (n=2; n<sqrt(i); n++) //Divide by every number up to square root
{
if (i%n == 0) //If evenly divisible by n, not a prime
{
isPrime = NO;
break; //Don't need to check any more factors, so break
}
}
if (isPrime) //If isPrime was never set to NO, i is prime
{
NSString *temp = [NSString stringWithFormat:#"%d ", i];
primetext.text = [primetext.text stringByAppendingString:temp];
}
}
Hope this helps.
You should append the number to primetext.text instead of assigning. Right now it's being reassigned on every iteration.

pattern recognition in a matrix

I'm not sure I'm giving the right name to this, but anyway I have a matrix that essentially contains 1s or 0s. The matrix is a square matrix, its size can be 3x3, 4x4 or 5x5.
By pattern matching, I mean to find some "shapes" in my matrix such as a line, a T or a U, e.g.:
0 1 0
0 1 0
1 1 1
that matrix contains a T, but it also contains 2 lines! Now if the matrix was a 4x4, the shapes don't increase but they can be positioned at more place obviously, e.g.:
0 0 0 0
1 1 1 0
0 0 1 0
1 1 1 0
That matrix would contain a U (no lines though, this is the exception, lines have the size of the matrix).
Naively since the matrix is pretty small I would have tried all possibilities for each shape I'm wiling to support, but it's not very fun. I cannot figure out any algorithm for this though, and not being able to label this operation properly doesn't help ;) Has anyone got any idea how to would do this "efficiently" ? (efficiently may be a bit of an overstatement considering the size of the matrix, but you know what I mean).
There's some ambiguity in your question. For instance, does:
1 1 1
1 1 1
1 1 1
contain 6 lines, a T, a U, and a bunch of other letters of the alphabet? Or are all letters separated? Your initial question implied that letters could be discovered in overlapping fashion, because the T template contains two lines. Thus, a matrix where all elements were 'on' would contain every possible letter/line in every possible position.
Also, I'm assuming you're only concerned about 90 degree rotations and you wouldn't want to try to find 45-degree offset letters when the matrix sizes get large enough to support it.
In terms of ease-of-implementation, the brute-force approach you're talking about (test every position for all four letter rotations) really wins out, I'd say.
Alternatively, you could get pretty fancy by (warning: vague algorithm descriptions ahead!):
1) Walking along the matrix elements until you found a 1. Then essentially flood-fill from that 1 on a stack and keep track of the direction changes. Then have some sort of rotation-invariant lookup that mapped a set of 'on' pixels to found letters.
2) Use some sort of integral-image or box-filter description to take sums of subsections of the matrix. You could then do lookups on the subsections and map the subsection sums to letter/line values.
3) Since the comments have determined that you're only really looking for 4 shapes, a new approach may be worthwhile. You're only examining 4 shapes (line, cross, T, and U) if I'm not mistaken. Each of them can be in 4 orientations. One quick tip is that you can just run the algorithm 4 times but rotate the underlying matrix by 90 degrees. Then you don't have to adjust for rotation in your algorithm. Also note that the cross only needs to be found in one orientation because it looks identical in all 4 orientations and the line is identical in two orientations. Anyway, you could save yourself some work by searching for the 'hardest' things to match first. Let's say I'm looking for an upright 'U' here:
1 0 1
1 0 1
1 1 1
I start in the top left. Rather than checking to make sure that any pixels are 'off' (or 0), I go to the next place I expect to find an 'on' value (or a 1). Let's say that's the pixel below the top left. I check the middle-left pixel, and indeed it's on. Then I check below that. If you develop a simple rule set for each letter, you can quickly abandon the search for it if you don't have the required values turned 'on'. If you then run the same algorithm 4 times and only search for upright values, I'm not sure you'd be able to do much better than this!
The approaches I've mentioned are just ideas. They may be more trouble than they're worth in terms of efficiency gains, though. And who knows, they may not work at all!
Good luck!
I thought I could contribute with what I ended up doing so here it is, following aardvarkk idea. (objective-c code) I wasn't very pedantic with the array size checks because my matrix is necessarily a square matrix. Also sorry if the code is ugly :D
I made a little class structure for the shapes I want to reconize, they have a list of "directions" which are essentially values of an enum.
-(BOOL)findShape:(NSInteger)size directions:(NSArray*)directions{
NSMutableArray* current = [mgs tokens];
for (int rot = 0; rot < 4; rot++) {
for (int i = 0; i < size; i++) {
for(int j = 0; j < size; j++){
NSInteger value = [[[current objectAtIndex:i] objectAtIndex:j] integerValue];
if(value){
BOOL carryOn = [self iterateThroughDirections:directions i:i j:j tokens:current size:size];
if(carryOn){
return YES;
}
}
}
}
current = [self rotate:current];
}
return NO;
}
-(BOOL) iterateThroughDirections:(NSArray*)directions i:(NSInteger)i j:(NSInteger)j tokens:(NSMutableArray*)tokens size:(NSInteger)size{
BOOL carryOn = YES;
for(int k = 0; k < [directions count] && carryOn; k++){
NSNumber* dir = [directions objectAtIndex:k];
NSInteger d = [dir integerValue];
//move in the direction
switch (d) {
case UP:
if(i > 0){
i--;
}else{
carryOn = NO;
}
break;
case DOWN:
if(i < size-1){
i++;
}else{
carryOn = NO;
}
break;
case LEFT:
if(j > 0){
j--;
}else{
carryOn = NO;
}
break;
case RIGHT:
if(j < size-1){
j++;
}else{
carryOn = NO;
}
break;
default:
NSAssert(NO, #"invalid direction");
break;
}
NSInteger v = [[[tokens objectAtIndex:i] objectAtIndex:j] integerValue];
//now that we moved, check if the token is active, if it's not we're done
if(!v){
carryOn = NO;
break;
}
}
return carryOn;
}
-(NSMutableArray*)rotate:(NSMutableArray*)matrix{
NSInteger w = [matrix count];
NSInteger h = [[matrix objectAtIndex:0] count];
NSMutableArray* rotated = [[NSMutableArray arrayWithCapacity:h] retain];
for (int i = 0; i < h; i++) {
[rotated addObject:[NSMutableArray arrayWithCapacity:w]];
}
for(int i = 0; i < h; ++i){
for(int j = 0; j < w; ++j){
[[rotated objectAtIndex:i] addObject:[[matrix objectAtIndex:j] objectAtIndex:h-i-1]];
}
}
return rotated;
}
This seems to be working well for me! Thanks again for the help!