I have just started taking a Computer Science class online and I am quite new to Programming(a couple of week's worth of experience). I am working on an assignment, but I do not understand what a mystery method is. I have yet to find an answer that I can wrap my head around online, in my textbook, or from my professor. Any explanation using this code as an example would also be greatly appreciated!
This is the equation where I saw it in:
public static void mystery1(int n) {
System.out.print(n + " ");
if (n > 0) {
n = n - 5;
}
if (n < 0) {
n = n + 7;
} else {
n = n * 2;
}
System.out.println(n);
}
If anybody can help, that would be amazing! Thank you!
First of all, I voted your question up because I think it's a valid question for someone who is just beginning in computer programming, and I think that some people fail to understand the significance and purpose of Stack Overflow, which is to help programmers in times of need.
Secondly, I think that the couple of users that have commented on your post are on the right track. I have personally never heard of a mystery method, so I think the goal here is for you to simply figure out what the method does. In this case, the method takes a parameter for int 'n'. This means that if, at any point in the application, the 'mystery1()' method is called, an integer will have to be passed as the variable.
Let's say that a user enters the number '9'. The method would be called by the code mystery1(9). This would then run the first part of the 'if' statement, because n is greater than 0. So, n would be equal to n - 5, or 9 - 5, which is 4. (So, n=4.)
I hope my answer was somewhat helpful to you. Take care.
Your assignment is probably to figure out what this method does. More specifically, what does it print to the screen. I'll walk you through how to figure this out.
You have a function, also called a methood, called mystery1. A function is just a named block of code that you can use throughout other pieces of code. This function takes an integer argument called n. Let's assume n=12 for this example.
The first thing that happens in your function when it is called is that n is printed out via the System.out.print method. Notice that it prints a blank space after it. Notice also at the end it prints another value of n that gets assigned within the method. So the method is going to print "12 ?" without the double quotes. The question mark is what we have to figure out. The code says if n > 0 then n = n-5. Since 12 is greater than 0, n gets the new value of 7. The next if statement says if n is less than 0, n gets assigned n+7. But it is not less than zero, it is 7 at this point, so we move to the else statement. In this statement n gets multiplied by 2 which is 14. So the last statement prints 14.
So for an input value of 12 this method prints:
12 14
I hope this helps. If not, please give more detail about your assignment and what you don't understand about my explanation.
The point of this kind of exercise is that you are given a method, but they don't tell you what it does (hence the "mystery"). You are supposed to figure out what it does on your own (like "solving the mystery"). It doesn't mean that the method is special in any way.
Say I give you a "mystery" method like this:
public static void mystery(int n) {
System.out.println(n+1);
}
You would "solve the mystery" by telling me that this method prints out the number that comes after n. Nothing else is special here.
In the example you gave, your job would be to tell me why the method prints out 0 0 when n = 0, or 6 2 when n = 6.
I think the usage of the term "mystery method" is rather misleading, as it has clearly made you (and many, many, many others) believe that something about these methods is special and something that you need to learn about. There isn't anything special about them, and there's nothing to learn.
I think a lot of people would understand this better if instructors just said "tell me what this method does" instead of trying treat students like 5 year olds by saying "Here's a mystery method (ooh, fancy and entertaining). Can you play detective and solve the mystery for me?"
Related
Having a tough time with the below code, I have answered the first call correctly as the condition is immediately correct. However, the second call of 4 is causing me great confusion, I came to the answer 2, 1 however it is incorrect- I am clearly getting things mixed up. Can someone explain to me exactly why my answer is wrong and the correct breakdown of the process of Recursive tracing in this example. I do understand elements of recursion however I am having issues following the process of tracing.
public void mystery1(int n) {
if (n <= 1) {
System.out.print(n);
} else {
mystery1(n / 2);
System.out.print(", " + n);
}
}
mystery1(1);
mystery1(4);
mystery1(16);
Recursion is beautiful yet very powerful and when it comes to observe it, people get tricked.
Let me explain you how i learnt it when i was preparing for my GATE(Graduate Aptitude Test in Engineering).
Think of each Function call as 2 parts:
Printing
Calling with halving itself
Now all the operations will be stacked upon the older one until unless we are out of recursion and only Printing is left in the function cycle.
We will print out in stack format i.e FIFO
Example, if we have these elements in stack:
Top:
4
3
7
2
Bottom
It will print 4 3 7 2 .
Now taking your Question:
Lets break your Conditional statements in two halves, 1st will be if condition with Print 2nd will be else with its print.
Note: Only one part i.e 1st will print 1 and that too without commas (,).
I have attached the Image below kindly refer it, think as print statement as on stack, and the lowest print statement will be executed first as we will end out of function calls.
Now combining mystery1(1),mystery1(4),mystery1(16) the final output will be: 1
1
, 2
, 4
1
, 2
, 4
, 8
, 16
PS: If you are going to give interviews of Amazon , Google or any Reputed Product based company they will ask question with flavor of recursion and that too without using any compiler, they wanna test your concepts via programming.
When you call mystery1(4), it goes to the else part and calls mystery1(2) since n>1. The print statement will be executed only after mystery1(2) has finished executing.
The same thing happens for mystery1(2) and it calls mystery1(1). It waits for mystery(1) to finish execution.
When mystery1(1) is called, it prints "1".
Then, mystery1(2) will continue and print ",2".
Finally, mystery1(4) will continue and print ",4".
So your output will be 1,2,4
In your method:
public static void mystery1(int n) {
if (n <= 1) {
System.out.print(n);
} else {
mystery1(n / 2);
System.out.print(", " + n);
}
}
try to replace the position of System.out.print(", " + n); before mystery1(n / 2); call.
In the first case, when System.out after mystery1 call, you have result as 1, 2, 4, because, first you have to get result, then print it.
In the second case, when System.out before mystery1 call, you have result as , 4, 21, because, first you print the result, then calculate the next result in function.
I have an array list with some names inside it (first and last names). What I have to do is go through each "first name" and see how many times a character (which the user specifies) shows up at the end of every first name in the array list, and then print out the number of times that character showed up.
public int countFirstName(char c) {
int i = 0;
for (Name n : list) {
if (n.getFirstName().length() - 1 == c) {
i++;
}
}
return i;
}
That is the code I have. The problem is that the counter (i) doesn't add 1 even if there is a character that matches the end of the first name.
You're comparing the index of last character in the string to the required character, instead of the last character itself, which you can access with charAt:
String firstName = n.getFirstName()
if (firstName.charAt(firstName.length() - 1) == c) {
i++;
}
When you're setting out learning to code, there is a great value in using pencil and paper, or describing your algorithm ahead of time, in the language you think in. Most people that learn a foreign language start out by assembling a sentence in their native language, translating it to foreign, then speaking the foreign. Few, if any, learners of a foreign language are able to think in it natively
Coding is no different; all your life you've been speaking English and thinking in it. Now you're aiming to learn a different pattern of thinking, syntax, key words. This task will go a lot easier if you:
work out in high level natural language what you want to do first
write down the steps in clear and simple language, like a recipe
don't try to do too much at once
Had I been a tutor marking your program, id have been looking for something like this:
//method to count the number of list entries ending with a particular character
public int countFirstNamesEndingWith(char lookFor) {
//declare a variable to hold the count
int cnt = 0;
//iterate the list
for (Name n : list) {
//get the first name
String fn = n.getFirstName();
//get the last char of it
char lc = fn.charAt(fn.length() - 1);
//compare
if (lc == lookFor) {
cnt++;
}
}
return cnt;
}
Taking the bullet points in turn:
The comments serve as a high level description of what must be done. We write them aLL first, before even writing a single line of code. My course penalised uncommented code, and writing them first was a handy way of getting the requirement out of the way (they're a chore, right? Not always, but..) but also it is really easy to write a logic algorithm in high level language, then translate the steps into the language learning. I definitely think if you'd taken this approach you wouldn't have made the error you did, as it would have been clear that the code you wrote didn't implement the algorithm you'd have described earlier
Don't try to do too much in one line. Yes, I'm sure plenty of coders think it looks cool, or trick, or shows off what impressive coding smarts they have to pack a good 10 line algorithm into a single line of code that uses some obscure language features but one day it's highly likely that someone else is going to have to come along to maintain that code, improve it or change part of what it does - at that moment it's no longer cool, and it was never really a smart thing to do
Aominee, in their comment, actually gives us something like an example of this:
return (int)list.stream().filter(e -> e.charAt.length()-1)==c).count();
It's a one line implementation of a solution to your problem. Cool huh? Well, it has a bug* (for a start) but it's not the main thrust of my argument. At a more basic level: have you got any idea what it's doing? can you look at it and in 2 seconds tell me how it works?
It's quite an advanced language feature, it's trick for sure, but it might be a very poor solution because it's hard to understand, hard to maintain as a result, and does a lot while looking like a little- it only really makes sense if you're well versed in the language. This one line bundles up a facility that loops over your list, a feature that effectively has a tiny sub method that is called for every item in the list, and whose job is to calculate if the name ends with the sought char
It p's a brilliant feature, a cute example and it surely has its place in production java, but it's place is probably not here, in your learning exercise
Similarly, I'd go as far to say that this line of yours:
if (n.getFirstName().length() - 1 == c) {
Is approaching "doing too much" - I say this because it's where your logic broke down; you didn't write enough code to effectively implement the algorithm. You'd actually have to write even more code to implement this way:
if (n.getFirstName().charAt(n.getFirstName().length() - 1) == c) {
This is a right eyeful to load into your brain and understand. The accepted answer broke it down a bit by first getting the name into a temporary variable. That's a sensible optimisation. I broke it out another step by getting the last char into a temp variable. In a production system I probably wouldn't go that far, but this is your learning phase - try to minimise the number of operations each of your lines does. It will aid your understanding of your own code a great deal
If you do ever get a penchant for writing as much code as possible in as few chars, look at some code golf games here on the stack exchange network; the game is to abuse as many language features as possible to make really short, trick code.. pretty much every winner stands as a testament to condense that should never, ever be put into a production system maintained by normal coders who value their sanity
*the bug is it doesn't get the first name out of the Name object
This question already has answers here:
Understanding recursion [closed]
(20 answers)
Closed 5 years ago.
Before you get started, I have used google countless times in hopes of searching for a very brief and simple explanation of how recursion works when it has a return type. But I guess I'm not as bright as I thought since i still cant understand it quite well.
Take the following code snippet (in java) as an example
public static int recursion(int num)
{
int result;
if (num == 1)
result = 1;
else
result = recursion(num - 1) + num;
return result;
}
I grabbed this code from my professors lecture slide and he said this will return 1 + 2 + 3 + ... + num.
I just need someone to explain how the process works in the method that i provided. Maybe a step by step approach might help me understand how recursion works.
recursion(5) = recursion(4) + 5, let's figure out recursion(4) and come back to this later
recursion(4) = recursion(3) + 4, let's figure out recursion(3) and come back to this later
recursion(3) = recursion(2) + 3, ...
recursion(2) = recursion(1) + 2, ...
recursion(1) = 1, we know this!
recursion(2) = 1 + 2, now we can evaluate this
recursion(3) = (1+2) + 3, and now we can evaluate this
recursion(4) = (1+2+3) + 4, ...
recursion(5) = (1+2+3+4) + 5, the answer to our original question
Note: Without knowing recursion(1), we'd have gone to 0, -1, -2, and so on until forever. This known quantity is called the base case and it is a requirement for recursion.
Basically when there is a stack buildup for each item that is created beyond the last iteration. (Where num=1)
When n>1 the if statement kicks the iteration to the else which 'saves' the result in a stack and calls the same funtion again with n-1
what this effectively does is keep calling the same function until you hit your designated 'base case' which is n=1
Recursion is all about solving a problem by breaking it into a smaller problem. In your case, the question is "how do you sum the numbers from 1 to n", and the answer is "sum up all the numbers from 1 to n-1, and then add n to it". You've phrased the problem in terms of a smaller or simpler version of itself. This often involves separating out a "base case"—an irreducibly simple problem with a straightforward answer.
public static int recursion(int num)
{
int result;
if (num == 1)
result = 1; // Base case: the sum of the numbers from 1 to 1 is 1.
else
result =
// This is the sum of numers from 1 to n-1. The function calls itself.
recursion(num - 1)
// Now add the final number in the list, and return your result.
+ num;
return result;
}
You're defining the unsolved problem in terms of itself, which works because the solution always involves either the base case or a simpler version of the problem (which itself further involves either the base case or an even simpler version of the problem).
I'll close with one of my favorite jokes:
How do you explain recursion to a five-year-old?
You explain recursion to a four-year-old, and wait a year.
Going by the classic code example you posted. if you call your method like so with number passed in as 5:
recursion(5);
In layman terms just to understand, your function will create & call another copy of your function in the else block as below:
recursion(4);
and then
recursion(3);
recursion(2);
recursion(1);
as the number keeps decrementing.
Finally it will call the if part in the final copy of the method as num will satisfy num == 1. So from there it starts unwinding & returning each value to the previous call.
As each method call has its own stack to load method local variables on, there will be n number of stacks created for n calls. When the deepest call in recursion is made, then the stacks start unwinding. Hence recursion achieved
The most important thing however to note is that there is a base-most call in your code, which is done at 1 just because you have the check if (num == 1). Else it would be infinite recursion & of course a fatal & wrong program to write. The base-most call is from where its called as stack unwinding in recursion terms.
Example: Finding the factorial of a number is the most classic examples of recursion.
Performance: Do look into recursion vs iteration and recursion vs looping to see what are the performance impacts of recursion
I'm very new to Java and stackoverflow so I'm sorry if I seem ignorant but I wrote this program to multiply two numbers together using the Russian Peasant multiplication algorithm. The complete program includes far more operations and is hundreds of lines of code but I only included what I thought was necessary for this particular method. I have a test harness so I know that all the submethods work correctly. The problem that I'm struggling with though is the 3rd line where I'm adding factor1 to the product. The values add correctly but then when factor1 is multiplied by 2 in the 5th line then the value that was added to product in the 3rd line also gets doubled resulting in an incorrect product value. How can I make sure that when factor 1 is doubled that it doesn't carry backwards to the product term?
while (Long.parseLong(factor2.toString()) >= 1) {
if (factor2.bigIntArray[0] % 2 == 1) {
product = product.add(factor1);
}
factor1 = factor1.multiplyByTwo();
factor2 = factor2.divideByTwo();
}
I think in your method multiplyByTwo you use code
`datamember=datamember*2;`
rather than that try doing this
return new FactorClass(datamember*2);
so it doesnt change the added value.
it would be better if u could show the mulTiplyByTwo method code since that is where your actually are getting the changed value.
I'm at my wit's end... I understand the easier examples of recursion, but I when it gets tricky I don't have a clue. Here is an example. I would be glad if someone can say what it does. What does the compiler do...
public static char mystery(String s, int n, int m)
{
if (n==1) return s.charAt(m);
char first = mystery(s, n/2, m*2);
char second = mystery(s, n/2, m*2 +1);
System.out.print(first + " " + second + " ");
return first;
}
What is printed when the method is called with:
mystery("fredpass", 5, 1)
The answer is p a s s p s
I don't have a CLUE how they get there...
Would REALLY appreciate it if someone can help me with this matter. On other places on the internet they only explain factorial - easy examples. Not sure what happen if you call it twice as in char first = mystery ( blah ); and then again char second = mystery ( blah );
Just trace the calls by hand:
mystery(5, 1)
first = mystery(2, 2)
first = mystery(1, 4) = 'p'
second = mystery(1, 5) = 'a'
second = mystery(2, 3)
...
and so on. Give yourself enough paper to draw a complete picture of the call stack, the state of a function call, and the local variables. For example, after the innermost call in my picture prints "p a ", it returns 'p', so I would write that letter after mystery(2, 2).
So, you already know examples of recursion and how it can be used.
Perhaps what you are missing is why recursion works. In order to understand this you need to know what happens when a method is called. Familiarize yourself with the call stack.
In terms of what happens logically, you should just consider 'walking' across the code sequentially. When you call a method recursively, it will simply return the result and continue execution as it would in any other procedural code. Every method call however has its own scope of variables which are only valid in that particular call of the recursion.
Hand "executing" as described in #jleedev's answer is a useful exercise, especially if you've never done it before.
An alternative is to run the code under the control of a Java debugger, and single step the execution while examining the call stack / local variables. This is less error prone, though if you do it too quickly you might miss important details of what is actually going on.
Don't be too worried that it is a mystery to you what the mystery function actually does. It is clearly designed to be difficult to understand. (And I cannot see any point to it ... apart from being mysterious.) Most recursive functions that you are likely to encounter will do something useful, and will be easier to understand ... with experience ...
For every recursion there are two things to be considered
Every recursive method should have a base case.
Every recursion should progress towards this base case