Counting recursive calls - java

is there a mathematical formula to calculate how many times the recursive function is called for the following without having to check with my complier
How many times will mystery2 be called recursively when invoked with the call
mystery2(1000)?
public void mystery2(int n)
{
if (n <= 1)
System.out.print(n);
else
{
mystery2(n / 2);
System.out.print(", " + n);
}
}
1, 3, 7, 15, 31, 62, 125, 250, 500, 1000 = 10 times

There is no "formula", but there is a general technique for solving recurrences. Here you have the recurrence
N(x) = 1 + N(floor(x / 2))
with the base case
N(1) = 1
The definition of N(x) is "the number of times mystery2 is called if its initial argument is x".
Recurrences are solved by "tricks" that are learned like integration formulas or else fancy math like generating functions. Sometimes approximations are the best you can do. In your case, if we do away with the floor operator (or assume x is a power of 2), then it's pretty clear that
N(x) = 1 + log_2(x)
We can verify this. if x is 1, we have N(x) = 1 + 0 = 1. For x = 2, we have N(x) = 1 + 1 = 2 and so forth... For x = 1024, it's N(x) = 1 + 10 = 11.
With the floor operator, the exact answer is more complicated, depending on the number of odd factors of x, but the formula above will always be close.

Use ceil from log2(n)
ceil(log2(1000)) = ceil(9.966) = 10

Another option is to pass the count into your method;
public void mystery2(int n) {
mystery2(n, 1);
}
public void mystery2(int n, int count) {
if (n <= 1)
System.out.print(n);
else
{
mystery2(n / 2, count+1);
System.out.print(", " + n + ":count=" + count);
}
}
Edit: I thought of a better way to do it. You can return the count as you go like this.
public static void mystery2(int n) {
System.out.print("\ncount = " + mystery2(n, 1));
}
public static int mystery2(int n, int count) {
if (n <= 1) {
System.out.print(n);
return count;
}
System.out.print(n + ", ");
return mystery2(n / 2, count + 1);
}

Use a static variable, or a global
public void mystery2(int n)
{
static count = 0;
count++;
system.out.print("We have called this " + count + "times before...");
if (n <= 1)
System.out.print(n);
else
{
mystery2(n / 2);
System.out.print(", " + n);
}
}

outside the method make a variable like mysteryCnt = 0; (must initialize to 0) then inside the ELSE block increment it after the method, mysteryCnt ++; that might work.
else{
mystery2(n / 2);
mysteryCnt ++;
System.out.println(", " + n);
}
Jonny Z has the right idea but you cannot initialize the variable inside the method or it will never increment past 1; the way he did it, it will set to 0 then increment to 1 every time you call the method.

Related

What edits to my code should I make to handle the error?

I wrote a program where function isHappy takes in a long value and returns a statement of either True or False based on what the output number is... (1 means True; 4 means false).
The way my program reaches the output is by squaring each digit of the input n and adding them repeatedly until the output is only 1 digit
For instance, if n = 19, the code would return 1 because:
1^2 + 9^2 = 82, from which digits 8 and 2 would do: 8^2 + 2^2 = 68, from which digits 6^2 + 8^2 = 100, from which 1^2 + 0^2 + 0^2 = 1. <== 1 is only one digit, therefore, it shall be the answer.
Please note that every input I get will end up with either 1 or 4
Anyways, here is my code so far,
public class Happy
{
public static void main(String args[])
{
System.out.println(isHappy(989));
}
public static boolean isHappy(long n) {
long sum = 0;
boolean l = true;
boolean j = false;
while (n != 0) {
sum = sum + ((n % 10) * (n % 10));
n = n / 10;
}
if (sum == 1) {
return l;
} else {
return j;
}
}
}
When my plug in test case inputs like isHappy(100), isHappy(111), isHappy(1234), the program seems to work where
1 = True, 4 means false
isHappy(100) == true
isHappy(111) == false
isHappy(1234) == false
However, when I plug in specific numbers like isHappy(989), the program should be true since
9^2 + 8^2 + 9^2 = 226; 2^2 + 2^2 + 6^2 = 44; 4^2 + 4^2 = 32; 3^2 + 2^2 = 13; 1^2 + 3^2 = 10 and lastly 1^2 + 0^2 = 1; which is True.
However, after running my code, my output prints false instead.
I've tried debugging my code but I can't seem to find a problem. Any help on what changes to my code do I have to make would be greatly appreciated :)
You're mixing the two parts of the algorithm: calculating the sum of squared digits and verifying if the number is a "happy number".
After calculating the sum for the given number in case when the sum is naughtier 1, no 4, the sum becomes a new number to check, and we need to continue with calculating its sum.
So basically we need two loops, or two separate methods.
That that's how it can be implemented.
public static boolean isHappy(long n) {
while (n != 1 && n != 4) { // given number is naughtier `1`, no `4`
n = getHappySum(n); // calculating the sum
}
return n == 1;
}
public static int getHappySum(long n) {
int sum = 0;
while (n != 0) {
sum += Math.pow(n % 10, 2);
n /= 10;
}
return sum;
}
main()
public static void main(String[] args) {
System.out.println(isHappy(100));
System.out.println(isHappy(111));
System.out.println(isHappy(1234));
}
Output:
true
false
false

How to find the number of multiplications for x^63 using the exponent recursive function and how to justify it?

How would I go about justifying this algorithm is O(log n)?
public static long exponentiation(long x, int n){
if(n == 0){
return 1;
}
else if (n % 2 == 0){
x = exponentiation(x, n / 2);
return x * x;
}
else{
return x * exponentiation(x, n-1);
}
}
Each recursive call to method exponentiation is a multiplication step. Hence you need to count the number of recursive calls. There are several ways to achieve this. I chose to add another parameter to the method.
public static long exponentiation(long x, int n, int count) {
if (n == 0) {
System.out.println("steps = " + count);
return 1;
}
else if (n % 2 == 0) {
x = exponentiation(x, n / 2, count + 1);
return x * x;
}
else {
return x * exponentiation(x, n - 1, count + 1);
}
}
Here is the initial call to method exponentiation
exponentiation(2, 63, 0);
When I run the above code, the following is printed
steps = 11
You can use a static counter as well (without changing the prototype of the function):
public static long counter = 0;
public static long exponentiation(long x, int n){
if(n == 0){
return 1;
}
else if (n % 2 == 0){
x = exponentiation(x, n / 2);
counter++;
return x * x;
}
else{
counter++;
return x * exponentiation(x, n-1);
}
}
However, you need to reset the counter before calling the function each time, i.e., set counter = 0.
Theoretical Analysis
Note that you need to the counter to prove that it is in O(log(n)). To prove the complexity, just you need to find the complexity term by looking at the flow of the code. Suppose T(n) is the number of multiplications for computing x^n. So, based on the written code, T(n) = T(n/2) + 1, if n is even, and T(n) = T(n-1) + 1, if n is odd. Now, at least in one of two consecutive recursions, input n is even. Therefore, at most 2 log(n) is required to reach to n = 0. Because, for each even input, the next input will be halved. So, we can conclude that the algorithm is in O(log(n)).

Trying to calculate a factorial e^x, x being what the user enters, having trouble with the formula

I am in a Java class and it's still early in the class. The assignment is to:
e^x Approximations
The value ex can be approximated by the following sum:
1 + x + x^2/2! + x^3/3! + …+ x^n/n!
The expression n! is called the factorial of n and is defined as: n! = 1*2*3* …*n.
Write a program that takes a value of x as input and outputs four approximations of ex done using four different values of n: 5, 10, 50, and 100. Output the value of x the user entered and the set of all four approximations into the screen.
Sample formula use: calculating e^7 using approximation with n = 5
1 + 7 + 7^2/2! + 7^3/3! + 7^4/4! + 7^5/5!
I've got all the rest to work, including getting n to be 5, 10, 50 and 100. I thought I had the factorial formula figured out and I used the number 4 like the sample we were show and my numbers done match. Could really use another set of eyes.
Here's my code with forumla (x is the value the user enters and n is the 5, 10, 50 and 100):
/**
* myFact takes in x and calculates the factorial
* #param x
* #param n
* #return the factorial as a long
*/
public static long myFact(int x, int n) {
//declare variables
long sum = x;
for (int i=2; i <= n; i++) {
sum += ((Math.pow(x, i))/i);
}
return (sum + 1);
}
}
Here's the main class where I am calling the function. The error I suppose could be there too:
public static void main(String[] args) {
//declare variable for user input and call method to initialize it
int x = getNumber();
long fact;
int n;
//Output first line
System.out.println("N\t approximate e^" + x);
for (n = 5; n <= 100; n *= 2) {
if (n == 10) {
fact = myFact(x, n);
System.out.println(n + "\t " + fact);
n += 15;
} else {
fact = myFact(x, n);
System.out.println(n + "\t " + fact);
}
}
}
Thanks for taking a look at this, it's taken me hours to get this as the teacher gave us very little help.
You did a mistake in
sum += ((Math.pow(x, i))/i);
here you need to calculate the i!. Add below method in your code
public static int fact(int i){
int fact = 1;
for (int n = i; n > 0; n--) {
fact = fact * n;
}
return fact;
}
Also change sum += ((Math.pow(x, i))/i) to
sum += ((Math.pow(x, i))/fact(i));

How do I print the factorials of 0-30 on a table

public static void main(String[] args) {
int n = factorial(30);
int x = 0;
while (x <= 30) {
System.out.println(x + " " + n);
x = x + 1;
}
public static int factorial (int n) {
if (n == 0) {
return 1;
} else {
return n * factorial (n-1);
}
}
}
I'm trying to print out something like this:
0 1
1 1
2 2
3 6
4 24
...etc, up to 30 (30!)
What I'm getting instead is this:
0 (30!)
1 (30!)
...etc, up to 30
In words, I'm able to create the left column from 0 to 30 but I want to make it print the factorial of the numbers in the right hand column. With my code, it only prints the factorial of 30 in the right-hand column. I want it to print the factorials in order next to their corresponding number. How can I fix my code to do this?
This is pretty simple. Instead of defining a variable, you call the method with the updated x every time:
System.out.println(x + " " + factorial(x));
Note that your loop could be rewritten as a for loop, which is exactly what they're designed for:
for (int x = 0; x < 30; x++) {
System.out.println(x + " " + factorial(x));
}
Note a couple of things:
The x++. It's basically a short form of x = x + 1, though there are some caveats. See this question for more information about that.
x is defined in the loop (for (int x = ...) not before it
n is never defined or used. Rather than setting a variable that's only used once, I directly used the result of factorial(x).
Note: I'm actually pretty certain that an int will overflow when confronted with 30!. 265252859812191058636308480000000 is a pretty big number. It also overflows long, as it turns out. If you want to handle it properly, use BigInteger:
public BigInteger factorial(int n) {
if (n == 0) {
return BigInteger.ONE;
} else {
return new BigInteger(n) * factorial(n - 1);
}
}
Because of BigInteger#toString()'s magic, you don't have to change anything in main to make this work, though I still recommend following the advice above.
As #QPaysTaxes explains, the issue in your code was due to computing the final value and then printing it repeatedly rather than printing each step.
However, even that working approach suffers from a lack of efficiency - the result for 1 computes the results for 0 and 1, the result for 2 computes the results for 0, 1, and 2, the result for 3 computes the results for 0, 1, 2, and 3, and so on. Instead, print each step within the function itself:
import java.math.BigInteger;
public class Main
{
public static BigInteger factorial (int n) {
if (n == 0) {
System.out.println("0 1");
return BigInteger.ONE;
} else {
BigInteger x = BigInteger.valueOf(n).multiply(factorial(n - 1));
System.out.println(n + " " + x);
return x;
}
}
public static void main(String[] args)
{
factorial(30);
}
}
Of course, it would be faster and simpler to just multiply in the loop:
import java.math.BigInteger;
public class Main
{
public static void main(String[] args)
{
System.out.println("0 1");
BigInteger y = BigInteger.ONE;
for (int x = 1; x < 30; ++x) {
y = y.multiply(BigInteger.valueOf(x));
System.out.println(x + " " + y);
}
}
}
Just for fun, here's the efficient recursive solution in Python:
def f(n):
if not n:
print(0, 1)
return 1
else:
a = n*f(n-1)
print(n, a)
return a
_ = f(30)
And, better still, the iterative solution in Python:
r = 1
for i in range(31):
r *= i or 1
print(i, r)

How to trace path in a simple dynamic programming prob?

I am trying to solve a simple DP problem:
Given a positive integer n, you can perform any one of the following 3 steps.
1) Subtract 1 from it.
2) If it is divisible by 2, divide by 2.
3) If it is divisible by 3, divide by 3.
Please find the minimum number of steps that takes n to 1 and print out the steps. If there are multiple solutions to achieve the goal in the same number of steps, please print out all these solutions. (if it is hard, at least print out one of these solutions).
Getting the minimum number of steps is not that hard. Simply apply a bottom up DP solution like this:
public int getMinSteps(int n) {
int[] dp = new int[n+1];
int i;
dp[1] = 0;
for( i = 2 ; i < = n ; i ++ ) {
dp[i] = 1 + dp[i-1];
if(i%2==0) dp[i] = min( dp[i] , 1+ dp[i/2] );
if(i%3==0) dp[i] = min( dp[i] , 1+ dp[i/3] );
}
return dp[n];
}
However, I was not able to solve the print path part. In a high level, I think I need to stop the "action" at every level a minimum is determined?
Hope I can get some good suggestion or solution here.
thanks!
Just get another field to store the optimal step, i.e. -1, /2, or /3, if it is optimal to get the minimum path, possibly just using 1, 2, 3 as indicators.
For example, you are comparing a = 1 + dp[i-1], b = 1 + dp[i/2], c = 1 + dp[i/3]. If a is minimum, then you know you should -1 for the number. Store the step as 1. Later, you just jump to the field for i-1 to find the next step until you reach the start point, i.e. 1.
Update:
If you want to print all the paths, you have to store all the optimal steps, and print all the combinations.
In details, you can use three boolean fields for -1, /2, /3 to store if any optimal path goes through a certain number. After that, you can print all the combinations recursively, like traversing a tree.
int[] dp; // for minimum steps
bool[] gominus1;
bool[] godivideby2;
bool[] godivideby3;
List<Integer> steps;
PrintAllPath(int n) {
if(n == 1) {
// print steps
return;
}
steps.push_back(n);
if(gominus1[n]) {
PrintAllPath(n - 1);
}
if(godivideby2[n]) {
PrintAllPath(n / 2);
}
if(govidivideby3[n]) {
PrintAllPath(n / 3);
}
steps.pop_back();
}
Here is How you can retrieve the path:
public static int getMinSteps(int n) {
int[] dp = new int[n + 1];
String[] path = new String[n+1];
int i;
dp[1] = 0;
path[1] = "end";
for (i = 2; i <= n; i++) {
dp[i] = 1 + dp[i - 1];
if (i % 2 == 0) {
if(dp[i] < 1 + dp[i/2]){
path[i] = "sub 1," + path[i-1];
}
else {
path[i] = "div by 2," + path[i/2];
}
dp[i] = min(dp[i], 1 + dp[i / 2]);
}
if (i % 3 == 0) {
if(dp[i] < 1 + dp[i/3]){
path[i] = "sub 1," + path[i-1];
}
else {
path[i] = "div by 3," + path[i/3];
}
dp[i] = min(dp[i], 1 + dp[i / 3]);
}
if( i % 3 != 0 && i % 2 != 0) {
path[i] = "sub 1," + path[i-1];
}
}
System.out.println("number of steps = "+dp[n]+",path = "+path[n]);
return dp[n];
}
This is to print single path. To print all the path you need to track all the minimum possible ways to dp[i]. So you need a two dimensional array of String to store them.

Categories

Resources