End condition of an IF loop that depends on a 3D array - c

I'm writing a program which will move a particle about a cube, either left,right,up,down, back or forward depending on the value randomly generator by the program. The particle is able to move with cube of dimensions LxLxL. I wish the program to stop when the particle has been to all possible sites and the number of jumps taken output.
Currently I am doing this using an array[i][j][k] and when the particle has been to a position, changing the value of the array at that corresponding point to 0. However, in my IF loop I have to type out every possible combination of i,j and k in order to say if they are all equal to 0 the program should end. Would there be a better way to do this?
Thanks,
Beth

Yes. I'm assuming the if in question is the one contained within the triple nested loop who's body sets finish=1;. The better way of doing this is to set a your flag before the loop, beginning with a true value then setting it to false and breaking if you encounter a value other then zero. Your if statement becomes much simpler, like this;
int finish =1; // start with a true value
//loops are untouched so still got the for i and for j above this
for(k = 0; k < 15; k++)
{
if (list[i][j][k] != 0)
{
finish = 0;
break;
}
}
// outside all the loops
return finish;
I think this is what you're asking for but if not please edit your question to clarify. I'm not sure if there is some technical name for this concept but the idea is to choose your initial truth value based on what's most efficient. Given you have a 15x15x15 array and a single non-zero value means false, it's much better to begin with true and break as soon as you encounter a value that makes your statement false. Trying to go in the other direction is far more complicated and far less efficient.

Maybe you can add your list[i][j][k] to a collection every time list[i][j][k]=0. Then at the end of your program, check for the collection's length. If it's of the right length, then terminate..

Related

Making a new array without duplicates in C

my code works as far as i can tell..
I was wondering if it can be done in a better way (better time complexity) and what is the time complexity of my code as im not really sure how to caculate it.
cant change the current array in the question but if there is a faster way to do it by removal i would also like to know, thanks a lot.
int i = 1, j = 0, count = 1;
int arrNew[SIZE] = { NULL };
arrNew[0] = arr1[0];
while(i<size){
if (arr1[i] == arrNew[j]) { // if the element of arr1 is already added, resets j for next iteration and moves to the next element.
j = 0;
i++;
}
else {
if (j == count - 1) { // checks if we reached the end of arrNew and adds missing element.
arrNew[count] = arr1[i];
j = 0;
count++; // this variable makes sure we check only the assigned elements of arrNew.
i++;
}
else // if j < count -1 we didnt finish checking all of arrNew.
j++;
}
}
I was wondering if it can be done in a better way (better time complexity)
It's a little hard to tell what's going on at first, but it looks like you're basically using one loop to do two jobs. You're looping on i to step through the original array, but also using j to scan through the new array for each new element. Effectively, you've got nested loops that both potentially have the same size, so you've got O(n2) complexity.
I'd suggest rewriting your code so that the two loops are explicit. You're not saving any time by making one loop do double duty, and if you come back to this code a month from now you're going to waste a bunch of time trying to remember how it works. Make your code obvious — it's as much about communicating with your future self or your coworkers as with the compiler.
Can you improve on that O(n2) complexity? Yes, definitely. One way is to sort the array, so that duplicate values end up being adjacent to each other in the array. It's then easy to just not copy any values that are the same as the preceding value. I know you can't modify the original array, but you can copy the whole thing, sort it, and then copy that array while removing dupes. That'd give you O(n log n) complexity (if you choose an efficient sorting algorithm). In fact, you could speed that up a bit by combining the sorting and copying -- but you'd still end up with O(n log n) complexity. Another way is to use a hash table: check to see whether the value exists in the table, tossing it if it does, or adding it to the table and copying to the new array if it doesn't. That'd be close to O(n).

How to check the elements of a row in a 2D Array

So, what I am trying to do is a three in a row game, and so far I have managed to make it work, but I am struggling a bit when it comes to getting a winner, since I need to check that all the elements of either a row, a column or a diagonal are the same.
So far I have managed to get it to kinda work by using a boolean, a counter and a for loop. Here is an example of how my code looks
//Code to check the rows horizontally
public void checkH(){
int cont1 = 0;
Boolean winner1 = false;
for(int i=0;i<size;i++){
if(a[0][i]==1 || a[1][i]==1 || a[2][i]==1){
cont1++;
if(cont1==3){
winner1 = true;
}
So, as y'all can see what I am doing in that code is telling the program that if the array in either one of the rows is equal to one and if that same case happens when it goes through all the positions in the row, then the counter is going to add plus one, and once the counter hits 3, the boolean will be true and there will be a winner, but here is the catch: if, for example, the 2D array looks like this:
int a[][] = {{1,0,0},
{1,1,0},
{0,0,0}};
then the counter is still hitting three, even though they are not aligned. I know I havent specified that kind of condition in the program, but that's what I am struggling with. What I would like to do is to be able to make that condition with loops, so that I dont have to fill the whole thing with if statements.
Any leads you guys could give me on this would be highly appreciated. Thanks in advance!
If you are finding it difficult to search for a solution/tutorial on the web, notice that the three in a row game is also called tic-tac-toe. So, if you search for "tic tac toe algorithm" you will find several examples on how to solve it, as it is a somewhat usual interview question. Here is a reference for the reader’s convenience.
Now, for the desire to use for loops instead of chained ifs (or an if with multiple logical comparisons), it is a question about row-wise, column-wise and diagonal-wise traversal of a matrix. Here is a reference for the row and column traversals, and here is another reference for the diagonal traversal.
Specific to your question, below is a pseudo-code showing the check for column and row using for and the cell values to have a small number of if statements. But please notice this is just an example, as there are many interesting ways to solve a tic-tac-toe game that you may want to take a look, from traversing trees to using a string and regex.
public bool checkRow() {
int i, j;
int count = 0;
// accessing element row wise
for (i = 0; i < MAX; i++) {
for (j = 0; j < MAX; j++) {
// Considering we were checking for 1
// And array can have 0 or 1
// You can add the cell value and avoid an if
count += arr[i][j];
// if you go with arr[j][i] you will be traversing the columns and not the rows.
}
// if all cells in the row are 1, we have a winner
if(count == MAX)
return true;
}
return false
}

are all while loops convertible to for loops?

earlier, I thought that we can't use for loops when working with linked lists... but then
for(current = head; current != NULL; current = current->next)
this line made me think. is all while loops are convertible to for loops especially when there is more than one condition?
Yes anything which can be written in a while loop can be represented with a for loop. Both of them are entry controlled loops which means first they check the condition and then the body is executed.
For a loop to run properly, we need at least one thing, i.e. condition and at most 3 things:
Initialization of the looping variable (If necessary)
Condition (Necessary)
Modification to the looping variable (If looping variable is initialized)
Now I will present a simple code block with both while and for loops:
-> To print all naturals numbers from 1 to 100.
Using While loop
int i=1; //Initialization of looping variable
while(i<=100) //Condition check
{
cout<<i;
i++; //Increment (Modification of looping variable)
}
Using For loop
Method 1:
for(int i=1;i<=100;i++)
//Here the first part to the for is initialization of looping variable.
// Second part is the Condition
// Third part is the increment
{
cout<<i;
}
Method 2:
int i=1;//Initializing the loop variable
for(;i<=100;)//Condition
{
cout<<i;
i++;//Increment
}
I gave this 2 methods to write the For loop, to show that both while and for loop can run only with the condition. If we are capable enough to rewrite the code in the format we need, both will run exactly in the same way.
You can use for loops in this instance because you are iterating a specific number of times (once per item in the list). It's not super intuitive but most purely programming related you could manage to change from a purely true/false run condition to a bounded countable run condition.
This line of thinking breaks down very quickly if you involve any amount of hardware. Let's say you have a program that turns on an LED so long as you hold down a button.
while(button is down)
{
LED = ON;
}
Something like this you wouldn't want to do with a for loop because there is no way of counting something to know when you stop, the amount of time is decided by the person holding down the button and can't be known by the computer until it actually happens.
TL;DR: You can use for loops for a lot of things that aren't intuitive. But you can't use them to replace EVERY possible while loop.
Some code example from my code, using while in a way that I wouldn't replace it with a for.
public function generateUniqueTokenForEntity(){
while (true) {
$token = substr(md5(uniqid()), 0, 10);
$entry = $databaseTable->findEntryByToken($token);
if ($entry === null) {
return $token;
}
}
}

Syntax/concept of a non-iterated loop?

I'm trying to iterate through a loop (any programming language, really, but for this exercise I happen to be using c#) and I was just wondering... what happens when you try to use a loop that doesn't iterate at all (i.e. ...."null"?)
For example:
int x = choose(0,1,2);
for(int i=0;i<x;i++) {
//some stuff
}
Like, what would happen if x gets chosen to be 0? Does it just become a useless for loop on that case? Will my program crash? Is that bad programming practice? etc. etc.
I'm mainly asking because I'm trying to format a concatenated string but only if some array has enough elements. thanks
Well simply put, nothing will happen. A for loop is like an if statement where it checks the condition and repeats while that condition is true.
for(int i=0;i<x;i++)
This is saying:
Initialize i to 0
Check if i is less than the value of x
Increment i at the end of the loop
If x is 0, then the loop will simply not run; it becomes useless.

Loops in Matlab

I get stuck when I initialize v(0)=0 and t(0)=0. Is the problem in not creating an empty array first? Your help is greatly appreciated.
T= 0.001;
C= 0.004;
n=0;
k=0;
v(0)=k;
t(0)=k;
while v(n)<60
v(n+1)= T.*(A(n)-C.*(v(n)).^2)+v(n);
t(n+1)= (n-1)*T;
n=n+1;
end
n60=n
t60=(n60-1)*T
Indices in Matlab are starting with 1.
Therefore v(0)=k and t(0)=k are not legal.
You rather do:
v(desired arraysize)=k;
t(desired arraysize)=k;
to pre-allocate.
and
v(1)=k;
t(1)=k;
to initialize the first value.
so v(n)<60 will give you an error as well.
you can write:
v(1) = 0;
while v(n) < 60+1
v(n+1)= T.*(A(n)-C.*(v(n)).^2)+v(n);
t(n+1)= (n-2)*T; %not completetely sure with this line, you should check it again.
n=n+1;
end
from comments:
just set t(1)=0 and v(1)=0, you simple need to rethink from other languages, that the indexing starts with 1. That basically means you cannot use the index as a substitute for "time" you usually need an additional time-vector, which relates your values with a certain time

Resources