I keep getting stuck in an infinite loop java - while-loop

I am writing a battleship program. Right now I am testing a couple lines of code to see if it will place the boat going in the up direction. How my program is set up is that if, for example, the user clicks on the aircraft carrier button to set his aircraft carrier, the program should also set the ai's aircraft carrier. The boats are placed on a button array, called tlba. aifirstclicki is set by a random generator so that it will choose a random row. aifirstclickj chooses a random column, in conjunction the two pinpoint a spot on the button array (which is 10x10). I wrote the following code to try to make it so that if the program has an outofboundsexception error,or in other words if the program chooses a first spot that will eventually cause an outofbounds exception error because the for loop will keep adding spots until aiclickcount = 5, it should start over and pick a different spot until it finds a spot that will allow it to place all 5 spots. I keep getting stuck in an infinite loop though.
int aiclickcount = 0;
while (directiondecider == 0)
{//up
aifirstclicki = generator.nextInt(10);
aifirstclickj = generator.nextInt(10);
while (aifirstclicki != 3 &&
aifirstclicki != 2 &&
aifirstclicki != 1 &&
aifirstclicki != 0)
{
for(int k=0; k<shiplength; k++)
{
tlba[aifirstclicki - k][aifirstclickj].setBackground(Color.RED);
aistringarray[aifirstclicki - k][aifirstclickj] = "aircraftcarrier";
aioccupied2d[aifirstclicki - k][aifirstclickj] = true;
aiclickcount++;
}
if (aiclickcount == 5)
{
shipset = true;
break;
}
}
System.out.println(shipset);
}
Does anyone know what's wrong or have a different solution to my problem?

You never have aiclickcount == 5 if your shiplength is not 5. Put if into your for loop. You don't need the second while at all, you don't break out of it as well. Just generate number greater than 3 by nextInt(6) + 4.

Your code does not tell us, which value the variable shiplength has. If it's 0 the for-loop will never be entered thus aiclickcount will remain 0 and your break statement is never reached (under the premise that the random value of aifirstclicki is greater than 3).
Try to step through your code with a debugger and let it display the values for the variables to you to find out what's going on.

Your break; is only going to get you out of the second while loop, not the first as it only works on the inner-most loop that it is part of.
Java allows you to specify multi-level breaks, rather than having to complicate your loop conditions:
Breaking out of nested loops in Java

Related

What is the time complexity of below function?

I was reading book about competitive programming and was encountered to problem where we have to count all possible paths in the n*n matrix.
Now the conditions are :
`
1. All cells must be visited for once (cells must not be unvisited or visited more than once)
2. Path should start from (1,1) and end at (n,n)
3. Possible moves are right, left, up, down from current cell
4. You cannot go out of the grid
Now this my code for the problem :
typedef long long ll;
ll path_count(ll n,vector<vector<bool>>& done,ll r,ll c){
ll count=0;
done[r][c] = true;
if(r==(n-1) && c==(n-1)){
for(ll i=0;i<n;i++){
for(ll j=0;j<n;j++) if(!done[i][j]) {
done[r][c]=false;
return 0;
}
}
count++;
}
else {
if((r+1)<n && !done[r+1][c]) count+=path_count(n,done,r+1,c);
if((r-1)>=0 && !done[r-1][c]) count+=path_count(n,done,r-1,c);
if((c+1)<n && !done[r][c+1]) count+=path_count(n,done,r,c+1);
if((c-1)>=0 && !done[r][c-1]) count+=path_count(n,done,r,c-1);
}
done[r][c] = false;
return count;
}
Here if we define recurrence relation then it can be like: T(n) = 4T(n-1)+n2
Is this recurrence relation true? I don't think so because if we use masters theorem then it would give us result as O(4n*n2) and I don't think it can be of this order.
The reason, why I am telling, is this because when I use it for 7*7 matrix it takes around 110.09 seconds and I don't think for n=7 O(4n*n2) should take that much time.
If we calculate it for n=7 the approx instructions can be 47*77 = 802816 ~ 106. For such amount of instruction it should not take that much time. So here I conclude that my recurrene relation is false.
This code generates output as 111712 for 7 and it is same as the book's output. So code is right.
So what is the correct time complexity??
No, the complexity is not O(4^n * n^2).
Consider the 4^n in your notation. This means, going to a depth of at most n - or 7 in your case, and having 4 choices at each level. But this is not the case. In the 8th, level you still have multiple choices where to go next. In fact, you are branching until you find the path, which is of depth n^2.
So, a non tight bound will give us O(4^(n^2) * n^2). This bound however is far from being tight, as it assumes you have 4 valid choices from each of your recursive calls. This is not the case.
I am not sure how much tighter it can be, but a first attempt will drop it to O(3^(n^2) * n^2), since you cannot go from the node you came from. This bound is still far from optimal.

For loop with only a declaration?

This is a very basic question but please bear with me!
I got this code in a question as part of a quiz I was doing earlier and just didn't know if I might be missing something. I typed it into the editor and it would not run and it does appear to be incomplete. Had it been if (k) it would have made more sense.
But, as I have heard that you can leave out components of a for loop, I was just wondering if there is any time you would see the likes of for (k)?
int k = 0;
for (k) {
printf ("hello");
}
for(int k; ;)
/*this is the correct syntax of a for loop without conditional statement and incrementation/decrementation statement*\
Remember,those semi-colons within the paranthesis is important(without that the program wouldn't compile).
Now,to answer some of the questions you asked me in the earlier answer-
for(int k; ;)
{
printf("infinite loop");
}
When will this loop come to an end?
This loop will never come to an end.It is an infinite loop.It will keep printing infinite loop forever.
Is it possible to bring this loop to an end?
Yes,it is.It can be brought to an end using break statement.
for(int k; ;)
//or for( ; ; )
{
printf("infinite loop");
break;
}
Prints infinte loop only once.It will encounter the break statement and the control will move outside the loop.
Possible application.
It's used when you actually have no idea about when a loop should come to an end.
int i=0; //to take user input
for(int k; ;)
{
//accept the value of k from user.
/*You want the user to enter 1 as the input*/
if(k==1)
{
printf("entered 1,moving out of loop");
break;
}
}
What is the meaning of above loop?
- This loop keeps running until the user enters '1'.This is important in cases where you are giving the user options and the options are limited and so you don't want the user to give an invalid input.It runs until a valid input is entered(you can add more if statements with break statement).
Menu: 1)Pizza
2)Burger
3)Quit buying!
for(int k;k<10;k++)
/* this is a finite loop and this isn't suitable for the above requirement because you are not sure if the user will give the valid input within 10 iterations.*/
When k becomes 10,the control will move out irrespective of whether the user has entered a valid input or not.What if the user inputs 8 when k=9? The control will move out of the loop at k=10.As a result,your program will not work efficiently because i=8 is not an input you expected.You wanted 1,2 or 3 as input.
So,an infinite loop is used when you are not sure about how many iterations are required.You will actually be using a break statement to exit such a loop.
Is this the only option for an infinite loop?Why not while() ?Isn't while() with no condition an infinite loop?
while();// invalid in C.
//objective-C follows C-standards.
while("condition"); //valid
Some valid for loop declarations in C
for(k; ;) // infinite loop
for(; ;) // infinite loop
for(; k<0;)// valid
So,I think that sums up a small explanation.
Remember,semi-colons are important(irrespective of whether a condition is given or not).
And of course,you have other options to keep running or taking user input unless a valid input is given.But above one was just an application I could figure out to show that an infinite loop could be cool!
If you find any error or doubt,please comment.
Well,even I am not too good in C.But yeah since java is somewhat similar,I figured it out.

Loop semantics(literal)

If you don't care what your variables are called LOOK AWAY!!
Anyway, lets say I have a loop
for (int i = start; i < whatisthis; i++) {
//something
}
I'm not sure what to call "whatisthis", usually I can call it the length or the size of the relevant collection but its not always strictly true, if start != 0 then it cannot be the length. Its not the length of the stretch either since its in fact start + length of the stretch. Can't call it the end since its end+1 so what do you call it?
Serious problems.
whatisthis has no name. The whole condition i < whatisthis is a termination condition, and whatisthis is merely part of that condition.
If you're looking for advice about what to name the variable, limit works pretty well if it's not a length or a size. You could also prefix it with max_ or min_. For example, max_row or min_timeout.

For loop or fast enumeration of nsarray with a skip or step

I have an NSArray and I need to perform an action every two items on those two items. So I assume it is like a step value or something like it.
Start the loop, run my command on the first two items and then loop and run my command on the next two items - until the array is exhausted.
Any ideas on how to do this? I thought using a modulus but that can help with even odd, right? I need even and odd every 2.
My code that is hardwired to run on the first two items is below. I would like to add many more items and have the loop intelligently skip every two after the action and start the loop over again.
for (int i = 0; i < 2; i ++) {
shut01Path = CGPathCreateMutable();
shut01Path = CGPathCreateMutableCopy([self buildPathAtIndex:i].CGPath);
[arr_cgPathArray addObject:[UIBezierPath bezierPathWithCGPath:shut01Path]];
}
Simply increment the counter by two:
for (NSUInteger i = 0; i < array.count; i += 2) {
id even = array[i];
id odd = array[i + 1]; // Make sure the array has even count, otherwise this crashes.
}
You just need to check the index value at the beginning of each iteration of your for-loop.
If your index value starts at zero and is incremented by 1 then you can check using modulo
If the index % 2 is zero, you've got an even number. Otherwise odd number.
Other conditions and indexing schemes may require fancier math or enable other conditional checks.
This is really standard C and general programming.
This code steps for me. Change s as needed.
int s = [array count]/4;
for (int i = 0; i < s; i ++) {
NSLog(#"%i",(i*s));
NSLog(#"%i",(i*s) + 1);
}

Specifying variable range in Verilog using for loop

I am trying to write this code:
for (i = 0; i <= CONST - 1'b1; i = i + 1'b1)
begin : loop_inst
if (i < 3)
begin
if (changed[i] & !done_q[i])
begin
writedata[3-i] = en[i];
writedata[2-i:0] = readdata[2-i:0];
writedata[15:4-i] = readdata[15:4-i];
end
end
else
...
Basically, the location of the bit I am trying to write to (en) changes depending on which address I am talking to, depending on i. This code is not synthesizable because i is not a constant.
Is there any other workaround to this? The only workaround I know is writing out those three statements CONST times. I am hoping I DON'T have to do that in the end. Is there any other solution?
It looks like you're trying to copy readdata to writedata all the time, but fill in the LSBs with en if certain special case conditions are met. I'm also going to assume that the for loop you have is in an always block, and that you're intending to build combo logic.
The for loop as you've it written doesn't make much sense to me from a hardware perspective. A for loop is used for building arrays of logic, and as you've
written it you'll have at least 3 logic cones trying to set values on the entire writedata bus. (If it generates anything at all, it'll be some weird priority structure).
That said, it's probably the range selects that your compiler is complaining about, ie the writedata[2-i:0] rather than the writedata[3-i] = en[i]; (anything with : in the part select). If you want to do something along those lines, you can use 'indexed part selects' ( +: or -:) but there are better solutions in this case.
I'd rewrite it as follows - assuming I've assumed correctly :)
always #( /*whatever*/ ) begin
// default assignment
writedata = readdata;
// overwrite some bits in writedata for special cases
for(i=0; i<3; i++) begin
if( changed[i] & !done_q[i] )
writedata[3-i] = en[i];
end
end
In this code, I'm setting writedata to readdata, and then tweaking the resulting value of writedata if the special cases are in play. The for loop is building 3 logic cones, one for each of the bits in writedata[3:1]. I'd double-check if the bit mapping is what you intend -ie, mapping en[2:0] on to writedata[1:3].