Math logic to substitute if statement - objective-c

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.

Related

Create a euphonious word

All the letters of the English alphabet are divided into vowels and consonants.
A word is considered euphonious if it doesn't have three or more vowels or consonants in a row.
My goal is to create euphonious words from the discordant ones and output the minimum number of characters needed to create a euphonious word from a given word.
Examples:
Input:
schedule
Output:
1
Input:
biiiiig
Output:
2
Code
fun main() {
val word = readLine()!!.toMutableList()
checkWord(word)
}
fun isVowel(c: Char): Boolean {
val vowels = listOf('a', 'e', 'i', 'o', 'u', 'y')
return c in vowels
}
fun checkWord(word: MutableList<Char>){
var counter = 0
for (number in 0 .. word.size - 2) {
if (isVowel(word[number]) && isVowel(word[number + 1]) && isVowel(word[number + 2])) {
counter++
word.add(number + 2, 'b')
// println(word)
}
if (!isVowel(word[number]) && !isVowel(word[number + 1]) && !isVowel(word[number + 2])) {
counter++
word.add(number + 2, 'a')
// println(word)
}
}
println(counter)
}
My code is working for those examples but not for a case like eeeeeeeeeeeeeeeee where the output is supposed to be 8 but my counter is 6.
Since the list is growing as you iterate, your for loop never reaches the end of the list. Your code can be fixed by replacing
for (number in 0 .. word.size - 2) {
with
var number = -1
while (++number < word.size - 1) {
so it checks the current list size on each iteration.
I want to point out however that it is unnecessary to use a MutableList and keep enlarging it since you don't use the "fixed" euphonious list afterwards. It is also unnecessary to repeatedly search neighbors on each iteration. You can just count as you go.
fun checkWord (word: String) {
var count = 0
var currentTypeCount = 0
var lastTypeVowel = true
for (c in word) {
if (isVowel(c) == lastTypeVowel) {
if (++currentTypeCount == 3) {
count++
currentTypeCount = 1
}
} else {
lastTypeVowel = !lastTypeVowel
currentTypeCount = 1
}
}
println(count)
}
Let's analyze the modifications of your word:
eebeeeeeeeeeeeeeee
eebeebeeeeeeeeeeeee
eebeebeebeeeeeeeeeee
eebeebeebeebeeeeeeeee
eebeebeebeebeebeeeeeee
eebeebeebeebeebeebeeeee
eebeebeebeebeebeebeebeee
eebeebeebeebeebeebeebeebe
Your last 2 modification take place on the letters with index, which is bigger than your word's original length. That happens because for loop iterations number is dependent on your word's original length.
I recommend you to use while loop, as its condition is always recalculated and word.size will be updated there
var i = 0
while (i + 2 < word.size) {
// the same logic
i++
}

count and repetive structure

We have 490 students
We have a capacity of 20 students per classroom
Ie we have 490/20 = 24.5 ie 25 sections
First I want to arrange students in alphabetical order
Secondly I want to make a table containing
Id_classroom and id_student attributes
My Problem is in id_classroom and how to populate it
How can I automatically give this
Students from 1 to 20 === id_classroom = 1
Students from 21 to 40 === id_classroom = 2
and so on
thank you in advance
In your SQL RESQUEST, the function FLOOR is your friend.
What it does is reduce your number to the largest integer less than or equal to the expression.
Let's say you have a student id 46.
The operation would look like this:
46-1= 45 //index starts at 1 instead of 0.
45/20=2.25
Floor(2.25)=2
2+1=3
So your SQL would have something as such in it:
id_classroom=FLOOR((id_student-1)/20)+1
Haven't tested this, I just thought something up :)
EDIT: Just noticed this was in SQL not C# forum. Not sure if still useful.
TotalStudents = 490;
MaxCap = 20;
RoomID = 0;
Dictionary<RoomID, MaxCap>() StudentsAndRooms = new Dictionary();
void PopulateRoom(Dictionary<int,int> myD)
{
myD = StudentsAndRooms;
for(int i = 0; i < TotalStudents; i++)
{
if(myD[RoomID].Value.Count <= MaxCap)
{
myD[RoomID] = myD[RoomID +1]
Debug.Log("Added Room");
}
else if(myD[RoomID].Value.Count != MaxCap)
{
myD[RoomID] +=1;
Debug.Log("Added Student");
}
else
{
Debug.Log("Something went wrong!");
}
}
void Start()
{
PopulateRoom(StudentsAndRooms);
}

TicTacToe is cheating

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.

What's wrong with my pascal's triangle?

I've been looking for some simple coding challenges recently, and discovered about Pascal's triangle (here), and I've tried to generate one myself in C/Objective-C. For those that don't know what it is, that link explains it pretty well.
I'm starting to get oddness after the fourth row, and I just can't figure out why.
My output for 5 iterations currently looks like this:
1
1 1
1 2 1
1 3 3 1
4 6 3 1
It should look like this:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Here is my code so far. The first loop is just a reset loop (setting all the values to 0). The actual logic happens mostly in the second loop. The third loop is where the values are concatenated and formatted in a string.
I've commented this code much more than I would for myself just to aid readability.
int iterations, i, b, mid, chars, temp;
NSLog(#"Please enter the number of itereations");
scanf("%i",&iterations); // take users input and store it in iterations
// calculate where the first 1 should go.
if (iterations % 2 == 0) mid = (iterations)/2;
else mid = (iterations+1)/2;
chars = iterations*2;
int solutions[iterations][chars];
// reset loop
for (i = 0; i<iterations; i++) {
for (b = 0; b<chars; b++) {
solutions[i][b] = 0;
}
}
solutions[0][mid] = 1; // place the initial 1 in first row
for (int row = 1; row<iterations; row++) {
for (int chi = 0; chi<chars; chi++) {
temp = 0;
if (chi > 0) {
temp += solutions[row-1][chi-1]; // add the one diagonally left
}
if (chi < iterations) {
temp += solutions[row-1][chi+1]; // add the one diagonally right
}
solutions[row][chi] = temp; // set the value
}
}
// printing below...
NSMutableString *result = [[NSMutableString alloc] initWithString:#"\n"];
NSMutableString *rowtmp;
for (i = 0; i<iterations; i++) {
rowtmp = [NSMutableString stringWithString:#""];
for (b = 0; b<chars; b++) {
if (solutions[i][b] != 0) [rowtmp appendFormat:#"%i",solutions[i][b]];
else [rowtmp appendString:#" "]; // replace any 0s with spaces.
}
[result appendFormat:#"%#\n",rowtmp];
}
NSLog(#"%#",result);
[result release];
I have a feeling the problem may be to do with the offset, but I have no idea how to fix it. If anyone can spot where my code is going wrong, that would be great.
It appears (from a brief look) that the original midpoint calculation is incorrect. I think it should simply be:
mid = iterations - 1;
In the example of 5 iterations, the midpoint needs to be at array position 4. Each iteration "moves" one more position to the left. The 2nd iteration (2nd row) would then place a 1 at positions 3 and 5. The 3rd iteration at 2 and 6. The 4th at 1 and 7. And the 5th and last iteration would fill in the 1s at 0 and 8.
Also, the second if statement for the temp addition should be as follows otherwise it reads past the end of the array bounds:
if (chi < iterations - 1) {

Objective-C loop logic

I'm really new to programming in Objective-C, my background is in labview which is a graphical programming language, I've worked with Visual Basic some and HTML/CSS a fair amount as well. I'm trying to figure out the logic to create an array of data for the pattern below. I need the pattern later to extract data from another 2 arrays in a specific order.
I can do it by referencing a = 1, b = 2, c = 3 etc and then creating the array with a, b, c but I want to use a loop so that I don't have 8 references above the array. These references will be used to generate another generation of data so unless I can get help figuring out the logic I'll actually end up with 72 references above the array.
// This is the first one which gives the pattern
0 0 0 0 (etc) // 1 1 1 1 // 2 2 2 2
NSMutableArray * expSecondRef_one = [NSMutableArray array];
int a1 = 0;
while (a1 < 9) {
int a2 = 0;
while (a2 < 8) {
NSNumber * a3 = [NSNumber numberWithInt:a1];
[expSecondRef_one addObject:a3];
a2++;
}
a1++;
}
// This is the second one which I'm stumbling over, I am looking for the pattern
1 2 3 4 5 6 7 8 //
0 2 3 4 5 6 7 8 //
0 1 3 4 5 6 7 8 //
0 1 2 4 5 6 7 8 // etc to -> // 0 1 2 3 4 5 6 7
If you run it in a line every 9th number is -1 but I don't know how to do that over a pattern of 8.
Thanks in advance!
Graham
I think you're looking for something like :
for(int i = 0; i < 9; ++i) {
for (int j = 0; j < 8; ++j) {
if (j < i) {
//Insert j into array
}
else {
//Insert j + 1 into array
}
}
}
I left out the code to actually insert the numbers into the array.
I'm not totally clear on how you're using this array, but if this is just an order of indexes to access data from another group of arrays, you may be able to skip the first set of arrays and just use this loop to access your data later.
--edit--
If I'm understanding you correctly, you want to compare each index in an array of 9 numbers to every other index, then store the results in an array. If that's the case, you could just do something like this:
for (int i = 0; i < 9; ++i) {
for (j = 0; j < 9; ++j) {
if (j != i) {
//Compare object at array index i with object at array index j
}
}
}
That loop works perfectly on a meta level for what I was trying to do. The array's that I was creating were to reference the original array (9 cells) With the algorithm you made I eliminated those and can reference the original array exactly as I wanted.
Thank you very much.
Cheers
Graham
NSMutableArray *a=[[NSMutableArray alloc]init];
for(int i=0;i<8;i++){
NSMutableString *s=[[NSMutableString alloc]init];
for(int j=0;j<8;j++){
if(i!=j){
[s appendString:[NSString stringWithFormat:#"%i",j]];
}
}
[a addObject:s];
}
NSLog(#"%#",a);
}
output:
1234567,
0234567,
0134567,
0124567,
0123567,
0123467,
0123457,
0123456