How many times is this loop body repeated? - java

In my Object-Oriented Programming course we discussed a topic that I don't think he ever named, I've tried to find out what it's name is to find a proper way to solve these, but I have had no luck.
This is not homework, but a question for clarification about the process to solve this problem.
for I = (N + 2) downto -1
for J = (I - 1) to (N + 4)
// Code is run here
The question is "How many times is // Code is run here ran?"
Here is what I have tried to solve this:
1) I = (N + 2), J = [(N + 2) - 1] from this (and what I remember) you use b - a - 1 to solve for the number of times executed, which gives us X = [(N + 2) - 1] - (N + 2) - 1 which can be simplified to X = -2
2) I = -1, J =((-1) - 1)andX = ((-1) - 1) - (-1) - 1which simplifies toX = -2`
I'm getting lost on dealing with the second for loop and how to finish the problem. I know that we have to end up with an answer such as r(r + 1)/2
I just want to say that I have attempted to look for a name of this type of technique, but he simply called it "Code Counting" which didn't return any searches relating to this topic.
Thank you
EDIT: This course was in Java, so that is why I used the Java tag for this question, if anyone is curious.
EDIT2: To clarify, this was on a written exam, so we are expected to do this via pen-and-paper, I would like an explanation of how to solve this question as I have attempted it many times and still end up with the wrong answer.

Just look at the "code" and start counting logically. In the first iteration of the outer loop (called OL) you execute the inner loop (IL) (N + 4) - (N + 2 - 1) + 1 times = 4 times.
Explanation of the +1: if we run the loop from -1 to 2, we in fact run it 4 times: -1, 0, 1, 2, which in math is `2 - (-1) + 1.
The next time I = N + 1, therefore the IL runs (N + 4) - (N + 1 - 1) + 1 times = 5 times. Same goes for the next step and the step after that, the times the IL is executed increase by one each time : 4 + 5 + 6 + .... The question remaining is how far we go.
The last step is I = -1, there IL gets run (N + 4) - (-1 - 1) + 1 = N + 7 times.
The sum you are looking for therefore seems to be 4 + 5 + 6 + ... + (N + 6) + (N + 7). Which in fact is something like r(r + 1)/2 with a few substractions and additions.
The above numbers assume the to boundaries to be inclusive.
Note: whenever you come up with some kind of a formular, choose the input parameter as something small (like 0 or 1) and verify that the formula works for that value.
Summing the values using the little gaussian formula r * (r + 1) / 2 we have r -> N + 7. And therefore (N + 7) * (N + 8) / 2. But then we count the 3, 2 and 1 as well, which are actually not in the above listing, we need to subtract them and come to the final solution of:
(N + 7) * (N + 8) / 2 - 6

The algorithm as shown in the question looks like the good old Basic syntax
for X down/to Y, that includes Y
The outer loop goes from n+2 to -1, so the inner loop goes
n+1 to n+4 => 4 iterations
...
-2 to n+4 => n+7 iterations
Summing all of these, we get
n+3
∑ (4+i) = 4(n+4) + (n+3)(n+4) / 2
i=0
= (n+11)(n+4) / 2
which is also equal to (N + 7)(N + 8) / 2 - 6

Related

Java - Using recursion to sum a number with the difference of that number and multiples of 3

I am doing exercises with algebraic formulas to practice the use of recursion in Java.
I am trying to write a method that returns the result of n + (n - 3) + (n - 6) + (n - 9) ... + 0.
For example, when n = 7, the result should be 12.
When n = 10, the result should be 22.
So far, this is what I have:
public static int sumDownBy3(int n)
{
if(triSum <= 0)
{
return sum;
}
sum = n;
triVar += 3;
triSum = (n - triVar);
return sumDownBy3(n + triSum);
}
However, when I compile and run it, it does not return the expected result.
How may I fix this method to correctly apply the formula I am trying to emulate?
So, here are a few tips to hopefully get you going considering the comments by childofsoong and Jonny Henly.
What you are looking for is simply:
f(n) = n + f(n-3) for n > 0.
Your recursive function should just check if n is <= 0. If it is, return 0. Else return the variable n + another call to your function with n-3.
Hope this helps without giving too much away.
Since this isn't an assignment, just practice, then here is a working solution based off the information given in your question. This solution works for all n, however n <= 0 will always return 0.
public static int sumDownBy3(int n) {
if (n <= 0) {
return 0;
}
return n + sumDownBy3(n - 3);
}
Instead of having an extra parameter or global/class variables keeping track of the sum, this example just uses the stack to keep track of the sum. One downside to this approach is that for a very, very large number the stack could overflow and/or the program could lock up.
Output:
sumDownBy3(7) = 12
sumDownBy3(10) = 22
sumDownBy3(9) = 18
Breakdown for sumDownBy3(10):
sumDownBy3(10): 10 !<= 0 -> return 10 + sumDownBy3(10 - 3)
sumDownBy3( 7): 7 !<= 0 -> return 7 + sumDownBy3( 7 - 3)
sumDownBy3( 4): 4 !<= 0 -> return 4 + sumDownBy3( 4 - 3)
sumDownBy3( 1): 1 !<= 0 -> return 1 + sumDownBy3( 1 - 3)
sumDownBy3(-2): -2 <= 0 -> return 0
So 0 + 1 + 4 + 7 + 10 ='s 22

Result of recursive method

I am trying to understand this recursive method but even with a debugger I couldn't come up to something that makes sense to me so i hope someone here is motivated to explain me what is going on here. I know how recursion works basically but the way this method is written down troubles me.
I know the conditional operator in java and I worked out a new code but still I don't understand it, so what I expect here is.
What is the result for m(5) AND m(15). How did you calculate it? Thanks
Edit after the answers. I made a table with my results for future readers
m(n)::|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|...
result|0|0|1|1|1|2|3|4|6|9|13|19|28|41|60|88|...
I checked only the result of 15 with my program.
public class practice {
/**
* Try to understand the way this works
* #param n
* #return
*/
static long m(long n) {
return n <= 1 ? 0 : n == 2 ? 1 : m(n - 1) + m(n - 3);
}
/**
* This is what i tried so far.
* #param n
* #return
*/
static long ma(long n) {
System.out.println("Method called");
System.out.println("N is: " + n);
if (n <= 1) {
System.out.println("N<=1: " + n);
System.out.println("0 is returned");
return 0;
} else if (n == 2) {
System.out.println("N==2: " + n);
System.out.println("1 is returned");
return 1;
} else {
System.out.println("Inside ELSE, N is: " + n);
return ma(n - 1) + ma(n - 3);
}
}
public static void main(String[] args) {
ma(15);
}
}
Wrote it this way to make it more understandable:
m(0) = 0
m(1) = 0
m(2) = 1
m(n) = m(n - 1) + m(n - 3) // n >= 3
When we know the values for m(0), m(1) and m(2), we can calculate any m(n), where n >= 3, using m(n - 1) + m(n - 3). For any negative input, the result is 0.
For example:
m(3) = m(3 - 1) + m(3 - 3) = m(2) + m(0) = 1 + 0 = 1
m(4) = m(4 - 1) + m(4 - 3) = m(3) + m(1) = 1 + 0 = 1
m(5) = m(5 - 1) + m(5 - 3) = m(4) + m(2) = 1 + 1 = 2
And so on...
Pencil and paper are you friends.
There are 3 cases (two of them are base conditions)
if n <= 1 then return 0
if n == 2 then return 1
else recursive call to m(n-1) + m(n-3)
So you know that on every recursive call we are approaching one of the base conditions.
Here is a stack trace of what happens on m(5)
m(5)
m(4) + m(2)
m(3) + m(1) return 1
m(2) + m(0) return 0
return 1 return 0
Adding all the returns gives 1 + 0 + 0 + 1 which is 2
So
m(5) == 2
Method m in pseudo code. (this is some kind of scala/python mash up)
def m (number n)
if (n <= 1) 0
else if (n == 2) 1
else m(n - 1) + m(n - 3)
Looking at this you can see that anything <= 2 is a terminal operation, returning 0 or 1 based on the input. If n is > 2, the fun begins. Take for example n=3. Since 3 is greater than 2, we need to run the third if. When we look at that line we see that we nee to return m(n - 1) + m(n - 3). Plugging n = 3 in, it looks like this: m(3 - 1) + m(3 - 3), or, more simplified, like this: m(2) + m(0). This will now terminate with 1 because neither 2 or 0 for n will result in more calling of m.
So now we have something we understand we can now workout what m(15) and m(5) will return.
I will only work it out for 5 since the call stack for 15 would be way to long
m(5)
/ \
m(5-1) + m(5-3)
/ \ |
m(4-1) + m(4-3) |
/ \ | |
m(3-1) + m(3-3) | |
| | | |
1 + 0 + 0 + 1
2
Hope it helps!
m(5) = m(4)+m(2) // 5>2, so the third condition
m(4) + m(2) = m(3)+m(1) + 1 // 4>2, so the third condition
m(3) + m(1) + 1 = m(2)+m(0) + 0 + 1 // 3>2, so the third condition
m(2) + m(0) + 0 + 1 = 1 + 0 + 0 + 1 = 2
Now, between transformations, m(2) s instantly replaced with 1, and m(n<=1) is instantly replaced with 0. This is how you can analyze this on paper. Computer, however, would wirst calculate m(4) before calculating m(2) and adding the results in the first line - this happens because of order of poerations within the recursive functions.

Matrix encoding implementation in the F5 steganography algorithm is unclear

I need to implement my own F5 algorithm. I have read the F5 documentation and the paper can be found here.
In the section 6.2 Matrix Encoding of the paper, equations 16-18 define the change density, D(k), the embedding rate, R(k) and the efficiency rate, W(k), as follows:
D(k) = 1 / (n + 1) = 1 / 2**k
R(k) = k / n = k / (2**k - 1)
W(k) = R(k) / D(k) = k * 2**k / (2**k - 1)
Where n is the number of modifiable places in a code word and k the number of embedding bits. W(k) indicats the average number of bits we can embed per change.
In the source code we find the number of bits as stated below. Can someome please explain why usable and changed are calculated this way? I simply don't understand the logic.
int _changed = 0;
int _expected = 0;
int _one = 0;
int _large = 0;
int _zero = 0;
for (i = 0; i < coeffCount; i++) {
if (i % 64 == 0) {
continue;
}
if (coeff[i] == 1) {
_one++;
}
if (coeff[i] == -1) {
_one++;
}
if (coeff[i] == 0) {
_zero++;
}
}
_large = coeffCount - _zero - _one - coeffCount / 64;
_expected = _large + (int) (0.49 * _one);
for (i = 1; i < 8; i++) {
int usable, changed, n;
n = (1 << i) - 1;
usable = _expected * i / n - _expected * i / n % n;
changed = coeffCount - _zero - coeffCount / 64;
changed = changed * i / n - changed * i / n % n;
changed = n * changed / (n + 1) / i;
//
changed = _large - _large % (n + 1);
changed = (changed + _one + _one / 2 - _one / (n + 1)) / (n + 1);
usable /= 8;
if (usable == 0) {
break;
}
if (i == 1) {
System.out.print("default");
} else {
System.out.print("(1, " + n + ", " + i + ")");
}
System.out.println(" code: " + usable + " bytes (efficiency: " + usable * 8 / changed + "." + usable * 8
/ changed % 10 + " bits per change)");
}
coeff is an array that holds the DCT coefficients,coeffCount is the number of DCT coefficients,_large is the teoretical number of bits from the image that can be encoded and expected is the expected capacity of the image(with shrinkage).I don't understand what is the logic behind usable and changed variables
The last paragraph of the section 6.2 in the paper says the following and I quote:
We can find an optimal parameter k for every message to embed and every
carrier medium providing sufficient capacity, so that the message just fits into the
carrier medium. For instance, if we want to embed a message with 1000 bits into
a carrier medium with a capacity of 50000 bits, then the necessary embedding
rate is R = 1000 : 50000 = 2 %. This value is between R(k = 8) and R(k = 9) in
Table 1. We choose k = 8, and are able to embed 50000 : 255 = 196 code words
with a length n = 255. The (1, 255, 8) code could embed 196 · 8 = 1568 bits. If
we chose k = 9 instead, we could not embed the message completely.
I believe this should be straightforward. If you can understand this, you can follow the steps below.
One more preliminary thing is the expression result = var - var % n; throughout the code. This means you make var exactly divisible by n by removing the remainder (modulo operation). Now onto the loop block.
n = 1 << i - 1
This is the code word length, as defined in the paper.
usable = _expected * i / n - _expected * i / n % n;
To understand this line, remember that i / n is the embedding rate, R(i). In simple words, the number of possibly available bits (_expected) times the embedding rate (i / n), gives the number of bit we can encode. In the example from the quote that's 50000 / 255 * 8 = 1568 bits.
changed = coeffCount - _zero - coeffCount / 64;
changed = changed * i / n - changed * i / n % n;
changed = n * changed / (n + 1) / i;
The first line says that the number of bits that we can go through (call this total) is the number of coefficients (coeffCount), while skipping any zeros and the DC component of each 8x8 block (coeffCount / 64). Each 8x8 block has 64 coefficients, but only one is the DC coefficient, so every 64 coefficients you have one more DC coefficient to skip.
The second and third lines go together. Notice than in the second line you multiply by the embedding rate and you make that result perfectly divisible by the code word length. In the third line you divide by the embedding rate, thereby cancelling the previous step, and then you multiply by the change density, 1 / (n + 1), to find the number of bits to be changed on average.
The reason you go through this whole process is because the order of divisions and multiplications matter. As a straightforward example, consider you have 150 bits and 7 items that you want to distribute evenly into as many bits as possible. How many bits will you need overall?
7 * (150 / 7) = 7 * 21 = 147
Note: The following lines overwrite the currently computed value of changed. The previous 3 lines and the following 2 independently tend to give similar answers when I make up my own _one, _zero, coeffCount values. One of these two versions may be old code which was not removed. Regardless, the logic is the following.
changed = _large - _large % (n + 1);
changed = (changed + _one + _one / 2 - _one / (n + 1)) / (n + 1);
The first line has to do with the change density, D(i), since you make the expression perfectly divisible by n + 1. Because of how _large is defined, this is similar to how changed is computed in the previous version.
_large = coeffCount - _zero - _one - coeffCount / 64;
Which bears close resemblance to this
changed = coeffCount - _zero - coeffCount / 64;
The next line is a little bit hazy to me, but this is what it seems to achieve. It reintroduces back the _one it substracted in _large and one half of the ones. This is due to shrinkage, since it replicates the idea in _expected = _large + int(0.49*_ones). I don't quite understand why you would substract ones / (n + 1), but multiplying this whole expression by the change density, 1 / (n + 1), you get the number of bits you expect to change.
Conclusion
The two ways for calculating the expected number of bits to change are not exact and it has to do with not knowing in advance exactly how many will be changed. They both seem to give similar results for given values of _zero, _one and coeffCount. None of this is really necessary as it just estimates the efficiency for different k as in the quote. You just need to find the maximum k for which you use as much of the carrier medium to embed your information. This is done by just calculating usable and breaking the loop as soon as you don't have enough bits to embed your message. And this exact thing is done a bit further down in the source code.

Calculate set bits in character

So I saw this one question on the interwebs that was along the lines of
Write a function that counts the number of bits in a character
Now obviously this confused me (or I wouldn't be here).
My very first thought was "aren't all chars 16 bits by default?" but obviously that has to be wrong because this question exists. I have no idea where to start. Maybe I can get the hex value of a char? Is there an easy way to convert from hex to binary or something? Is this something that can be asked about ANY language (I'm curious about Java here) or does it only matter to like C or something?
Here's another approach if you want to avoid recursion.
public static int bitsSet(char arg) {
int counter = 0;
for (int oneBit = 1; oneBit <= 0x8000; oneBit <<= 1) {
if ((arg & oneBit) > 0) {
counter++;
}
}
return counter;
}
Update
Here's a bit of an explanation. In the loop, oneBit bit-shifts to the left each time, which doubles its value. The <<= operation is a kind of shorthand for oneBit = oneBit << 1. So, the first time through, we have oneBit = 0000000000000001. Then the next time, we have oneBit = 0000000000000010, then oneBit = 0000000000000100, and so on, until we reach the last iteration, when we have oneBit = 1000000000000000 (these are all binary of course).
Now, the value of arg & oneBit will equal oneBit if arg has the matching bit set, or 0 otherwise. So the condition is executing counter++ if it encounters a set bit. By the time the loop has run all 16 times, we've counted all the set bits.
I'm assuming from your title that you're after the number of "set bits" (that is, bits that are equal to one). You can do it like this.
public static int bitsSet(char arg) {
return arg == 0 ? 0 : (arg & 1) + bitsSet((char)( arg >>> 1 ));
}
And yes, all chars in Java are 16 bits.
Update
Here's a bit of an explanation. (arg & 1) will check the rightmost bit of arg and return 0 or 1 depending on whether it is clear or set. So we want to take that 0 or 1, and add it to the number of set bits among the leftmost 15 bits. So to work that out, we shift arg to the right, introducing a zero at the left end. We need >>> rather than >> to make sure that we get a zero at the left end. Then we call bitsSet all over again, with the right-shifted value of arg.
But every time we do that, arg gets smaller, so eventually it's going to reach zero. When that happens, no more bits are set, so we can return 0.
To see the recursion working, take, for example, arg = '%' = 100101. Then we have the following - where all numbers shown are binary -
bitsSet(100101)
= (100101 & 1) + bitsSet(10010))
= (100101 & 1) + (10010 & 1) + bitsSet(1001)
= (100101 & 1) + (10010 & 1) + (1001 & 1) + bitsSet(100)
= (100101 & 1) + (10010 & 1) + (1001 & 1) + (100 & 1) + bitsSet(10)
= (100101 & 1) + (10010 & 1) + (1001 & 1) + (100 & 1) + (10 & 1) + bitsSet(1)
= (100101 & 1) + (10010 & 1) + (1001 & 1) + (100 & 1) + (10 & 1) + (1 & 1) + bitsSet(0)
= 1 + 0 + 1 + 0 + 0 + 1 + 0
= 3
All chars are 1-byte in C, Unicode (TCHAR) char's are 2 bytes.
To count the bits, you do bit shifting. I am not really that good at binary arithmetic personally.
According to Oracle JAVA doc for primitives.
char: The char data type is a single 16-bit Unicode character.

Determining as a function of n how often the statement incrementing the variable count is performed

Ok so I'm new to analyzing algorithms and would really appreciate any helpful tips that can be shared on how to go about this. I am trying to determine how many times count is incremented as a function of n. I have ran it in an ide and for values 1-7 the output is 1,3,6,10,15,21,28. Im just unsure how to write this as a function of n? Thanks.
The loop is as follows:
for(int i = 1 ; i <= n ; i++){
for (int j = 1 ; j <= i ; j++) {
count++;
}
}
The aim of this type of exercise is to teach how to you analyze it on paper instead of running it on a machine. But let's look at the pattern:
The outer loop will run a total of n times
The inner loop will run between 1 to n times depend on what i is at the time. But you know that on average this will run (n+1)/2 times.
Thus count = n(n+1)/2), which is O(n^2)
See arithmetic series
Update: As requested - why the inner loop is (n+1)/2:
The outer loop will increment i between 1 and n. So on each iteration of the outer loop, the inner loop will "loop" one more than than it did previously.
Thus the inner loop will iterate this number of times:
1 + 2 + 3 + ... + n
So we can do something clever and pair up :
n with 1: (n + 1) = n + 1
n-1 with 2: (n - 1) + 2 = n + 1
n-2 with 3: (n - 2) + 3 = n + 1
...
And since we paired these up, we have n/2 such pairs:
So the sum of 1 + 2 + ... + n is ( (n+1) * (n/2) ).
So the average is ( (n+1) * (n/2) ) / n = (n+1)/2
(Visualize it as you are writing 1 + 2 + 3 + ... + n on a long strip of paper, and you fold it in half.)
I would also highly recommend reading this famous story about Karl Friedrich Gauss so you'll always remember how to sum arithmetic series =)
1
1+2 = 3
1+2+3 = 6
1+2+3+4 = 10
1+2+3+4+5 = 15
It is only me who sees the pattern? :-)
Here you go:
count = n * (n + 1) / 2

Categories