Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
To make it clear, this IS a graded assignment for my Programming II class. I've generally been very easily receptive to new programming concepts but this particular assignment on recursion is really throwing me and I'm looking for some good nudging in the right direction. Below is the assignment verbatim and the code I currently already have.
Magic Plant
We have a magic plant that once it is planted, it germinates and grows two leaves in the first year. It doubles its leaves every year except that every three years it triples its leaves. Something like:
Write a class called MagicPlant that includes the following methods:
A method that returns the number of leaves given the age of the plant
A non-recursive method that returns the age of the plant given the number of leaves.
A recursive method that returns the age of the plant given the number of leaves.
In a driver class test the methods.
Find out what is the largest (oldest) plant that your algorithm and data structure can handle.
That is what I was given and I'm having trouble on the last bullet point as well as a bit muddy on the second one (but I have code that seems to work).
My current code excluding the Driver class since it's just call statements:
public class MagicPlant {
// Method that returns the number of leaves given
// the age of the plant.
public int getLeaves(int age) {
int leafCount = 1;
for (int i = 1; i <= age; i++) {
if (i % 3 != 0) {
leafCount *= 2;
} else {
leafCount *= 3;
}
}
return leafCount;
}
// Non-recursive method that returns the age of the plant
// given the number of leaves.
public int getAgeNR(int leaves) {
int age = 1;
while (leaves > getLeaves(age)) {
age++;
}
return age;
}
// Recursive method that returns the age of the plant
// given the number of leaves.
public int getAgeR(int leaves) {
return 0;
}
}
My tipp is, to replace the while-loop with recursion. So you don't have a local variable but instead give that variable back into the method (recursive).
Also i would suggest that you make 2 methods for the recursion:
public int getAgeR(int leaves){
return getAgeR(1, leaves); // call overload with initial value
}
private int getAgeR(int age, int leaves){
// do your magic here
}
// Recursive method that returns the age of the plant
// given the number of leaves.
public int getAgeR(int leaves) {
if(leaves == 2) {
return 1;
}
if(leaves % 3 == 0) {
return getAgeR(leaves/3)+1;
} else {
return getAgeR(leaves/2)+1;
}
}
It's the inverse of counting years. Instead of starting from the beginning, you just have to start from the end and decreasing for every recurrent loop.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 11 months ago.
Improve this question
I am trying to calculate the average of values given via repeated function calls.
Actually Bluej allows me to put the number to rate but if i am trying to put again it replaces the previous one, i want to be stored and after that an average to be shown.
I can't figure out how to do it
This is the part of code:
public int getRate() // here i put an int number
{
return this.rate;
}
public void setRate(int rate) // here i change it but i think i don't need it
{
this.rate = rate;
}
I can't use strange or complex commands because i am allowed to only use this type of commands like get/set and arraylists.
It is a school assignment.
Thanks
An easy way to keep an average of inputs is to keep track of:
The sum of all inputs received so far.
The number of inputs you have received.
Every time you call setRate to update the rate, you add to the sum and increment the count. You also need a special case for when no rates have been added yet, to avoid division by zero:
private int ratesSum = 0;
private int rateCount = 0;
public int getRate()
{
return this.rate;
}
public void setRate(int rate)
{
this.rate = rate;
this.ratesSum += rate;
this.rateCount++;
}
// Gets the average of all rates so far, or returns zero if no rates
// have been set yet.
public float getAverageRate()
{
// Do not divide by zero
if (rateCount == 0) return 0;
return ((float)ratesSum) / ((float)rateCount);
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I want to write a recursive method that fills and returns a String[] list of random balls for either "blue" or "red" of length n where n is a random odd number.
I wrote this method to generate an odd number in range 1-10 to use as a parameter for the recursive method.
public int ranNum (int ranN) {
int min = 1
int max = 10
Random r = new Random();
ranN = min + r.nextInt((max - min)/2)*2;
return ranN;
}
Is the (random odd number) method right? How to implement the recursive method?
A recursive function is a function which calls itself directly or via any amount of intermediate function calls.
The first step usually is to think about the termination. In your case you want to either count from 1 up to n or from n down to 1. And when the function terminates you have the choice of either returning the final value (it's called tail-recursion) or start building up your answer by traversing the call stack upwards. The later is being used, when you have one long calculation and you just want the last value (e.g. Fibonacci-Numbers).
And then do the work in every step:
String[] tailRecursion(int n, String[] accumulator, Random rnd)
{
if(n == 0) {
return accumulator;
}
accumulator[n-1] = rnd.nextBoolean() ? "red" : "blue";
return tailRecursion(n-1, accumulator, rnd);
}
The method is called via tailRecursion(10, new String[10], new Random())
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
import java.util.*;
class towers{
public static void main(String args[])
{
honoi('A','B','C',(long)1,n);
}
static int disk_no(long i,int n) // to find the next disk to move
{
if(i%2!=0)
return 1;
else
{
int j;
long k;
for(j=2;j<=n;j++)
for(k=0;k<Math.pow(2,n-j);k++)
if(i==(long)Math.pow(2,(long)j-1)*((2*k)+1))
{
System.out.println("returning :"+j);
return j;
}
return 0;
}
}
static void honoi(char x,char y,char z,long i,int n)
{
if(i<Math.pow(2,n))
{
switch((int)i%2)
{
case 0:System.out.println("STEP "+i+" :\tMove disk "+(long)disk_no(i,n)+" from pole "+z+" to "+y);
honoi(x,y,z,++i,n);break;
default:System.out.println("STEP "+i+" :\tMove disk "+(long)disk_no(i,n)+" from pole "+x+" to "+y);
honoi(y,z,x,++i,n);
}
}
}}
I read n value from user as number of disks ofcourse I skipped it here
I thought that the problem is with
disk_no()
function if not mention the logical errors in the code if any
The problem is that your code throws a StackOverflowError.
Essentially, your honoi method prints out all the moves necessary to solve the Towers of Hanoi puzzle with n disks from step i onwards. It does this by figuring out what is necessary for move i and then calling itself with i replaced with i + 1 and optionally with x, y and z switched around.
The problem arises because your method calls itself. Each time Java calls your honoi method, it needs to store where to return to when executing the method finishes. It stores these return locations on a 'stack'. When a method returns, Java removes the last of these locations from the top of the stack and resumes running your program from this location. There is only a limited amount of space for the 'stack' used for these return locations. If this stack grows too large, Java will throw a StackOverflowError.
If you run your program with a large number of disks, your code will require too much space to store return locations, because your method calls itself too many times before it returns. Your honoi method only returns once all of the moves have been displayed.
To avoid the stack overflow, I modified your honoi method to the following, which uses a loop instead of calling itself. i is now a loop variable, so I've removed i as a method parameter. You will need to remove the (long)1 from your call to honoi in main():
static void honoi(char x,char y,char z,int n)
{
for (long i = 1; i < Math.pow(2,n); ++i)
{
switch((int)i%2)
{
case 0:System.out.println("STEP "+i+" :\tMove disk "+(long)disk_no(i,n)+" from pole "+z+" to "+y);
break;
default:System.out.println("STEP "+i+" :\tMove disk "+(long)disk_no(i,n)+" from pole "+x+" to "+y);
char temp = x;
x = y;
y = z;
z = temp;
}
}
}
The four lines from char temp = x; onwards swap around x, y, and z, as your recursive version of this method called itself with the x, y and z arguments switched around in the default case.
I don't know if you originally wrote this program in another language (e.g. a functional language such as Haskell) which supports tail recursion optimization. If a language supports this optimization, then it will be able to detect whether a method ends with a call to the same method, and if so, jump back to the start of the method using a kind of 'goto'. Your code would seem to benefit from this kind of optimization: if tail recursion optimization was supported in Java, your code would quite possibly run without an error. However, that's not likely to happen in Java.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am preparing for an exam next week, and I decided to look for some exam questions online for better preparation.
I came across this question and the answer is c. But I really want to know how or the step by step process to answer to answer a question like this. The part where I got stuck is trying to logically understand how a int m = mystery(n); How can a number equal a method? Whenever I get to a question like this is their anything important I should breakdown first?
private int[] myStuff;
/** Precondition : myStuff contains int values in no particular order.
/*/
public int mystery(int num)
{
for (int k = myStuff.length - 1; k >= 0; k--)
{
if (myStuff[k] < num)
{
return k;
}
}
return -1;
}
Which of the following best describes the contents of myStuff after the
following statement has been executed?
int m = mystery(n);
(a) All values in positions 0 through m are less than n.
(b) All values in positions m+1 through myStuff.length-1 are
less than n.
(c) All values in positions m+1 through myStuff.length-1 are
greater than or equal to n.
(d) The smallest value is at position m.
(e) The largest value that is smaller than n is at position m.
See this page to understand a method syntax
http://www.tutorialspoint.com/java/java_methods.htm
int m = mystery(n); means this method going to return int value and you are assigning that value to a int variable m. So your final result is m. the loop will run from the array's end position to 0. loop will break down when array's current position value is less than your parameter n. on that point it will return the loop's current position. s o now m=current loop position. If all the values of the loop is greater than n it will return -1 because if condition always fails.
Place the sample code into a Java IDE such as Eclipse, Netbeans or IntelliJ and then step through the code in the debugger in one of those environments.
Given that you are starting out I will give you the remainder of the code that you need to make this compile and run
public class MysteriousAlright {
private int[] myStuff;
public int mystery(int num)
{
for (int k = myStuff.length - 1; k >= 0; k--) {
if (myStuff[k] < num) {
return k;
}
}
return -1;
}
public static void main(String[] args) {
MysteriousAlright ma = new MysteriousAlright();
ma.setMyStuff(new int[] {4,5,6,7});
int m = ma.mystery(5);
System.out.println("I called ma.mystery(5) and now m is set to " + m);
m = ma.mystery(3);
System.out.println("I called ma.mystery(3) and now m is set to " + m);
m = ma.mystery(12);
System.out.println("I called ma.mystery(12) and now m is set to " + m);
}
public void setMyStuff(int[] myStuff) {
this.myStuff = myStuff;
}
}
You then need to learn how to use the debugger and/or write simple Unit Tests.
Stepping through the code a line at a time and watching the values of the variables change will help you in this learning context.
Here are two strategies that you can use to breakdown nonsense code like that which you have sadly encountered in this "educational" context.
Black Box examination Strategy
Temporarily ignore the logic in the mystery function, we treat the function as a black box that we cannot see into.
Look at what data gets passed in, what data is returned.
So for the member function called mystery we have
What goes in? : int num
What gets returned : an int, so a whole number.
There are two places where data is returned.
Sometimes it returns k
Sometimes it returns -1
Now we move on.
White Box examination Strategy
As the code is poorly written, a black box examination is insufficient to interpret its purpose.
A white box reading takes examines the member function's internal logic (In this case, pretty much the for loop)
The for loop visits every element in the array called myStuff, starting at the end of the array
k is the number that tracks the position of the visited element of the array. (Note we count down from the end of the array to 0)
If the number stored at the visited element is less than num (which is passed in) then return the position of that element..
If none of elements of the array are less than num then return -1
So mystery reports on the first position of the element in the array (starting from the end of the array) where num is bigger than that element.
do you understand what a method is ?
this is pretty basic, the method mystery receives an int as a parameter and returns an int when you call it.
meaning, the variable m will be assigned the value that returns from the method mystery after you call it with n which is an int of some value.
"The part where I got stuck is trying to logically understand how a int m = mystery(n); How can a number equal a method?"
A method may or may not return a value. One that doesn't return a value has a return type of void. A method can return a primitive value (like in your case int) or an object of any class. The name of the return type can be any of the eight primitive types defined in Java, the name of any class, or an interface.
If a method doesn't return a value, you can't assign the result of that method to a variable.
If a method returns a value, the calling method may or may not bother to store the returned value from a method in a variable.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
EDIT: I am using BlueJ. When I right click my class I am supposed to enter the values for a and b there rather than the actual code. Is there a way to do that?
Hello I am trying to write a basic program that will let me enter 2 numbers and then automatically calculate the sum, difference, division and remainder, and then print the results to the output. Here is what I have so far. It compiles but I get this error
java.lang.ArithmeticException: / by zero
at Q1A3.DoTheCalculation(Q1A3.java:33)
at Q1A3.<init>(Q1A3.java:24)
when I try to run it. I have no java experience and this is my first time trying anything on the computer other than emailing. Please be gentle! Can you point out my errors and guide me toward fixing them? Thank you.
/*
This program accepts two numbers from the user. Finds out the sum, diff, division and
remainder of the two numbers, and prints the results on the screen
*/
public class Q1A3
{
//instant variables - replace the example below with your own
private int a;
private int b;
private int sum;
private int difference;
private int division;
private int remainder;
//-----------------------------------------
//The following is the constructor that takes the input from the user
//and stores it in the system
public Q1A3(int a, int b)
{
DoTheCalculation ( );
PrintTheResults ( );
}
//-------------------------------------------------------------
//The following routine does all of the required calculations.
public void DoTheCalculation ( )
{
sum = (a+b);
difference = (a-b);
division = (a/b);
remainder = (a%b);
}
//----------------------------------------------------------------------------
//The following routine prints all of the information including the calculated
//items on the screen
public void PrintTheResults ( )
{
System.out.println("The value of “a” is:");
System.out.println("The value of “b” is:");
System.out.println("The sum is:" );
System.out.println("The difference is:");
System.out.println("The division is:");
System.out.println("The remainder is:");
}
}
You don't assign any values to a or b. try this:
private int a = 5;
private int b = 7;
(1) Make sure that private member variables are initialized from constructor parameters.
(2) Make sure to assign variables to string outputs.
Please observe the proposed changes in the following source code:
public Q1A3(int a, int b)
{
this.a = a;
this.b = b;
DoTheCalculation ( );
PrintTheResults ( );
}
public void PrintTheResults ( )
{
System.out.println("The value of 'a' is:"+a);
System.out.println("The value of 'b' is:"+b);
System.out.println("The sum is:" +sum);
System.out.println("The difference is:"+difference);
System.out.println("The division is:"+division);
System.out.println("The remainder is:"+remainder);
}
public static void main(String [] args)
{
Q1A3 obj = new Q1A3(8,4);
}
Your answer is in the first line of the error code "/ by zero". You cannot divide by zero (it'd implode the universe or something.) Try an if statement to test if 0 is being passed, and reject, or skip it.
You cannot divide by zero (it'd implode the universe or something.)
~ Andrew
No, it creates black holes. Or something :P
The question has been answered. BUT:
A good way to find the mistake yourself (next time) would have been a good debugger or systematic outputs, e.g. System.out.println("var a:"+a) to see what values which variables have at the time, before the error occurs.