Loop semantics(literal) - semantics

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.

Related

Time and Space Complexity(for specific algorithm)

Despite the last 30 minutes i spent on trying to understand time and space complexity better, i still can't confidently determine those for the algorithm below:
bool checkSubstr(std::string sub)
{
//6 OR(||) connected if statement(checks whether the parameter
//is among the items in the list)
}
void checkWords(int start,int end)
{
int wordList[2] ={0};
int j = 0;
if (start < 0)
{
start = 0;
}
if (end>cAmount)
{
end = cAmount -1;
}
if (end-start < 2)
{
return;
}
for (int i = start; i <= end-2; i++)
{
if (crystals[i] == 'I' || crystals[i] == 'A')
{
continue;
}
if (checkSubstr(crystals.substr(i,3)))
{
wordList[j] = i;
j++;
}
}
if (j==1)
{
crystals.erase(wordList[0],3);
cAmount -= 3;
checkWords(wordList[0]-2,wordList[0]+1);
}
else if (j==2)
{
crystals.erase(wordList[0],(wordList[1]-wordList[0]+3));
cAmount -= wordList[1]-wordList[0]+3;
checkWords(wordList[0]-2,wordList[0]+1);
}
}
The function basically checks a sub-string of the whole string for predetermined (3 letter, e.g. "SAN") combinations of letters. Sub-string length can be 4-6 no real way to determine, depends on the input(pretty sure it's not relevant, although not 100%).
My reasoning:
If there are n letters in the string, worst case scenario, we have to check each of them. Again depending on the input, this can be done 3 ways.
All 6 length sub-strings: If this is the case the function runs n/6 times, each running 8(or 10?) processes, which(i think) means that its time complexity is O(n).
All 4 length sub-strings: Pretty much the same reason above, O(n).
4 and 6 length sub-strings mixed: Can't see why this would be different than previous 2. O(n)
As for the space complexity, i am completely lost. However, i have an idea:
If the function recurs for maximum amount of time,it will require:
n/4 x The Amount Used In One Run
which made me think it should be O(n). Although, i'm not convinced this is correct. I thought maybe seeing someone else's thought process on this example would help me understand how to calculate time and space complexity better.
Thank you for your time.
EDIT: Let me provide clearer information. We read a combination of 6 different letters into a string, this can be (almost)any combination in any length. 'crystals' is the string, and we are looking for 6 different 3 letter combinations in that list of letters. Sort of like a jewel matching game. Now the starting list contains no matches(none of the 6 predetermined combinations exist in the first place). Therefore the only way matches can occur from then on is by swaps or matches disappearing. Once a swap is processed by top level code, the function is called to check for matches, and if a match is found the function recurs after deleting the "match" part of the string.
Now let's look at how the code is looking for a match. To demonstrate a swap of 2 letters:
ABA B-R ZIB(no spaces or '-' in the actual string, used for better demonstration),
B and R is being swapped. This swap only effects the 6 letters starting from 2nd letter and ending on 7th letter. In other words, the letters the first A and last B can form a match with are same, before and after the swap, thus no point checking for matches including those words. So a sub-string of 6 letters sent to the checking algorithm. Similarly, if a formed match disappears(gets deleted from the string) the range of effected letters is 4. So when i thought of a worst case scenario, i imagined either 1 swap creating a whole chain reaction and matching all the way till there are not enough letters to form a match, or each match happens with a swap. Again, i am not saying this is how we should think when calculating time and space complexity but this is how the code works. Hope this is clear enough if not let me know and i can provide more details. It's also important to note that swap amount and places are a part of the input we read.
EDIT: Here is how the function is called on top level for the first time:
checkWords(swaps[i]-2,swaps[i]+3);
Sub-string length can be 4-6 no real way to determine, depends on the
input (pretty sure it's not relevant, although not 100%).
That's not what the code shows; the line if (checkSubstr(crystals.substr(i,3))) conveys that substrings always have exactly 3 characters. If the substring length varies, it is relevant, since your naive substring match will degrade to O(N*M) in the general case, where N is start-end+1 (the size of the input string) and M is the size of the substring being searched. This happens because in the worst case you'll compare M characters for each of the N characters of the source string.
The rest of this answer assumes that substrings are of size 3, since that's what the code shows.
If substrings are always 3 characters long, it's different: you can essentially assume checkSubstr() is O(1) because you will always compare at most 3 characters. The bulk of the work happens inside the for loop, which is O(N), where N is end-1-start.
After the loop, in the worst case (when one of the ifs is entered), you erase a bunch of characters from crystal. Assuming this is a string backed by an array in memory, this is an O(cAmount) operation, because all elements after wordList[0] must be shifted. The recursive call always passes in a range of size 4; it does not grow nor shrink with the size of the input, so you can also say there are O(1) recursive calls.
Thus, time complexity is O(N+cAmount) (where N is end-1-start), and space complexity is O(1).

Variable Declaration Inside For Loop Initialization Statement

I have a simple question with regards to initializing for loops.
Here is my for loop declaration:
for (int i=player.x-xIndex-1; i<=player.x+xIndex+1; i++)
{
for (int j=player.y-yIndex-1; j<=player.y+yIndex+1; j++)
{
}
}
My question is:
Is it bad practice to have the values of the indices i and j be set to non-static integer values at declaration?
Will the code just evaluate the minimum and maximum values of i and j once at beginning of execution, or will it evaluate those values (i.e. player.x+xIndex+1, etc.) every single time the loop executes.
Any light you guys can shed on my problem would be awesome!
I'm a freakin' amateur, guys. Seriously.
Thanks :D
Not an amateur question at all. The "initialization" expressions are calculated only on the first run through, because of course they're only used that one time.
For the loop's "condition" (the middle expression that is tested at the end of every iteration), in the worst case it can be evaluated every iteration. Because what if (in this case) player.y actually changes during the loop?
However, most modern compilers will likely not compute that whole thing every loop if they can detect that the end value is provably never changing during the loop.
If you wanted to be double sure and manhandle the path of execution, you can explicitly "hoist" the conditional end expression out of the loop yourself, like:
int maxValue = foo.x + y.bar + 12 + myString.length;
for (int i = 0; i < maxValue; i++) {
....
But now the standard style disclaimer: optimizing prematurely can make your code less readable for no provable gains. Unless you're doing real work in that condition expression, or the loop is running bazillions of iterations, some additional computation won't hurt you much, and might be worth keeping so that it's clearer to yourself and others what you're trying to do.

I keep getting stuck in an infinite loop java

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

What naming conventions should I use on the second integer on a nested for loop?

I'm pretty new to programming, and I was just wondering in the following case what would be an appropriate name for the second integer I use in this piece of code
for (int i = 0; i < 10; i++)
{
for (int x = 0; x < 10; x++)
{
//stuff
}
}
I usually just name it x but I have a feeling that this could get confusing quickly. Is there a standard name for this kind of thing?
Depending upon what you're iterating over, a name might be easy or obvious by context:
for(struct mail *mail=inbox->start; mail ; mailid++) {
for (struct attachment *att=mail->attachment[0]; att; att++) {
/* work on all attachments on all mails */
}
}
For the cases where i makes the most sense for an outer loop variable, convention uses j, k, l, and so on.
But when you start nesting, look harder for meaningful names. You'll thank yourself in six months.
You could opt to reduce the nesting by making a method call. Inside of this method, you would be using a local variable also named i.
for (int i = 0; i < 10; i++)
{
methodCall(array[i], array);
}
I have assumed you need to pass the element at position i in the outer loop as well as the array to be iterated over in the inner loop - this is an assumption as you may actually require different arguments.
As always, you should measure the performance of this - there shouldn't be a massive overhead in making a method call within a loop, but this depends on the language.
Personally I feel that you should give variables meaningful names - here i and x mean nothing and will not help you understand your code in 3 months time, at which point it will appear to you as code written by a dyslexic monkey.
Name variables so that other people can understand what your code is trying to accomplish. You will save yourself time in the long run.
Since you said you are beginning, I'd say it's beneficial to experiment with multiple styles.
For the purposes of your example, my suggestion is simply replace x with j.
There's tons of real code that will use the convention of i, j, and k for single letter nested loop variables.
There's also tons that uses longer more meaningful names.
But there's much less that looks like your example.
So you can consider it a step forward because you're code looks more like real world code.

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].