Update a variable outside a loop from inside the loop - java

Trying to create a method to return the first number below "n" which can be entirely divided by both the first and second divisor. Currently my program is returning the default value of "answer" being 0, I want the value which is calculated within the loop to be translated outside the loop to be returned. Yes I am a beginner :(
static int highestNumberBelowNDivisibleByTwoNumbers(int firstDivisor, int secondDivisor, int n) {
int multipliedDivisors = firstDivisor * secondDivisor;
int answer = 0;
int remainder = 0;
for (int i = n; i <= 1; i--) {
remainder = multipliedDivisors / i;
if (remainder == 0){
answer = i;
break;
}
}
return answer;
}

Based on your description of:
Trying to create a method to return the first number below "n" which
can be entirely divided by both the first and second divisor.
Try something more like below with the % operator (remainder/modulo):
static int highestNumberBelowNDivisibleByTwoNumbers(int firstDivisor, int secondDivisor, int n) {
while (n>0) {
if ((n % firstDivisor == 0) && (n % secondDivisor == 0)) {
return n;
}
n--;
}
return -1; // no answer found
}

Your code
for (int i = n; i <= 1; i--) {
remainder = multipliedDivisors / i;
if (remainder == 0){
answer = i;
break;
}
Decreases the counter from n down to 1. HOWEVER, your answer is not updated UNLESS remainder equals to zero. If that condition is never met, the default value of n will be returned (which is zero).
The problem? remainder = multipliedDivisors / i when will remainder be zero?
Because of this assignment, int multipliedDivisors = firstDivisor * secondDivisor;, only if one of the "divisor" variables is zero.
Redo your logic.

Related

Stackoverflow Error in Staircase Problem when step size is greater than 3

I'm trying to solve the staircase problem in java with a method that gets the number of stairs (n) and the maximum step size (maxStep). Somehow it works until step size is > 3 after that I get a Stackoverflow error but I don't know why that is.
public static int climbStairs(int n, int maxStep) {
if (n == 0 || n == 1) {
return 1;
} else if (n == 2) {
return 2;
} else {
int count = 0;
for (int i = 1; i <= maxStep; i++) {
count += climbStairs(n - i, maxStep);
}
return count;
}
}
Try this code hope it will work.
public static int climbStairs2(int n, int maxStep) {
if (n == 0 || n == 1) {
return 1;
} else if (n < maxStep) {
return n;
} else {
int count = 0;
for (int i = 1; i <= maxStep; i++) {
count += climbStairs2(n - i, maxStep);
}
return count;
}
}
You don't check whether the maxstep is smaller than the step count. This means that after a while, the i<=maxstep can be > n, which results in negative n for the next recursion. If it once turns to the negatives, it will recurse infinitely. To fix it, just check for n<=maxstep or n<=0.
Example of your 'bad' code: Try inputs 5,4: it will start the method with n=
5
4
3
-1
-2

Codewars Persistence method with recursion?

I finished a Kata on Codewars, which is the multiplicative persistence method. For those who aren't aware of the challenge, it goes as follows:
The function takes in a positive parameter num and returns its multiplicative persistence, which is the number of times you must multiply the digits in num until you reach a single digit. For example:
persistence(39) === 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
// and 4 has only one digit
persistence(999) === 4 // because 9*9*9 = 729, 7*2*9 = 126,
// 1*2*6 = 12, and finally 1*2 = 2
persistence(4) === 0 // because 4 is already a one-digit number
My solution, which works, uses two while loops (below). I am now attempting to write the method using recursion. However, I see that I may run into threading issues (since I need to return the number of times I am multiplying the digits). Is it possible to use recursion? If so, how?
This is my code using iteration:
public static int persistence(long n) {
int count = 0;
if(n < 10) return count;
long num = 1;
while(n >= 10) {
while(n != 0) {
num*=(n % 10);
n/=10;
}
n = num;
num = 1;
count++;
}
return count;
}
As of now, I only know that:
The base case would be
if(n < 10) return 0;
This is if n is a single digit.
The recursive case is what I am stuck in. Thanks!
You can easily eliminate the outer loop with recursion:
public static int persistence(long n) {
if(n < 10) return 0;
long num = 1;
while(n != 0) {
num*=(n % 10);
n/=10;
}
if (num > 10) {
return 1 + persistence (num);
} else {
return 1;
}
}
Or even simpler:
public static int persistence(long n) {
if(n < 10) return 0;
long num = 1;
while(n != 0) {
num*=(n % 10);
n/=10;
}
return 1 + persistence (num);
}

Sum of digits (INC. Negative numbers)

How can I make the following allow negative numbers and treats them as positives. Ex. -91 = 10
It currently works for taking int n and adding all digits, but just for positives. Thanks!
public static int sumOfDigits(int n) {
int sum = 0;
while (n > 0) {
sum += n % 10;
n = n / 10;
}
return sum;
}
Simple solution: add n = Math.abs(n) as the first line of the function. This solution works for all numbers, except Integer.MIN_VALUE.
Always correct solution: replace loop condition by n != 0 and return Math.abs(sum) as the result.
public static int sumOfDigits(int n) {
if (n == 0) return 0;
else return (n % 10) + sumOfDigits(n / 10);
}

Time efficient recursion for Magical Number

I was solving the Magical Number Problem where the number at nth position is the sum of the previous 3 numbers, minus 1. For example: 0 1 1 1 2 3 5 9 16.... and so on.
I solved it in 2 ways.
Code 1) Using Recursion
int magicNumber(int n){
int f = 0;
if (n == 1)
return 0;
else if (n > 1 && n <= 4)
return 1;
else
f = (magicNumber(n-1) + magicNumber(n-2) + magicNumber(n-3)) - 1;
return f;
}
Code 2) Using Array
void magicNumber(int n){
long arr[] = new long[100];
int i=1;
for(i = 1; i <= n; i++)
{
if(i==1)
arr[i] = 0;
else if(i>1&&i<=4)
arr[i] = 1;
else
arr[i] = (arr[i-1] + arr[i-2] + arr[i-3]) - 1;
}
System.out.println("Result is : "+arr[n]);
}
Code 1 works fine when I provide a small integer number to the program, but it hangs with the input of bigger integer numbers and Code 2 runs fine without any problem.
So I need your suggestions, how can I improve the performance of the recursion program Code 1?
You can speed up your recursion like this:
int magicNumber2(int n, int a, int b, int c){
if (n <= 1) return a;
return magicNumber2(n - 1, b, c, a + b + c - 1);
}
int magicNumber(int n) {
magicNumber2(n, 0, 1, 1);
}
You're experiencing delay for higher numbers because each recursive call ends up in 3 more recursive calls. Hence the time rises exponentially. Try this approach:
Maintain a lookup table. Here I have an array magic_num[100] with all it's elements initialized to -1.
int magicNumber(int n){
if(n == 1)
{
magic_num[n] = 0;
return 0;
}
else if(n>1 && n<=4)
{
magic_num[n] = 1;
return 1;
}
else if(magic_num[n] == -1)
{
magic_num[n] = magicNumber(n-1) + magicNumber(n-2) + magicNumber(n-3) - 1;
return magic_num[n];
}
else
return magic_num[n];
}

Any idea on how can I count the number of elements that verify an "if" condition?

private static int chain(int n){
int count = 0;
while(n > 1){
if(n % 2 == 0){
count++; //the value is not stored
return chain(n/2);
}
count++; //same thing
return chain(3*n+1);
}
return count; //prints the initial value (0)
}
}
I need to print the number of times the chain method reoccurs.
How about this:
public static int chain(int n) {
return chain(n, 0);
}
private static int chain(int n, int count) {
if (n > 1) { // no need for a while-loop, it will never get past 1 iteration
if (n % 2 == 0) {
return chain(n / 2, count + 1);
}
return chain(3 * n + 1, count + 1);
}
return count;
}
To me, this seems cleaner than declaring a static field outside of the method, primarily because I wouldn't want to worry about having to reset the static field to 0 every time I call chain.
I don't really understand what you are asking. but if you want count to live outside of the method, instead of creating a local copy every time the method is called you can make it static.
static int count=0;
Remove the count variable from your method, and make it a static member of your class. And to prevent repeating yourlsef (DRY principle), you should increment the count variable at the top of your method.
private static int count = 0;
private static int chain(int n) {
count++;
while(n > 1) {
if(n % 2 == 0) {
return chain(n/2);
}
return chain(3*n+1);
}
return count;
}
This seems to work too and doesn't use that ugly extra parameter.
I have adjusted the algorithm a little (putting chain(3 * n + 1) in an else part) on the assumption that this is actually an attempt at measuring the length of the hailstone sequence of the Collatz conjecture. As originally stated it would merely stack overflow.
This code does indeed produce 111 when passed 27.
private static int recursiveChain(int n) {
if (n > 1) {
if (n % 2 == 0) {
return 1 + recursiveChain(n / 2);
} else {
return 1 + recursiveChain(3 * n + 1);
}
} else {
return 0;
}
}
And an iterative version looks surprisingly similar to the original question:
private static int iterativeChain(int n) {
int count = 0;
while (n > 1) {
count += 1;
if (n % 2 == 0) {
n = n / 2;
} else {
n = 3 * n + 1;
}
}
return count;
}

Categories

Resources