I'm working on a small program where a method takes 3 int's bigCount smallCount and goal.
These variables are supposed to represent the number of bags of flour in 2 sizes, the bigCount weight value is 5 kilos per bag, smallCount weight value is 1 kilo per bag and goal is the goal weight of the box that would contain the bags.
for example bigCount = 1, bigCount = 1, smallCount = 0, goal = 4
Should return a value of false since bigCount is given the value of 1 and 1 value in bigCount is representative of a 5 kilo bag and thus the bags that you have would never fit into a box with the weight requirement of 4.
At first, I tried to create a bunch of if and else if statements that would return a true value if the values of bigCount and smallCount could be added in a combination to sum to the weight given in the goal variable.
I feel like there is a much smarter way to go about this but I can't figure out an algorithm that could simply wrap all this up without all these if and else if statements. Currently, the logic for some of these if statements is incorrect and not catching all the scenarios to make it work properly.
public static boolean canPack(int bigCount, int smallCount, int goal){
boolean isPackable = false;
int bigBKilo = bigCount*5;
int smallBKilo = smallCount*1;
int remain5 = goal %5;
int remainTest = 6 %5;
int sum = bigBKilo+smallBKilo;
if( bigCount < 0 || smallCount < 0 || goal <0){
isPackable = false;
}else{
if(remain5 > 0 && remain5 <= smallCount && smallCount >= goal) {
isPackable = true;
}
else if(remain5 == 0 && bigCount > 0){
isPackable = true;
}
else if(bigCount == 0 && smallCount >= goal){
isPackable = true;
}
else if(smallCount ==0 && remain5 == 0){
isPackable = true;
}
else if(sum == goal){
isPackable = true;
}
else if(bigBKilo < goal && remain5 <= smallCount){
isPackable = true;
}
else if(bigCount == 0 && smallCount < goal){
isPackable = false;
}
else{
isPackable = false;
}
}
return isPackable;
}//end method
One possible way to solve the problem with some math is as follows:
Pick the biggest bag
Try to fit as many of them in the box as possible (limited by box goal and amount of bags available) - by doing some math
Calculate amount of space remaining in the box after those operations
Pick second biggest bag
Try to fit as many of those in the remaining space as possible
Repeat until you run out of bags or remaining space is 0
I think you should be able to implement this algorithm on your own.
Related
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;
}
Im trying to pick from a list of 5 numbers, the biggest and the smallest numbers.
With the biggest I have no problems, either with the smallest for some cases.
But, for the smallest number I would like to adding a condition that if its zero ('0'), I wouldn't pick it, thats mean from 5 numbers I would like to pick the smallest one, that is not 0.
for example:
1000 2000 3000 0 0
I would like to pick the 1000.
Also, I can't use any methods, or based functions, Just If statements.
thats my code:
if((manufactorsPrice1<manufactorsPrice2)&&(manufactorsPrice1<manufactorsPrice3)&&(manufactorsPrice1<manufactorsPrice4)&&(manufactorsPrice1<manufactorsPrice5)){
if(manufactorsPrice1>0){
smallestPrice=manufactorsPrice1;
}
}else if((manufactorsPrice2<manufactorsPrice3)&&(manufactorsPrice2<manufactorsPrice4)&&(manufactorsPrice2<manufactorsPrice5)){
if(manufactorsPrice2>0){
smallestPrice=manufactorsPrice2;
}
}else if((manufactorsPrice3<manufactorsPrice4)&&(manufactorsPrice3<manufactorsPrice5)){
if(manufactorsPrice3>0){
smallestPrice=manufactorsPrice3;
}
}else if(manufactorsPrice4 < manufactorsPrice5){
if(manufactorsPrice4>0){
smallestPrice=manufactorsPrice4;
}
}else{
if(manufactorsPrice5>0){
smallestPrice=manufactorsPrice5;
}}
Thats work fine if I could pick the 0 as the smallest, But I cannot. Please help me, How can I pick the next smallest number that is not a Zero from the list.?
thanks.
Here is a solution which only uses an extra local variable to reduce nesting. It will find the minimum non-zero value (if it exists) or zero in the case they are all 0. It also uses fewer comparisons.
...
int min1, min2;
if (a2 == 0 || (a1 < a2 && a1 != 0))
min1 = a1;
else
min1 = a2;
if (a4 == 0 || (a3 < a4 && a3 != 0))
min2 = a3;
else
min2 = a4;
if (min1 == 0 || (min2 < min1 && min2 != 0))
min1 = min2;
if (min1 == 0 || (a5 < min1 && a5 != 0))
min1 = a5;
return min1;
Solution appropriate for your teacher who only allows the use of conditionals...
s=
(s=
(s=
(s=
x2!=0&&x2
<x1?x2:x1)>x3
&&x3!=0?x3:s)>x4
&&x4!=0?x4:s)>x5
&&x5!=0?x5:s;
I took a programming class, and I'm revisiting old programs that I did not quite get right. This one is a Game Of Life program, and I have a question about code cleanup.
I need to make sure that an array element is in bounds before checking whether its neighbor's boolean value is true or false. I have a statement to check if firstGen[0][0]'s top-left (up one row, left one column) is in bounds. Is there an easier or more elegant way to check if an element is in bounds or to restrict the element checks to the boundaries of a given array without using four && conditionals per if statement?
Note that I have only changed the first if statement thus far, so there may be errors elsewhere. I also excluded the boundary checks for the other neighbors.
public static boolean[][] generation(boolean[][] firstGen)
{
int length = firstGen.length;
boolean[][] newGen = new boolean[length][length];
for (int j = 0; j < firstGen[0].length; j++)
{ for (int i = 1; i < firstGen.length; i++)
{
int count = 0;
if ((i-1 >= 0) && (i-1 < length) && (j-1 >= 0) && (j-1 < length)) //top-left element exists
{ if (newGen[i-1][j-1] == true) count++; } //increment `count` if top-left element is true
if ((newGen[i][j] == false) && (count == 3)) newGen[i][j] = true;
else if ((newGen[i][j] == true) && (count == 1)) newGen[i][j] = false;
else if ((newGen[i][j] == true) && (count > 3)) newGen[i][j] = false;
else break;
}
}
return newGen;
}
If i and j are in bounds, then you know for sure that i - 1 < length and j - 1 < length are both true.
Also:
i - 1 >= 0 can be written i > 0
if (condition == true) can be rewritten if (cond)
So you could replace:
if ((i-1 >= 0) && (i-1 < length) && (j-1 >= 0) && (j-1 < length)) //top-left element exists
{ if (newGen[i-1][j-1] == true) count++; } //increment `count` if top-left element is true
by:
//increment `count` if top-left element is true
if (i > 0 && j > 0 && newGen[i-1][j-1]) count++;
That's the best way I can think of to check if its out of bounds, but an alternative method in general, and one that I think gives programs like the Game of Life more exciting outcomes, is adding periodic boundaries. Basically this means that if you walk off one edge, you end up on the other side (like in pac-man). It sounds complicated, but really all it takes is the % function, which returns the remainder of division between the two numbers given.
So:
27 % 5 = 2;
So for adding periodic boundries you would update x and y positions like this:
x = (x + xStep + horizontalSize) % horizontalSize;
y = (y + yStep + verticalSize) % verticalSize;
Where xStep and yStep are +1 or -1 depending on what direction you want to go. (this works nicely with a for loop) The addition of the size is to make sure you go below zero when you get close to borders.
Then you never have to worry about messy border conditions, everything simply overlaps. No need to check each and every border. I hope this makes sense. Please ask for clarification if not. I've used this more for random walker programs but the idea is the same.
For my Mastermind Game I am using 6 numbers instead of 6 colours. Also instead of showing black and white pegs, just 2 sentences are outputted. One reads:
"The number of correct digits in the right position is __ "(black pegs/bothRight)
"The number of correct digits in the wrong position is __ "(white pegs/numberRight)
For the 4 digit guesses that are submitted, I am using an array called guessArr, which accepts 4 values from 4 input boxes.
guess0 = Integer.parseInt(firstInput.getText());
guess1 = Integer.parseInt(secondInput.getText());
guess2 = Integer.parseInt(thirdInput.getText());
guess3 = Integer.parseInt(fourthInput.getText());
//New array to arrange guesses
int[] guessArr = new int[] {guess0,guess1,guess2,guess3};
For the answer generated by the computer,
//Create a 4 digit code made of random numbers between 1 and 6
answerArr[0]=(int)(Math.random()*6+1);
answerArr[1]=(int)(Math.random()*6+1);
answerArr[2]=(int)(Math.random()*6+1);
answerArr[3]=(int)(Math.random()*6+1);
Finding the amount of black pegs is easy:
//Calculate number of correct digits in correct position
for (int i = 0; i < 4; ++i)
{
if (answerArr[i] == guessArr[i])
{
used[i] = true;
bothRight++;
}
}
EDIT
I've Solved It!
// Calculate number of correct numbers in wrong position
//Declare variables for what digits are in the answer
Integer digit1 = 0, digit2 = 0, digit3 = 0, digit4 = 0, digit5 = 0 , digit6 = 0;
//Find what the answer digits are
for (int k = 0; k < answerArr.length; ++k){
if (answerArr [k] == 1)
{
digit1++;
}
if (answerArr [k] == 2)
{
digit2++;
}
if (answerArr [k] == 3)
{
digit3++;
}
if (answerArr [k] == 4)
{
digit4++;
}
if (answerArr [k] == 5)
{
digit5++;
}
if (answerArr [k] == 6)
{
digit6++;
}
}
//Declare variables for what digits are in the answer
Integer gDigit1 = 0, gDigit2 = 0, gDigit3 = 0, gDigit4 = 0, gDigit5 = 0 , gDigit6 = 0;
//Find the guess numbers submitted
for (int p = 0; p < guessArr.length; ++p){
if (guessArr [p] == 1)
{
gDigit1++;
}
else if (guessArr [p] == 2)
{
gDigit2++;
}
else if (guessArr [p] == 3)
{
gDigit3++;
}
else if (guessArr [p] == 4)
{
gDigit4++;
}
else if (guessArr [p] == 5)
{
gDigit5++;
}
else if (guessArr [p] == 6)
{
gDigit6++;
if (gDigit6 == 0)
{
gDigit6++;
}
}
//Find the value of correct numbers submitted in the guess
Integer correctNumbers = Math.min (digit1, gDigit1) + Math.min (digit2, gDigit2) + Math.min (digit3, gDigit3) +
Math.min (digit4, gDigit4) + Math.min (digit5, gDigit5) + Math.min (digit6, gDigit6);
//Calculate value of numberRight
numberRight = (correctNumbers - bothRight);
}
Any help would be greatly appreciated. :D Thanks.
First, I'll say up front, I'm not going to give you any code since this is either a learning exercise, so you can learn the language, or else this is a class problem.
So, lets think about this logically... One way you can you can solve this is by counting the number of a type of colors.
As an example, suppose the player guessed 2 blues, and 2 greens, and the answer has 1 blue, 1 red, and two greens.
The player guessed 3 of the right colors, so you would give them 3 white pegs UNLESS they got some in the right spot. Now, suppose that they got one of those blues in the right spot, that means they have 1 black peg, which replaces a white peg. So, the grand total is 2 white pegs, and 1 black peg.
So, to find the number of "Correct Colors" you should check each color (good chance for a loop?) and compare the number of each color that the player guessed, to the number of each color that the solution has.
Put another way, you don't want to compare the guess to the answer. You want to compare the count for each color on the guess, to the count of each color on the solution.
Then, you get "White pegs" by this pesudo-code:
int whitePegs=correctColors-blackPegs;
Edit 1: Comparing answers one color at a time
If you're going to hold the count for each color, then you're going to want to use two arrays, one for the guess, and one for the solution. Each element in the array will hold the count for the color, like this:
r=red, o=orange, y=yellow, etc.
R O Y G B
Guess: [0][2][1][1][0] (Total is 4, for 4 pegs
Actual: [1][1][2][0][0] (Total is 4) for 4 pegs
Matches:[0][1][1][0][0] (Total is 2) This is "correctColors" from above