Given 1 coin from multiple denominations (E.G. a 1 coin, 5 coin, 16 coin), and a sum, return true or false determining if the sum can be made.
boolean go(int[] coins, int goal)
{
//Will set each time, but shouldn't matter as toggle is at bottom
boolean ans = false;
//loop running in recursion till founds ans
//Really bad time complexity lol
for (int i = 0; i < coins.length && (!ans); i++) {
if ((goal - coins[i] == 0) || goal == 0) {
return true;
}
if (goal > coins[i]) {
int[] red = new int[coins.length - 1];
//it necessary because making list with one less
int it = 0;
//Setting new list to avoid runtime
for(int x = 0; x < coins.length; x++){
if(!(i == x)){
red[it] = coins[i];
it += 1;
}
}
//Run with new list
ans = go(red, goal - coins[i]);
}
}
return ans;
}
This is my code so far. I have made it recursive, yet one of the test cases returns true when it should not. The test case in particular is [111, 1, 2, 3, 9, 11, 20, 30], with the goal doing 8; This should return false (as it cannot add up to 8), but in this case, returns true.
Other test cases work fine, so I believe my code has some sort of an exception.
I have tried to move the base case upward, and make a reverse variation...
boolean go(int[] coins, int goal)
{
boolean ans = false;
if(goal == 0){
return true;
}else if(goal < 0){
return false;
}
for (int i = 0; i < coins.length && (!ans); i++) {
if (goal >= coins[i]) {
int[] red = new int[coins.length - 1];
int it = 0;
for(int x = 0; x < coins.length; x++){
if(!(i == x)){
red[it] = coins[i];
it += 1;
}
}
ans = go(red, goal - coins[i]);
}
}
return ans;
}
is what I've tried, but the base case doesn't seem to affect anything
The bug is in your copying of the coins array: red[it] = coins[i] should really be red[it] = coins[x]...
For time complexity, you don't really have to do a loop inside the method. Each denomination is either part of the sum or not, so you can always remove the first denomination and test with and without it:
boolean go(int[] coins, int goal) {
if(goal == 0)
return true;
else if(coins.length == 0 || goal < 0)
return false;
else {
int[] tailOfCoins = Arrays.copyOfRange(coins, 1, coins.length);
return go(tailOfCoins, goal) || go(tailOfCoins, goal - coins[0]);
}
}
Related
Im trying to make a method which checks if there is an odd number in an array. If there is an odd number it should return true. If there are no odd numbers in the array it should return false. For example if the array a is {1,2,3} it should return true because there is an odd number.
Here is the array:
int[] arraySum1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
The problem is the boolean variable hasUneven is reset everytime it goes into the for loop. In this case it only checks the last value which is 10 in this case and then return false everytime I call the method.
Here is my code so far:
public boolean hasUneven(int[] a) {
boolean hasUneven = false;
int uneven = 0;
for (int i = 0; i < a.length; i++) {
uneven = a[i];
if (uneven % 2 != 0) {
hasUneven = true;
} else {
hasUneven = false;
}
}
return hasUneven;
}
you can directy return when you find your first odd number.
public boolean hasUneven(int[] a) {
for (int i = 0; i < a.length; i++) {
if (a[i] % 2 != 0) {
return true;
}
}
return false;
}
You need an exit condition. You can do that by returning true as soon as there is an uneven number e.g.
for (int i = 0; i < a.length; i++) {
uneven = a[i];
if (uneven % 2 != 0) {
return true;
}
}
return false;
The problem is that your method should return as soon as it has found an odd number. Now your code traverses the entire array and assigns the hasUneven value for each number. 10 being the last one and therefore an even number.
Try replacing your if construction with:
if (uneven % 2 != 0) {
return true;
}
...
return false;
for(int i=0; i<a.length; i++){
if(a[i]/2=0)
return true;
}else{
return false }
I'm trying to make a while loop that iterates through every long number possible and add every prime number it encounters into an the primes array. Since the while loop is supposed to run until the length of primes is 200, I expect the primes array to be filled with the first 200 prime numbers. Instead I get all zeroes. I have successfully gotten 20 rows of 10 characters each with a space in between them. How may I get them to be the actual prime numbers though?
public class PrimeGenerator {
public static void main(String[] args) {
long primes[] = new long[200];
while (primes.length > 200){
for(long y = 2; y < Long.MAX_VALUE; y++) {
int primeCounter = 0;
if (isPrime(y) == true){
primes[primeCounter] = y;
primeCounter++;
}
}
}
for (int i = 0; i < 20; i++) {
int primeCounter = 0;
for(int p = 0; p < 10; p++) {
System.out.print(primes[primeCounter] + " ");
primeCounter++;
}
System.out.println();
}
}
public static boolean isPrime(long number) {
if (number % 2 == 0)
return false;
if (number == 2)
return true;
for(int x = 3; x*x <= number; x+=2) {
if (number%x == 0)
return false;
}
return true;
}
}
primes.length is always 200 so the while loop is never entered.
The while loop is useless. Just add a condition to the for loop that would exit when the entire array has been assigned. Also move the initialization of primeCounter to be outside the for loop. Otherwise all the primes will be assigned to primes[0].
long primes[] = new long[200];
int primeCounter = 0;
for(long y = 2; y < Long.MAX_VALUE && primeCounter < 200; y++) {
if (isPrime(y) == true){
primes[primeCounter] = y;
primeCounter++;
}
}
for (int i = 0; i < primes.length; i++) {
System.out.print(primes[i]);
if ((i+1) % 10 == 0)
System.out.println();
}
EDIT :
As Sweeper commented, you should also fix your isPrime method, since it returns false for 2 :
public static boolean isPrime(long number) {
if (number == 2)
return true;
if (number % 2 == 0)
return false;
for(int x = 3; x*x <= number; x+=2) {
if (number%x == 0)
return false;
}
return true;
}
this code down
long primes[] = new long[200];
while (primes.length > 200){
means
while (200 > 200){
or the same as
while (false){
so your loop is NEVER executed!
because you did:
while (primes.length > 200)
and the length of the array is always 200,you never get into the while loop , and the zero in the array are coming because when you create array of "long" it initialized him with zeros
Firstly, the length of an array doesn't change. So, when you are testing for primes.length > 200 this will always be false, and the loop is never even entered. Therefore all values in the array are left at the default value of 0.
For doing this I would doing something like the following:
int primeCounter = 0;
long current = 0L;
while(primeCounter < primes.length){
if(isPrime(current)){
primes[primeCounter] = current;
primeCounter++;
}
current++;
}
An array's length never changes. If you declared an array to have a length of 200, it will always have a length of 200. Because of this, your while loop is never executed, not even once.
There are a lot of other errors in the code, so I tried to create a solution with as few changes as possible:
public static void main(String[] args) {
int primeCounter = 0;
long nextPossiblePrime = 2;
long primes[] = new long[200];
while (primeCounter < 200) {
for (long y = nextPossiblePrime; y < Long.MAX_VALUE; y++) {
if (isPrime(y) == true) {
primes[primeCounter] = y;
primeCounter++;
nextPossiblePrime = y + 1;
break;
}
}
}
primeCounter = 0;
for (int i = 0; i < 20; i++) {
for (int p = 0; p < 10; p++) {
System.out.print(primes[primeCounter] + " ");
primeCounter++;
}
System.out.println();
}
}
public static boolean isPrime(long number) {
if (number == 2 || number == 3)
return true;
if (number % 2 == 0)
return false;
for (int x = 3; x * x <= number; x += 2) {
if (number % x == 0)
return false;
}
return true;
}
The first problem is that you created two primeCounters, which is not needed. I removed the extra one and moved the scope of it to the scope of the method. The next problem is that your first for loop doesn't remember the prime number that it is on and it doesn't stop when it has found one so it will keep adding the 200th prime to the array. I fixed this by adding a nextPossiblePrime variable that stores what number should the program check next. The last problem is that your isPrime method is written incorrectly. I fixed it for you!
Here's another (cleaner) solution, which still uses a while loop:
public static void main(String[] args) {
ArrayList<Long> primes = new ArrayList<>();
long y = 2;
while (y < Long.MAX_VALUE && primes.size() < 200) {
if (isPrime(y) == true){
primes.add(y);
}
y++;
}
for (int i = 0; i < primes.size(); i++) {
System.out.print(primes.get(i) + " ");
if ((i+1) % 10 == 0)
System.out.println();
}
}
public static boolean isPrime(long number) {
if (number == 2 || number == 3)
return true;
if (number % 2 == 0)
return false;
for (int x = 3; x * x <= number; x += 2) {
if (number % x == 0)
return false;
}
return true;
}
I'm working on a Sudoku solver program. The idea is that the user inputs the Sudoku puzzle and the program solves it for them.
The program works fine when entering any normal puzzle. However, there are some puzzles that are impossible to solve. Here is one example that I entered: http://i.imgur.com/5L8pF8Q.png
The input is perfectly legal, but top right square cannot be filled in since all numbers 1-9 have been used in that row and column.
If I hit "Solve", my program freezes as it enters an infinite loop.
So my question here is, how can I prevent this from happening?
I tried implementing the "boolean flag" approach, but on second thought I realized that it's probably not feasible.
Here is my solver method:
public boolean solve(int i, int j) {
for (int a = 0; a < 9; a++) {
for (int b = 0; b < 9; b++) {
if (sudokuArray[a][b] == 0) {
for (int k = 1; k <= 9; k++) {
sudokuArray[a][b] = k;
if (checkNumber(a, b, k) && solve(a, b)) {
return true;
}else {
sudokuArray[a][b] = 0;
}
}
return false;
}
}
}
return true;
}
The checkNumber() method checks if number k can be legally inserted in row a, column b and returns true/false accordingly.
Ideas? Tips?
Thanks.
PS: Added checkNumber() as requested:
public boolean checkNumber(int i, int j, int num) {
for (int a = 0; a < 9; a++) {
if (a != i) {
if (sudokuArray[a][j] == num) {
return false;
}
}
if (a != j) {
if (sudokuArray[i][a] == num) {
return false;
}
}
}
for (int a = (i / 3) * 3; a < (i / 3) * 3 + 3; a++) {
for (int b = (j / 3) * 3; b < (j / 3) * 3 + 3; b++) {
if ((a != i) && (b != j)) {
if (sudokuArray[a][b] == num) {
return false;
}
}
}
}
return true;
}
This is just an idea (i would comment but this account is too new). Try making it so that if all numbers from 0-9 return false, then it returns an error of some sort. For example if it hasn't found an answer by 9, then move up to 10. If the program detects a 10, do some kind of System.out.println("Unsolvable") or something along those lines. Sorry if I'm confusing you by the way. I've been told I'm bad at explaining things.
This the question I must answer-
Given an array of ints, return true if the value 3 appears in the array exactly 3 times, and no 3's are next to each other.
haveThree({3, 1, 3, 1, 3}) → true
haveThree({3, 1, 3, 3}) → false
haveThree({3, 4, 3, 3, 4}) → false
This is my solution:
public boolean haveThree(int[] nums) {
int count = 0;
for (int i=0;i<nums.length-1;i++) {
if (nums[i] == 3 && nums[i+1] ==3) {
return false;
}
else
if ((nums[i]==3 && nums[i+1]!=3)||(nums[i]==3 && nums[i+1]!=3)) {
count ++;
}
}
return count ==3;
}
It fails for some tests. For example {3,1,3,1,3} should result in true being returned; however, false is returned and I can't figure out why.
You need to loop all the way to nums.length to count all occurences. Also, there is no need for the else statement. I would do something like:
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 3) {
if ((i < nums.length - 1) && (nums[i + 1] == 3)) {
return false;
}
count++;
}
}
It fails for that example because you don't check the last index, presumably to fix the out of bounds error for checking if two 3's are next to eachother. Also the or condition in your second if statement is redundant.
public boolean haveThree(int[] nums) {
int count = 0;
for (int i=0;i<nums.length-1;i++) {
if (nums[i] == 3 && nums[i+1] ==3) {
return false;
}
if ((nums[i]==3)) { //removed redundant condition and doesn't need to be an else
count ++;
}
}
// check the last index, you've already ensured the second to last is not also a 3
if(nums[nums.length-1] == 3) {
count++;
}
return count == 3;
}
Because you're not comparing the final value, you can't tell if the last array element is a three or not. What I would do (to guarantee going through each element as needed) is add a flag boolean that lets you know if the previous value was a three or not (resetting it back to false if the current value is not three).
My example:
public boolean haveThree(int[] nums) {
int count = 0;
boolean flag = false;
for(int i = 0; i < nums.length; i++) {
if(nums[i] == 3) { // The current value is a 3
if(flag) { // Previous value was a 3, rejecting.
return false;
}
else { // We have another 3, set the flag
count++;
flag = true;
}
}
else { // Since this wasn't a 3, we can set the flag back to false
flag = false;
}
}
return count == 3;
}
The for statement also has another form designed for iteration through Collections and arrays, and can be used to make your loops more compact and easy to read.
boolean haveThree(int[] nums) {
int count = 0, prevNum = 0;
for (int i : nums){
if (i==3) {
count++;
if (prevNum == i)
return false;
}
prevNum = i;
}
return count == 3;
}
As some people have already pointed out, you are not counting all the 3s that are present in the array. Your loop ends just before the last element in order to avoid ArrayIndexOutOfBoundsException.
It is a logical error. Your code fails for the test case that you've mentioned because first if condition returns false when i = 0. I wrote the following code snippet when I practiced. Hope it helps.
public boolean haveThree(int[] nums) {
int threeCount = 0;
boolean successive3s = false;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 3) {
threeCount++;
}
if (nums[i] == 3 && (i + 1) < nums.length && nums[i + 1] == 3)
successive3s = true;
}
return (!successive3s && threeCount == 3);
}
public boolean haveThree(int[] nums) {
int count = 0;
if(nums.length >= 1 && nums[0] == 3)
count++;
for(int i = 1; i < nums.length; i++) {
if(nums[i - 1] == 3 && nums[i] == 3)
return false;
if(nums[i] == 3)
count++;
}
return count == 3;
}
I made a trailing counter for mine.
public boolean haveThree(int[] nums)
{
//We check to see if it is possible to get 3 without being in a row.
//In this case, it is the smallest at five chars
//E.G 31313, so if we have any size less than this, we know it to be false.
if (nums.length >= 5)
{
//Create a counter to track how many 3's we have in a row,
//as well as how many we have total.
int counterInRow = 0;
int counterThrees = 0;
//Check for 3's
for (int i = 0; i < nums.length; i++)
{
//If a number is 3, we increment both;
if (nums[i] == 3)
{
counterInRow++;
counterThrees++;
}
//Otherwise, we reset the amount in a row to 0;
else
{
counterInRow = 0;
}
//If we have 2 or more in a row, we return false.
if (counterInRow >= 2)
{
return false;
}
}
//Return if the amount of the counterThrees equals 3 or not.
return (counterThrees == 3);
}
//If we have less than 5 characters, it isn't possible. We then,
//Return false;
else
{
return false;
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am trying to write a really simple poker game. I'm just using the non-face cards, 2-9, without suites or anything of the like. I'm trying to figure out how to write a method that determines if five cards are a full house, which is a pair and a 3 of a kind. I have the user input 5 integers that represent card values and store them in a single array. I tried writing something like this:
public static boolean containsFullHouse(int[] hand)
{
for (int i = 0; i < hand.length; i++){
int count = 0;
for (int j = 0; j < hand.length; j++){
if (hand[i] == hand[j]){
count++;}
if (count == 3){
return true;}
}
}
for(int i = 0; i < hand.length; i++){
for(int j = i + 1; j < hand.length; j++){
if(hand[i] == hand[j]){
return true;}
}
}
}
return false;
}
You need to count the occurrences of each number, and create what is called a cardinality map. Then the cardinalities must be (2,3) or (3,2). If not using guava or Apache Commons Collections (which contain convenience methods to do this), this can be done in the following way:
public static boolean isFullHouse(final int[] input) {
if (input.length != 5) { throw new IllegalArgumentException("need 5 integers"); }
Map<Integer, Integer> cardinalityMap = new HashMap<>();
for (int i : input) {
if (cardinalityMap.containsKey(i)) {
cardinalityMap.put(i, cardinalityMap.get(i) + 1);
}
else {
cardinalityMap.put(i, 1);
}
}
if (cardinalityMap.size() != 2) { return false; }
Collection<Integer> occurences = cardinalityMap.values();
int first = occurences.iterator().next();
return first == 2 || first == 3;
}
I would use CollectionUtils.getCardinalityMap from Apache Commons to do this
public static void main(String[] args) {
Integer[] fullHouse = new Integer[]{7, 7, 7, 4, 4};
Integer[] notFullHouse = new Integer[]{2, 2, 2, 2, 3};
Integer[] notFullHouse2 = new Integer[]{1, 4, 2, 2, 3};
System.out.println(isFullHouse(fullHouse));
System.out.println(isFullHouse(notFullHouse));
System.out.println(isFullHouse(notFullHouse2));
}
private static boolean isFullHouse(Integer[] cards){
Map<Integer,Integer> cardinalityMap = CollectionUtils.getCardinalityMap(Arrays.asList(cards));
if(cardinalityMap.size() == 2) {
if (cardinalityMap.values().containsAll(Arrays.asList(2, 3))) {
return true;
}
return false;
}
return false;
}
Problems:
You're checking index i twice, although correct (since you check for count == 3), it's unnecessary.
You're also returning before you check the other 2.
The second loop will return true since it will find the numbers from the previous loop.
If you sort them, you can simply check whether the two pairs of cards on both sides are the same and check whether the middle card is the same as either one. So something like this:
Arrays.sort(hand);
return (hand[0] == hand[1] && hand[3] == hand[4] &&
(hand[2] == hand[1] || hand[2] == hand[3]));
Alternatively, if you want to fix your function:
public static boolean containsFullHouse(int[] hand)
{
// a variable that keeps track of one of the 3-of-a-kind indices (used in 2-of-a-kind check)
int pos = -1;
for (int i = 0; i < hand.length && pos == -1; i++){
// start count at one instead
int count = 1;
// start j from next position rather than 0
for (int j = i+1; j < hand.length && pos == -1; j++){
if (hand[i] == hand[j]) {
count++;
}
if (count == 3) {
pos = i;
}
}
}
// if we didn't find 3-of-a-kind, return false
if (pos == -1)
return false;
// look for 2-of-a-kind
for(int i = 0; i < hand.length; i++){
// exclude elements that match one of the 3-of-a-kind
if (hand[i] != hand[pos]){
for(int j = i + 1; j < hand.length; j++){
if(hand[i] == hand[j]){
return true;
}
}
}
}
return false;
}
A full house consists of 2 different integers, so keep a counter for both. It also needs to keep track of the 2 different values. If you combine this you get something like this:
public static boolean containsFullHouse(int[] hand)
{
int value1 = -1, count1 = 0;
int value2 = -1, count2 = 0;
for (int i = 0; i < hand.length; i++) {
if(hand[i] == value1) {
// Found another value1 card
count1++;
} else if(hand[i] == value2) {
// Found another value2 card
count2++;
} else if(value1 == -1) {
// Found a new card, store as value1
value1 = hand[i];
count1++;
} else if(value2 == -1) {
// Found a new card, store as value2
value2 = hand[i];
count2++;
} else {
// Found a third card, so it cannot be a full house!
return false;
}
}
if(value2 == -1) {
// Found 'five of a kind'?!
return false;
}
// Check if it is a full house
return (count1 == 3 && count2 == 2) || (count1 == 2 && count2 == 3;)
}