The below code works, but I'm trying to come up with some math logic and use some binary operator to put in place of this if statement.
NSInteger indexCor = 0;
for (PFObject *object in self.objects) {
if (object == custom) {
if (indexCor < 2) {
NSLog(#"rodou indexCor <=2.");
[self.coresConjugadosDict setObject:self.uiColorsArray[0] forKey:object.objectId];
indexCor++;
}
else if (indexCor < 4) {
[self.coresConjugadosDict setObject:self.uiColorsArray[1] forKey:object.objectId];
indexCor++;
}
else if (indexCor < 6) {
[self.coresConjugadosDict setObject:self.uiColorsArray[2] forKey:object.objectId];
indexCor++;
}
else if (indexCor < 8) {
[self.coresConjugadosDict setObject:self.uiColorsArray[3] forKey:object.objectId];
indexCor++;
}
else if (indexCor < 10) {
[self.coresConjugadosDict setObject:self.uiColorsArray[4] forKey:object.objectId];
indexCor++;
}
else if (indexCor < 12) {
[self.coresConjugadosDict setObject:self.uiColorsArray[5] forKey:object.objectId];
indexCor++;
}
else {
[self.coresConjugadosDict setObject:self.uiColorsArray[6] forKey:object.objectId];
indexCor++;
}
}
So basically, some objects are going to be combined with another object. What I need to do is to set one UIColor for each group of two combined objects. I have a NSArray with the UIColors I want to use, and right now, what happens is that each object that meets the specific criteria I add the first color in the array, increment it. This way, each group of two objects will be of a different color.
So, if have 6 objects...
Objects 1,2 = Color 1 Objects 3,4 = Color 2 Objects 5,6 = Color 3
and so on.
I would like to achieve this without the if statement.
It looks like you'd like to make these transformation:
indexCor uiColorsArray index
-------- -------------------
0, 1 0
2, 3 1
4, 5 2
6, 7 3
8, 9 4
10, 11 5
12 and up 6
This can be achieved by integer-dividing indexCor by 2, and limiting the result to 6, like this:
[self.coresConjugadosDict
setObject:self.uiColorsArray[min(indexCor++/2, 6)]
forKey:object.objectId];
Note: you may need to define your own min function to use the above code; the code above will not work correctly with a simple MIN macro, unless you move indexCor++ on a separate line.
Demo of the concept on ideone.
I've created a TTT game. However I'm having trouble with the AI taking spots. How do I avoid this from happening so that in the chooseCellRow:Col method it only returns a random spot that has not already been selected by either player?
- (void) chooseCellRow:(NSInteger)row Col:(NSInteger)col
{
//pick random spot for computer's turn
row = random()%2;
col = random()%2;
if (row == 0 && col == 0) {
[but00 setTitle:#"X" forState:0];
}
else if (row == 0 && col == 1) {
[but01 setTitle:#"X" forState:0];
}
else if (row == 0 && col == 2) {
[but02 setTitle:#"X" forState:0];
}
else if (row == 1 && col == 0) {
[but10 setTitle:#"X" forState:0];
}
else if (row == 1 && col == 1) {
[but11 setTitle:#"X" forState:0];
}
else if (row == 1 && col == 2) {
[but12 setTitle:#"X" forState:0];
}
else if (row == 2 && col == 0) {
[but20 setTitle:#"X" forState:0];
}
else if (row == 2 && col == 1) {
[but21 setTitle:#"X" forState:0];
}
else if (row == 2 && col == 2) {
[but22 setTitle:#"X" forState:0];
}
}
Cheating is a moral concept, one which doesn't apply to the computer since it's doing exactly what you've told it to do. However, you could prevent this by simply choosing again if the cell is already occupied, pseudo-code:
row = random() % 3;
col = random() % 3;
while cell[row][col] != empty: # Add your REAL detection code here.
row = random() % 3;
col = random() % 3;
You'll also notice that the above code stops you from cheating as well. Shame on you for only allowing the computer to choose four of the nine possibilities :-)
Applying % 2 to a number will give you 0 or 1, you need to use % 3 to allow for 2 as well.
Based on your comments that you have a cell array which contains the character occupying that cell, the code to continuse until you find a blank cell would be along the lines of:
do {
row = random() % 3;
col = random() % 3;
} while (cell[row][col] != ' ');
One easy way would be to keep a list of unused positions and choose from that list. When either player moves, remove the position they choose from the list.
Another, even simpler but less efficient way is to have it choose any position, but try again if the spot it picks is already occupied.
This question already has answers here:
Expression in FOR command (for (int i=0; i < ([arr count]-1);i++){})
(3 answers)
Closed 9 years ago.
This works:
int i, start, end;
start = m_cardArr.count - 1;
end = m_cardArr.count - 4;
NSLog(#"%i %i", m_cardArr.count - 1, m_cardArr.count - 4);
for(i = start; i > end; i--)
{
LabyrinthCard* labyCard = (LabyrinthCard*)[m_cardArr objectAtIndex:i];
if(labyCard.m_type != cardType || labyCard.m_usedForDoor)
{
return false;
}
}
This doesn't enter the for loop at all:
int i;
NSLog(#"%i %i", m_cardArr.count - 1, m_cardArr.count - 4);
for(i = m_cardArr.count - 1; i > m_cardArr.count - 4; i--)
{
LabyrinthCard* labyCard = (LabyrinthCard*)[m_cardArr objectAtIndex:i];
if(labyCard.m_type != cardType || labyCard.m_usedForDoor)
{
return false;
}
}
I am not changing the size of the array inside, so using m_cardArr.count as the conditional should work. In both cases, the NSLog prints 2, -1 when there are 3 elements in the array.
I can't figure out what I'm missing here.
This is because the count property is of type NSUInteger, i.e. an unsigned number. When you subtract 4 from it and the result becomes negative, it gets interpreted as a very large positive number.
When you assign that result to an int, you re-interpret it as a negative again, fixing the problem.
The best way of addressing this would be moving -4 to the other side of the expression, changing the sign to a +, like this:
for(i = m_cardArr.count - 1; i+4 > m_cardArr.count; i--) {
...
}
The logic behind the expression would remain the same, but you would no longer see the signed/unsigned side effects caused by subtraction.
I have the following code:
- (NSArray *)checkNormalGameDuelAndMatch:(float)nrDuelQs andNrQPerDuel:(float)nrQPerDuel andNrMatchQ:(float)nrMatchQ andActivePlayer:(float)actPlayerNrQ andInactivePlayer:(float)inactivePlayerNrQ {
NSLog(#"checkNormalGameDuelAndMatch:");
// Check for Matches and Duels to prep for swaps and/or match endings
NSArray *theCheckArray = [[NSArray alloc]init];
NSLog(#"nrDuelQs: %.0f / nrQPerDuel: %.0f", nrDuelQs, nrQPerDuel);
// Check if Match still on
NSLog(#"actPlayerNrQ: %.0f / inactivePlayerNrQ: %.0f / nrMatchQ: %.0f", actPlayerNrQ, inactivePlayerNrQ, nrMatchQ);
if (actPlayerNrQ < nrMatchQ && inactivePlayerNrQ < nrMatchQ) {
// Match is still on
_isMatchStillOn = YES;
// Check if Duel is till on
if (nrDuelQs < nrQPerDuel) {
// Duel is still on
_isDuelStillOn = YES;
NSLog(#"_isDuelStillOn = YES;");
}
else {
_isDuelStillOn = NO;
NSLog(#"_isDuelStillOn = NO;");
}
}
else {
//==MATCH IS OVER==//
_isMatchStillOn = NO;
NSLog(#"MATCH OFF");
}
theCheckArray = #[[NSNumber numberWithBool:_isDuelStillOn], [NSNumber numberWithBool:_isMatchStillOn]];
return theCheckArray;
}
With the following NSLog output, during two loops:
checkNormalGameDuelAndMatch:
nrDuelQs: 4 / nrQPerDuel: 5
actPlayerNrQ: 4 / inactivePlayerNrQ: 0 / nrMatchQ: 5
_isDuelStillOn = YES;
checkNormalGameDuelAndMatch:
nrDuelQs: 5 / nrQPerDuel: 5
actPlayerNrQ: 5 / inactivePlayerNrQ: 0 / nrMatchQ: 5
MATCH OFF
I guess there is something wrong with the If-statement and "&&" as i am not expecting the "MATCH OFF" when it comes.
I guess i am blind as this should not be complicated.
This is very likely happening because the variables are of the type float: even through they both print as 5, one of them may be actually slightly smaller than the other (say, 4.9999999999999999). This could happen because of the way actPlayerNrQ is calculated: for example, if you add 0.1 fifty times, you would not get exactly a 5.
Here is a link to an example (it is in C, but that part of the language is shared with Objective C).
float n = 0;
int i = 0;
for (i = 0 ; i != 25 ; i++, n += 0.2);
printf("%f < 5.000000 : %s", n, n < 5.0 ? "yes":"no");
This prints
5.000000 < 5.000000 : yes
To fix this, you could compare with an epsilon, for example
#define EPSILON 1E-8
// 1E-8 stands for 1*10^-8, or 0.00000001
...
if ((actPlayerNrQ - nrMatchQ) < EPSILON && (inactivePlayerNrQ - nrMatchQ) < EPSILON)
...
I just came across with this interesting question from my colleague. I'm trying now, but meanwhile I thought I could share it here.
With the password grid shown in the Android home screen, how many valid passwords are possible?
min password length: 4 max: 9 (correct me if I'm wrong)
Summary
The full combinations of 4 to 9 distinctive numbers, minus the combinations which include invalid "jump"s.
The Long Version
The rule for Android 3x3 password grid:
one point for once
cannot "jump" over a point
The author of the original post used Mathematica to generate all 985824 combinations.
Because there is no "jump", several pairs of consecutive points are invalid.
Delete all invalid combinations to reach the result.
The combinations for 4-to-9-point paths are respectively 1624, 7152, 26016, 72912, 140704, 140704.
The Original Post In Chinese
The reference is from guokr, a site alike Stack Exchange Skeptics in the form of blogs.
I know this question is old, but I answered it in another question (before finding this question) with a brute force approach in python, so adding it here for posterity:
pegs = {
1: {3:2, 7:4, 9:5},
2: {8:5},
3: {1:2, 7:5, 9:6},
4: {6:5},
5: {},
6: {4:5},
7: {1:4, 3:5, 9:8},
8: {2:5},
9: {1:5, 3:6, 7:8}
}
def next_steps(path):
return (n for n in range(1,10) if (not path or n not in path and
(n not in pegs[path[-1]]
or pegs[path[-1]][n] in path)))
def patterns(path, steps, verbose=False):
if steps == 0:
if verbose: print(path)
return 1
return sum(patterns(path+[n], steps-1) for n in next_steps(path))
So you can list all the # of patterns for any number of steps:
>>> [(steps, patterns([], steps)) for steps in range(1,10)]
[(1, 9),
(2, 56),
(3, 320),
(4, 1624),
(5, 7152),
(6, 26016),
(7, 72912),
(8, 140704),
(9, 140704)]
>>> sum(patterns([], steps) for steps in range(4,10))
389112
This is not the most efficient way of solving it because you could use reflections and only calculate a 4*corner + 4*mid-edge + 1*middle, e.g.:
>>> patterns([], 6) == 4*patterns([1], 5) + 4*patterns([2], 5) + patterns([5], 5)
True
I brute forced the answer with a recursive search and i found a bigger answer, 487272. The algorithm is simple: trying it all. I quoted it down here. I didn't found any error in my code (but I'm not very skilled with c++). Sorry for the grammatical error I'm not English.
#include <iostream>
#include <stdlib.h>
using namespace std;
int combo; //counter
void research(int Ipoints /*number of points already took*/, bool Icheck[9]/*points matrix*/,int Ilast/*last took point*/,
int Icomboval/*combination representation, only for printing purpose*/, int deep/*number of iteration, only for printing purpose*/)
{
// int numcall = 0; //DEBUG
for( int i=0; i<9; i++) //Controlling every free point in search of a valid way to contimue
if( Icheck[i] == false )
{
//Just for security, coping every variable in a new variable. I don't know how c++ works but I will make it works
int points = Ipoints;
int last = Ilast;
int comboval = Icomboval;
bool check[9];
for( int j=0; j<9; j++)
check[j] = Icheck[j];
int e1,e2;
int middle = -1;
e1=i; e2=last; //Ccontrolling duble jumps
if( e1 == 0 && e2 == 2 ) middle = 1;
if( e1 == 3 && e2 == 5 ) middle = 4;
if( e1 == 6 && e2 == 8 ) middle = 7;
if( e1 == 0 && e2 == 6 ) middle = 3;
if( e1 == 1 && e2 == 7 ) middle = 4;
if( e1 == 2 && e2 == 8 ) middle = 5;
if( e1 == 0 && e2 == 8 ) middle = 4;
if( e1 == 6 && e2 == 2 ) middle = 4;
e2=i; e1=last; // in both way
if( e1 == 0 && e2 == 2 ) middle = 1;
if( e1 == 3 && e2 == 5 ) middle = 4;
if( e1 == 6 && e2 == 8 ) middle = 7;
if( e1 == 0 && e2 == 6 ) middle = 3;
if( e1 == 1 && e2 == 7 ) middle = 4;
if( e1 == 2 && e2 == 8 ) middle = 5;
if( e1 == 0 && e2 == 8 ) middle = 4;
if( e1 == 6 && e2 == 2 ) middle = 4;
if((middle != -1) && !(check[middle])) {
check[middle] = true;
points++; //adding middle points
comboval *= 10;
comboval += middle;
}
check[i] = true;
points++; // get the point
comboval*=10;
comboval += i+1;
if(points > 3)
{
combo++; // every iteration over tree points is a valid combo
// If you want to see they all, beware because printing they all is truly slow:
// cout << "Combination n. " << combo << " found: " << comboval << " , points " << points << " with " << deep << " iterations\n";
}
if(points > 9) //Just for sure, emergency shutdown,
{ exit(1); }
research(points,check,i,comboval,deep+1); /*Recursive, here is the true program!*/
// numcall++; //DEBUG
}
// cout << "Ended " << deep << " , with " << numcall << " subs called\n"; // Only for debug purposes,remove with all the //DEBUG thing
}
int main ()
{
combo = 0; //no initial knows combo
bool checkerboard[9];
for( int i=0; i<9; i++) checkerboard[i]=false; //blank initial pattern
research(0/*no point taken*/,checkerboard,-1/*just a useless value*/,0/*blank combo*/,1/*it's the firs iteration*/); //let's search!
cout << "\n" ;
cout << "And the answer is ... " << combo << "\n"; //out
char ans='\0';
while(ans=='\0')
{ //just waiting
cin >> ans;
}
return 0;
}
i just run a python code to get possible combinations
i got 985824 possibilities
from itertools import permutations
numbers = "123456789"
total_combos = list(permutations(numbers,4))+list(permutations(numbers,5))+list(permutations(numbers,6))+list(permutations(numbers,7))+list(permutations(numbers,8))+list(permutations(numbers,9))
print(len(total_combos))
(No of Points- Valid patterns)
(4 - 746)
(5 - 3268)
(6 - 11132)
(7 - 27176)
(8 - 42432)
(9 - 32256)
Total of 117010 valid Patterns are possible