Java : Method return - java

public class EulerProblem14 {
int chainLength=1;
public int findChainLength(int number){
System.out.println("number "+number);
System.out.println("Chainlength "+chainLength);
if(number==1){
System.out.println("the number is finally 1 return chain length");
return chainLength;
}
if(number%2==0){
chainLength++;
return findChainLength(number/2);
}
else {
chainLength++;
findChainLength(number*3+1);
}
System.out.println("THIS SHOULD NOT BE EXECUTED");
return -1;
}
public static void main(String args[]){
System.out.println(new EulerProblem14().findChainLength(13));
}
While solving Project Euler Problem 14, I came across a weird problem in method return in java I never faced before . In the above method when the number is finally 1 it should return the count of a chain . But this is the output for input 13 .
number 13 Chainlength 1
number 40 Chainlength 2
number 20 Chainlength 3
number 10 Chainlength 4
number 5 Chainlength 5
number 16 Chainlength 6
number 8 Chainlength 7
number 4 Chainlength 8
number 2 Chainlength 9
number 1 Chainlength 10
the number is finally 1 return chain length
THIS SHOULD NOT BE EXECUTED
THIS SHOULD NOT BE EXECUTED
-1
The problem is in the last part when the number becomes 1 instead of returning chainlength = 10 it somehow skips it and executes code which should never be executed and returns -1 . It runs fine for all powers of 2 like 1,2,4,8 but fails for others .
This is probably a stupid mistake on my part . Nonetheless it is a problem for me .

I haven't looked in detail, but I suspect this:
else {
chainLength++;
findChainLength(number*3+1);
}
should actually be:
else {
chainLength++;
return findChainLength(number*3+1);
}
You should then be able to remove the last two lines of the method entirely, as they're unreachable.

Related

For loop always runs one less time then it should, due to two lines of code that appear unrelated to the for loop

Edit: For some reason my code works as intended in an online compiler. But in eclipse, the exact same code has the following problem.
I am working on a Kattis Problem called Electrical Outlets.
On the first line of input will be the number of test cases (n). On the next n lines, each line will start with an integer k, which is the number of power strips that will follow on the line. The rest of the line will contain how many outlets each of these power strips contain. Here is my code:
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
ArrayList<Integer> outlets = new ArrayList<>();
int testCases = scnr.nextInt();
int stripCount;
int appliances = 0;
for (int i = 0; i < testCases; i++) {
stripCount = scnr.nextInt();
for (int j = 0; j < stripCount; j++) {
outlets.add(scnr.nextInt());
appliances += outlets.get(j);
}
System.out.print("\nNumber of outlets: " + (appliances - (outlets.size() - 1)));
System.out.print("\n" + i);
outlets.clear();
appliances = 0;
}
}
Now for some reason, the outer for loop always runs one less time then it should.
Here is a sample input
3
3 2 3 4
10 4 4 4 4 4 4 4 4 4 4
4 10 10 10 10
And expected output
Number of outlets: 7
Number of outlets: 31
Number of outlets: 37
However, my output is
Number of outlets: 7
Number of outlets: 31
Similarly, for input
5
5 4 3 2 5 6
4 3 2 2 3
7 4 4 4 4 4 4 4
5 4 3 3 4 4
8 9 9 9 9 9 9 9 9
I expect an output of
Number of outlets: 16
Number of outlets: 7
Number of outlets: 22
Number of outlets: 14
Number of outlets: 65
But receive an output of
Number of outlets: 16
Number of outlets: 7
Number of outlets: 22
Number of outlets: 14
If I comment out the following two lines contained within for loop(int j)
for (int j = 0; j < stripCount; j++) {
//outlets.add(scnr.nextInt());
//appliances += outlets.get(j);
}
And add print(i), the for loop iterates as many times as it should.
Kattis validates your code by inspecting your program's standard output. If even a single character is different than the judge expects, your submission will fail, and Kattis will only report "Wrong answer" without any reason, actual/expected diff or other diagnostics.
Therefore, it's critical to pay close attention to the expected output format in the problem description and sample test cases.
For the first sample input, we're given:
3
3 2 3 4
10 4 4 4 4 4 4 4 4 4 4
4 10 10 10 10
And the expected output is:
7
31
37
But your output is different:
Number of outlets: 7
0
Number of outlets: 31
1
Number of outlets: 37
2
This contains unnecessary "Number of outlets: " prefixes as well as an i for each test case. Sure, to a human, this is fine, but Kattis' runner program isn't smart enough to understand that you basically got it right.
Removing the i print and changing your result print to match what Kattis is asking for passes the submission tests:
System.out.println(appliances - (outlets.size() - 1));
As for the missing last line, you're probably not flushing that final buffer in the IDE. Either add a final newline or press Enter manually if you have interactive capabilities. This appears to be an environment misunderstanding, not a code problem.

In this example of recursion, how come the second printline prints the second half of the output?

I understand how calling the recursion method (n-1) prints out 4 3 2 1, and since on the last one, n=0; it breaks out of the loop I think, however, my lack of understanding comes from how the second print line prints 1 2 3 4.
static void recursion(int n) {
if(n>0) {
System.out.println(n);
recursion(n-1);
System.out.println(n);
}
}
public static void main(String[] args) {
recursion(4);
}
}
output:
4
3
2
1
1
2
3
4
You call recursion(4)
which prints 4
then calls recursion(3)
which prints 3
then calls recursion(2)
which prints 2
then calls recursion(1)
which prints 1
then calls recursion(0)
which does nothing
and returns to the previous level
which prints 1
and returns to the previous level
which prints 2
and returns to the previous level
which prints 3
and returns to the previous level
which prints 4
and returns to the previous level
and we're done

How can I find the stop and start index for a Java vector?

I have a vector that looks like this:
y =
Columns 1 through 19:
1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2
Columns 20 through 38:
2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4
Columns 39 through 57:
4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 6
Columns 58 through 67:
6 6 6 6 6 6 6 6 6 6
The vector y is always start at 1 and be counted up. You see that there are lots of same numbers. It's the classes for the samples.
Here we have 1 1 1 1 1 1 1 1 1 1 1 1 = 12 samples for class number 1.
We have 2 2 2 2 2 2 2 2 2 2 2 = 11 samples for class number 2.
My problem here is that I want to find start and stop for every class. For example: Class 1 begins always at index 0 and ends, in this case, at index 11.
Class 2 begins directly after class 1 ends.
Question:
I'm using EJML (Effient Java Matrix Library) and I'm planning to use this function:
C = A.extractMatrix(1,4,2,8)
Which is equal to this MATLAB code:
C = A(2:4,3:8)
But I need to find the start and stop indexes from this y vector. In what index does e.g class 3 stops and starts? Do you have any smart ideas how to do that?
Sure, I could use a for-loop, to do this, but for-loops in Java is quite slow because I'm going to have a very very large y vector.
Suggestions?
Edit:
Here is an suggestion. Is that good, or could it be done better?
private void startStopIndex(SimpleMatrix y, int c, Integer[] startStop) {
int column = y.numCols();
startStop[0] = startStop[1] + 1; // Begin at the next class
for(int i = startStop[0]; i < column; i++) {
if(y.get(i) != c) {
break;
}else {
startStop[1] = i;
}
}
}
Assuming that we are calling the method from:
Integer[] startStop = new Integer[2];
for(int i = 0; i < c; i++) {
startStopIndex(y, c, startStop);
}
If you want to do it faster then binary search is your friend. Threw this together really quick and it does things in O(log n) time, where as a linear search does it in O(n). It's pretty basic and assumes your data looks pretty much like you describe it. Feed it weird data and it will break.:
int[] breakPoints(int[] arr, int low, int high){
int[] rtrn = new int[high];
for(int i=low;i<high;i++){
rtrn[i]=binarySearch(arr, i, 0, arr.length-1);
}
return rtrn;
}
int binarySearch(int[] arr, int k, int start, int end){
int mid = (start+end)/2;
if(mid==arr.length){
return -1;
}
if(arr[mid]==k && arr[mid+1]==k+1){
return mid+1; //or just mid if you want before breakpoint
}
if(arr[mid]<=k){
return binarySearch(arr, k, mid+1, end);
}
return binarySearch(arr, k, start, mid-1);
}
You'd call it like this:
int[] data = {1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,5,5,6,6,6,6};
int[] bp = breakPoints(data,1,6);
//return 0, 3, 8, 13, 16, 18
I think there is a name for this, but I can't remember what it might be, but you start looking for the next boundary with an accelerating search, and use a binary search after that.
You know the numbers are in ascending order, and there are potentially a lot of the same number, so you start by checking the next element. But instead of keep going 1 step at a time, you accelerate and step 2, 4, 8, 16, ... until you find a higher number.
Once you've found a higher number, you've gone too far, but the last step had the initial number, so you know the boundary is somewhere between the last two steps, and you then apply a binary search for the boundary.
Once you've fund the boundary, you start over stepping 1, 2, 4, ... for the next boundary.
If you expect most numbers to have about the same number of occurrences, you could keep a running average count, and make the first step with that average, to get a running start.
I'll leave it to you to actually code this.
The below is in MATLAB. the for loop will go through each unique value stored in x1 and then find the first and last occurrence of that value.
x = [ 1 1 1 2 2 3 3 3 3 3 4 4 4 4 5 5 5 ]
x1 = unique(x)'
for k1 = 1:length(x1)
x1(k1,2:3) = [find(x == x1(k1,1),1,"first"), find(x == x1(k1,1),1,"last")];
end
the above code yields x1 to be a 3 column matrix
1 1 3
2 4 5
3 6 10
4 11 14
5 15 17

Can't understand recursion output [duplicate]

This question already has answers here:
Understanding recursion [closed]
(20 answers)
Closed 3 years ago.
I don't understand the following recursive code.
int func(int num){
if(num == 1){
return 1;
}
else{
return (func(num-1) + num));
}
}
public static void main(String[] args) {
System.out.println(func(100));
}
So the output is 5050.
I don't understand why that is. Can someone explain to me the working of the code?
Let's do it again with 3. Add system.out at every line.
The thing is when a function call happen, current function execution stops until the new function end and gives its result.
This is the program stack: the list of functions that wait for a subfunction to terminate.
With the code you provide, you will have a stack of 100 "func" calls, then the last call contain num == 1, because you have decremented 99 times 100.
After that all of the 100 func will return, each with the + num addition.
Ok, so let's analyze from the beginning the behaviour of your code step by step:
First of all, you call func(100)
100 is different than 1 so the first 'if' is skipped, the function "func(100)" returns
100 + func(99)
99 is different than 1 so the first 'if' is skipped, the function "func(99)" returns
99 + func(98)
so for the moment "func(100)" returns 100 + 99 + func(98)
same steps as before for func(97) until func(2)
so your function "func(100)" returns 100 + 99 + 98 + 97 + ..... + 2 + func(1)
func(1) 'if' this time is not ignored so func(1) returns 1
now you have func(100) = 100 + 99 + 98 + ..... + 2 + 1 which is the sum of the first 100 positive integers which is 5050

Recursive method confusion

Given the below
public class Recursion {
public static int magic(int a, int b) {
if (b == 0) {
return 0;
} else {
if (b % 2 == 0)
return magic(a + a, b / 2);
else
return magic(a + a, b / 2) + a;
}
}
public static void main(String[] args) {
Recursion r = new Recursion();
System.out.println(r.magic(3,11));
//System.out.println(r.magic(2,25));
}
}
When I use r.magic(3,11) I get an output of 33 and if I use r.magic(2.25) I get an output of 50, can someone explain the math behind it to me because I can't really seem to make sense of it.
Ok, here it is.
First of all you need to know the basics of recursion like how its returns the value and what is the exit condition.
Here is the stack trace for 2 and 25. In recursion we make a stack and this is the stack for 2 and 25. The first call value of a and b is in the bottom of the stack. i.e (2,25). You need to visualize it like this only.
a b called from return magic(a+a,b/2) or return magic(a+a,b/2)+a
64 0
32 1 2
16 3 2
8 6 1
4 12 1
2 25 2
Here 1 is for calling from magic(a+a,b/2) and 2 is for calling from return magic(a+a,b/2)+a.
So while returning from the function here is stack.If it is called from 1 then it will simply return the value else it will add a with the returned value.
a b
64 0 returns 0
32 1 2 returns 32
16 3 2 returns 32+16
8 6 1 returns 32+16
4 12 1 returns 32+16
2 25 2 returns 32+16+2
So the final return statement returns 50
And for the second call similarly here is the stack trace.
a b
48 0 returns 0
24 1 2 returns 24
12 2 1 returns 24
6 5 2 returns 24+6
3 11 2 returns 24+6+3
So the final return statement returns 33
So you can see now how the result is 50 and 33.
If you have any doubt you can comment.
I guess you want some explanations, not steps of the program. Here it is:
return magic(a + a, b / 2)
is actually
return magic(2 * a, b / 2)
It means you multiply one of the numbers by 2, and divide the other one by 2. So, these operations will not change the result in Math.
ab = (2a)*(b/2)
But, you work with integers in this method. That's OK with even numbers. But, if you divide an odd number by 2, you will lose the floating part which is "0.5".
If b is odd, let's say b = 2*n+1
a*(2n+1) = (2a)((2n+1)/2)
2an + a = (2a)(n+0.5)
2an + a = 2an + a
When you work with integers, it will be that which is wrong:
2an + a = 2an
Recursively this additional a becomes 2a, 4a, ...
And you can derive a*b with summation of these multiples of a.
When b is 0, this is the end, there is no need to sum any multiples of a.

Categories