The method is to record the number of strokes a player took when completing a hole. The method returns true when strokes are successfully recorded. There are 2 caveats: (1)the hole must be recorded in order and must start with 1. If a hole is received out of order, the score is not recorded and false is returned (2)The hole number must also be valid. You can't record a score for a hole that is less than 1 or greater than the number of holes on the course. Code gives a java.lang.NullPointerException. What does this mean and how do i fix it
Note: holesPlayed is an instance variable assigned the value of 0
Here is what i have:
public boolean recordStrokes(int holeNumber, int strokes) {
if ((holeNumber >= 1) && (holeNumber <= Course.NUM_OF_HOLES)
&& (holeNumber == holesPlayed + 1)) {
scores[holeNumber -1] = strokes;
holesPlayed = holesPlayed + 1;
return true;
} else {
return false;
}
}
When holeNumber 1 is handed in, holesPlayed is 0, so this fails: holeNumber <= this.holesPlayed.
Related
I have a method getNextPrime(int num) which is supposed to identify the closest prime number after the value received by the method.
If num is even, it will increment it and call itself again. If it is odd, it will run a for loop to check if it is divisible by odd numbers between 3 and num's half value. If it is then it will increase num by 2 and the method will call itself again, otherwise it will return the new num value which is a prime number.
The problem is, when the program gets to the return statement, it will jump to the if statement and return the original value of num + 1. I have been debugging this for a while and it just doesn't make sense. Wherever I place the return statement, the method just jumps to the if statement instead of terminating the method and returning the value to where it is being called from.
public int getNextPrime(int num){
if(num % 2 == 0){
//even numbers are not prime
getNextPrime(++num);
}
else{
for(int i = 3; i < (num + 1) / 2; i += 2){
if(num % i == 0) {
getNextPrime(num += 2); //consider odd numbers only
}
}
}
return num; //jumps to if and terminates
}
However, if I change the else statement to a separate if statement, if(num % 2 != 0) it works.
Why does this happen?
*Note - the values given to the method are greater than 3, the fact that 1, 2, and 3 are primes doesn't matter.
There is only one structural problem here. Reaching a single return does not collapse the entire call stack, it only returns to the previous invocation.
You need to save the result of calling getNextPrime() every time and use that as the return value, so the value actually found gets passed back along the call chain and returned to the initial caller. As it stands you return only the number that was passed in since you never modify it.
The fix is a very simple modification. Where you have
getNextPrime(++num);
... and ...
getNextPrime(num+2);
replace them with
return getNextPrime(++num);
... and ...
return getNextPrime(num+2);
The problem with the algorithm you chose is that it is inefficient. You need to test divisibility using smaller primes only, not all odd numbers, and only up to the square root of the original number.
Implementation is left as an exercise.
Lets try to look at the call stack when we call your function with argument 8;
The first call is : getNextPrime(8). As the number is even, the function goes into the if part and calls itself again with getNextPrime(9). This time the else part kicks in, checks for divisibility in for loop, finds that 9 is divisible so calls the getNextPrime(11). Now getNextPrime(11) goes again the else and the for loop and finds that 11 was prime and returns the number 11 to the caller, but if you look closely, you don't store this value in a variable, the num variable in the getNextPrime call was 9, and when getNextPrime(9) returns it returns that value to getNextPrime(8). In your getNextPrime(8) too you haven't really stored the num variable returned from the recursion call stack. You are just return the num variable defined in that function, which you happened to increment before calling the getNextPrime(11) so this value is 9, and 9 is returned.
Corrected program with the same if else block is given below for your reference.
public static int genNextPrime(int num) {
if (num % 2 == 0) {
num = genNextPrime(++num);
} else {
for (int i = 3; i < (num + 1) / 2; i += 2) {
if (num % i == 0) {
num += 2;
num = genNextPrime(num);
}
}
}
return num;
}
Your return statement works fine but ..you have left 1,2 and 3 out of your logic. 2 is a even prime number and 1 is not a prime number.
I need to build a method that calculates prime numbers.
I'm testing it and it's giving me the wrong answers and I don't know how to solve it! For example, it returns true to 98262679 instead of false. Where is my mistake?
public static boolean itsPrime(int nbTest){ // Tests for prime numbers method
boolean prime = false;
if (nbTest <= 1){
return false;
} else if (nbTest == 2){ // Two is prime
return true;
} else if ((nbTest != 2) && (nbTest % 2 == 0)){ // Evens except number 2
return false; // are not prime
} else if (nbTest % 2 != 0){ // For all remaining odds
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2){
if (nbTest % i == 0){
prime = false;
} else {
prime = true;
}
}
}
return prime;
}
I'm learning Java and my professor asked us to construct the method itsPrime was based on this:
For the first subtask, write a function `itsPrime` that takes an `int`
as argument and returns a `boolean`, `true` if the argument integer is prime
and `false` otherwise.
To test whether an integer x is prime, one can proceed as follows:
all integers less than or equal to 1 are not prime;
2 is prime;
all other even integers are not prime;
for all remaining integers (obviously odd), search for a divisor:
loop from 3 to the square root of the integer x (The square root of x can
be computed as ‘‘Math.sqrt(x)'' in Java.); if the remainder of the integer
division of x by the loop index is zero, then x is not prime;
if all remainders were non-zero at the end of the loop, then x is prime;
I know the answer is there somewhere in all the answers above, but I think that each require an explanation.
Here's a summary of all the enhancements you could make to your code:
1) Don't declare a boolean to return, since you are already returning true or false throughout your code. Remove this line from your code (call it [1]):
boolean prime = false;
You'll see why after you've fixed the rest of your function. Comment it out if desired, for now.
2) In your second else if, let's call it [2], you have:
else if ((nbTest != 2) && (nbTest % 2 == 0)){
return false;
}
You already checked if nbTest is 2 in your first else if, so you don't need to check if it's not 2 again. If it entered the first if else, your function will return true. When a function returns, it is done. It returns the value to the caller and the rest of the code is not executed.
Thus, you may replace that second if else, [2], with:
else if (nbTest % 2 == 0) { // all other even integers are not prime
return false;
}
3) If you enter third else if, this means that the rest of the code above already executed, and it either returned, or the program continued.
You may replace that third else if (nbTest % 2 != 0){ for:
else {
4) This is the one error that you really have to make your function return the wrong answer (call this snippet [4]):
if (nbTest % i == 0){
prime = false;
If you find that the number you are testing is divisible (i.e. the remainder is zero), you are done. You definitely know that it is not prime.
You may replace this code, [4], with:
if(nbTest % counter == 0) {
return false;
}
Thus, returning false. It is not a number. And the function does not keep executing. Your error was continuing execution after the function finds out that your input is not prime.
Finally, you may leave your return true at the end of the function body. If the function never returned from the previous tests, or from the loop, it has to be a prime number. Remember that first line I told you to remove? The boolean declaration? Since you never return a value from a variable, you just return true or false, you don't need that [1] line.
As an extra, a good read on finding prime numbers, which you might want to share with your professor:
https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
You should stop once you here:
if (nbTest % i == 0){
return false;
}
Delete the prime variable (it is an unnecessary step, see below).
Change the for loop:
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2){
if (nbTest % i == 0){
prime = false;
} else {
prime = true;
}
}
To this:
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2)
if (nbTest % i == 0)
return false;
This simply breaks out of the function early if it isn't prime (if a factor has been found).
You shouldn't keep testing for primality once prime has been set to false for a number.
Replace:
if (nbTest % i == 0){
prime = false;
with:
if (nbTest % i == 0){
return false;
And the last test is useless, you can just keep a basic else:
else if (nbTest % 2 != 0){ => else {
Your for loop is not correct.
A prime number is a number which is divisible by 1 and itself only. So, if a number A is divisible by any other number except 1 and itself, then A is a nonprime.
Just replace your for loop with the one below
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2) {
if (nbTest % i == 0)
return false;
}
Once it is found that nbTest is divisible by some number, there is not point in continuing the loop. Return `nbTest is nonprime, then and there.
Can anyone please help me understand this code?
This code is used to solve this problem.
You are playing a game on your cellphone. You are given an array of length n, indexed from 0 to n−1. Each element of the array is either 0 or 1. You can only move to an index which contains 0. At first you are at the 0th position. In each move you can do one of the following things:
Walk one step forward or backward.
Make a jump of exactly length m forward.
That means you can move from position x to x+1, x−1 or x+m in one move. The new position must contain 0. Also you can move to any position greater than n-1.
You can't move backward from position 0. If you move to any position greater than n−1, you win the game.
Given the array and the length of the jump, you need to determine if it's possible to win the game or not.
n = sc.nextInt();
m = sc.nextInt();
field = new int[n];
for (int i = 0; i < n; i++) {
field[i] = sc.nextInt();
}
if (makeMove(0, new LinkedList<Integer>()))
System.out.println("YES");
else
System.out.println("NO");
.
.
.
private boolean makeMove(int position, List<Integer> prevPositions)
{
if (prevPositions.contains(position))
return false;
prevPositions.add(position);
if (position < 0) return false;
else if (position >= n) return true;
else if (field[position] == 1) return false;
else {
return makeMove(position + m, prevPositions) ||
makeMove(position + 1, prevPositions) ||
makeMove(position - 1, prevPositions);
}
}
input: 6 2
0 0 0 1 0 0
Output: Yes
input: 6 2
0 0 1 1 0 0
Output: No
So, I am assuming that you understand the concept of recursion, which is calling a method within itself, if not you may want to look it up.
The first section of code is very simple. It initializes the move length m and the array of length n and populates it with random binary digits.
The makeMove method goes through a few base cases to see if a branch of recursion has failed or succeeded.
1.) if (prevPositions.contains(position))
return false;
prevPositions.add(position);
After making a move, this code checks whether you have already gotten to this position. If you have, it returns false because this case has already been known to be false, otherwise the method would have already returned true.
2.) if (position < 0) return false;
else if (position >= n) return true;
else if (field[position] == 1) return false;
-You can't have a negative position, so that returns false.
-If your position is greater than n then you win, so return true
-You can't move to a position that contains a non-zero digit, so return false
3.) return makeMove(position + m, prevPositions) ||
makeMove(position + 1, prevPositions) ||
makeMove(position - 1, prevPositions);
This code makes recursive calls to other moves from possible positions and returns true if any of these calls are true. Since you can leap to position+m, then it makes sense that if makeMove(position+m, prevPositions) is true, then makeMove(position, prevPositions) is also true. Similarly you can move to position+1 and position-1 so calls to makeMove of these positions should return the same value as makeMove of your original position. Hope this made sense!
This solution works fine. Please try this. you need to pass, the element array length and the jump values.
public static boolean decideMove(int[] elements, int length, int jump){
boolean result = false;
boolean makeMove = true;
int currentPosition = 0;
while(makeMove){
if (currentPosition + jump > length-1){
return true;
}
if(elements [currentPosition + jump] == 0){
currentPosition = currentPosition + jump;
if (currentPosition + jump > length-1){
return true;
}
}
if (elements[currentPosition + 1] == 0){
currentPosition = currentPosition + 1;
if (currentPosition + jump > length-1){
return true;
}
}
if(elements[currentPosition +1] ==1 && elements[currentPosition + jump]==1){
if(elements[currentPosition - 1]==0){
currentPosition = currentPosition - 1;
} else{
return false;
}
}
}
return result;
}
I'm sure this is a very basic question but having trouble understanding why the below FOR loop works?
The code below brings back a set number of Primes and works as it should. I understand the whole math reasoning behind using square root, however my issue is more with the conditional part of the FOR statement.
The first argument that is fed into isPrime() to check is 2 which of course is Prime. The first isPrime() gets the square root of 2 which is ~ 1.4.
At this point, I get confused. Starting at i = 2 which is obviously > 1.4 so than the starting condition of i <= root (ie 2 <= 1.4) has NOT been met. The IF statement should not run and it should return no result, but it does.
It doesn't seem to me like I should get any result back until I get to 5 because 2 is also > than the square root of 3. I'm obviously not understating either the initialization or conditional aspect of the FOR statement here? Can someone please help me with the logic?
class BooleanTest{
public static void main(String[] arguments) {
int quantity = 10;
int numPrimes = 0;
int candidate = 2; //starting prime #
System.out.println("First " + quantity + " primes:");
while (numPrimes < quantity) {
if (isPrime(candidate)) { //if isPrime Method true
System.out.println(candidate);
numPrimes++;
}
candidate++;
}
}
public static boolean isPrime(int checkNumber) {
double root = Math.sqrt(checkNumber); //get square root of candidate
for (int i = 2; i <= root; i++) {
if (checkNumber % i == 0) { //if remainder of candidate/i = 0
return false; //because candidate is not prime. has factor other than 1 and self.
}
return true;
}
}
For inputs 1, 2, 3 the loop will not execute at all, indeed. As a result, the return false statement in the body of the loop will not be executed as well. Instead the return true statement right after the loop will get executed and the result of the method call will be true for these inputs.
The first number for which the loop will execute is 4 and the method will correctly return false as 4 is divideable by 2.
Fixing the indentation of the code makes this behavior a bit easier to see:
public static boolean isPrime(int checkNumber) {
double root = Math.sqrt(checkNumber); //get square root of candidate
for (int i = 2; i <= root; i++) {
if (checkNumber % i == 0) { //if remainder of candidate/i = 0
return false; //because candidate is not prime. has factor other than 1 and self.
}
}
return true;
}
root is not initialized to sqrt(2), it's initialized to sqrt(checkNumber), which would be larger than 2 for most inputs. Therefore your So than the starting condition of i <= root (ie 2 <= 1.4) has NOT been met so then the IF statement should not run and I would get no result back assumption is false.
I'm trying to do the below tutorial question.
// Create a method called greatestCommonFactor
// It should return the greatest common factor
// between two numbers.
//
// Examples of greatestCommonFactor:
// greatestCommonFactor(6, 4) // returns 2
// greatestCommonFactor(7, 9) // returns 1
// greatestCommonFactor(20, 30) // returns 10
//
// Hint: start a counter from 1 and try to divide both
// numbers by the counter. If the remainder of both divisions
// is 0, then the counter is a common factor. Continue incrementing
// the counter to find the greatest common factor. Use a while loop
// to increment the counter.
And my code is below
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Ex4_GreatestCommonFactor {
// This is the main method that is executed as
// soon as the program starts.
public static void main(String[] args) {
// Call the greatestCommonFactor method a few times and print the results
}
public static int greatestCommonFactor(int a, int b){
int i = 1 ;
while (i >= 1 ){
i++;
}
if (a%i == 0 && b%i == 0){
ArrayList factor = new ArrayList<Integer>();
factor.add(i);
}
else if (a%i <= 1 || b%i <= 1){
Collections.sort(factor);
List<Integer> topnum = factor.subList(factor.size() - 1, factor.size());
}
return topnum;
}
}
So I have 2 questions.
1) In my elseif statement, I get an error where factor cannot be resolved to a variable. How do I "carry over" the factor ArrayList from the previous If statement into this elseif statement?
2) I also get a similar error where topnum cannot be resolved. Is this also a placement error for this line of code in my method, or am I making a completely different mistake?
1) In my elseif statement, I get an error where factor cannot be resolved to a variable. How do I "carry over" the factor ArrayList from the previous If statement into this elseif statement?
by declaring it before if
ArrayList factor = null;
if ( /* some condition */ ) {
// initialize factor
} else if (/* some condition */) {
// access factor here
}
Each variable (amongst other 'parts' of java) has a scope, in which it is available.
The scope is usually the block in which the variable is declared.
Block: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/expressions.html
In your method greatestCommonFactor there are three variables, which are valid in the whole method:
a, b, i
You can access them everywhere from the start of you method (the first open brace) till the end of it (the last close brace).
The block inside your first if statement is an new scope. factor is declared in this scope and is no longer available, after program execution leaves this block.
if (a%i == 0 && b%i == 0){ // Start of Block/Scope
ArrayList factor = new ArrayList<Integer>(); // Declaration, you can access factor now
factor.add(i);
} // End of Block/Scope, factor inaccessible
The else if part is an new block with it's own scope.
else if (a%i <= 1 || b%i <= 1){
Collections.sort(factor);
List<Integer> topnum = factor.subList(factor.size() - 1, factor.size());
}
factor, being declared in the first block does not exists any more.
You could pull up the declaration and put it outside the if.
public static int greatestCommonFactor(int a, int b){
int i = 1 ;
while (i >= 1 ){
i++;
}
ArrayList<Integer> factor = new ArrayList<Integer>();
if (a%i == 0 && b%i == 0){
factor.add(i);
}
else if (a%i <= 1 || b%i <= 1){
Collections.sort(factor);
List<Integer> topnum = factor.subList(factor.size() - 1, factor.size());
}
return topnum;
}