Small Straight - Method - java

I've been stuck on this method for a couple of days now. This method checks to see if the roll of 5 dice == a small straight. It works for some numbers. If I roll a
1, 2, 4, 3, 6
it will work. However, if I roll a
1, 2, 4, 3, 3
it will not work. I think it's because of the duplicate 3 in there. I need to move it to the end somehow.
A small straight is when there are four consecutive die face values, such as 1, 2, 3, 4 or 3, 4, 5, 6. It can be in any order such as 2, 3, 1, 4
int counter = 0;
int score = 0;
boolean found = false;
Arrays.sort(die);
for (int i = 0; i < die.length - 1; i++)
{
if (counter == 3)
found = true;
if (die[i + 1] == die[i] + 1)
{
counter++;
}
else if (die[i + 1] == die[i])
{
continue;
}
else
{
counter = 0;
}
}
if (found)
{
score = 30;
}
else
{
score = 0;
}
return score;
}

The duplicate 3 is not what is throwing off the algorithm. The issue is that you check for the straight during the iteration AFTER it occurs. Thus, if the last die is part of the straight, it won't be recognized.
To fix this, move
if (counter == 3) found = true;
to the END of the loop. Should work.
EDIT: So it looks like this.
for (/*...*/) {
/* Everything else */
if (counter == 3) {
found = true;
break;
}
}

EDIT: First, if a small straight is three in a row, then you want to see if the counter gets to 2, not to 3. 3 would demand a four in a row.
Edit the start of the for loop as follows:
for (int i = 0; i < die.length ; i++)
{
if (counter == 2)
found = true;
if (i == die.length - 1) break;
//method continues here
Reasoning: I imagine that when you started coding this method, it was throwing IndexOutOfBoundsExceptions when it got to the last die in the array, tried to compare it to the nonexistant sixth die and died. So, you made the loop stop one short. But if it stops one short and the small straight is finished on the very last dice, then you never got into the loop again to confirm that the counter was 3 and a small straight had occured. By editing the start of the loop this way it goes all the way to the last element, checks and then breaks.
Alternatively, do one last check after the loop ends:
for (int i = 0; i < die.length - 1; i++)
{
if (counter == 2)
found = true;
if (die[i + 1] == die[i] + 1)
{
counter++;
}
else if (die[i + 1] == die[i])
{
continue;
}
else
{
counter = 0;
}
}
found = (counter == 2); // or counter >= 2 if you want larger straights to be found too
//continue method here

This should calculate the longest sequence:
int longestSequence(int[] a) {
Arrays.sort(a);
int longest = 0;
int sequence = 0;
for (int i = 1; i < a.length; i++) {
int d = a[i] - a[i - 1];
switch (d) {
case 0:
// Ignore duplicates.
break;
case 1:
sequence += 1;
break;
default:
if (sequence > longest) {
longest = sequence;
}
break;
}
}
return Math.max(longest, sequence);
}

You could add code such as
for (int i = 0; i < (die.length-1); i++)
{
if (die [i] == die[i+1])
{
die[i+1] =1;
}
}
Arrays.sort(die);
This will set the code for example from 1,2,3,3,4 to 1,1,2,3,4 so your code should then work.

Related

Why is this not working? (Java for loop condition part)

int cnt = 0, sum = 0;
for(int i = 1; ((i <= 1000) && (i%3 == 0) && (i%5 == 0)); i++){
if(cnt >= 5)
break;
System.out.println(i);
sum += i;
cnt++;
}
System.out.println(sum);
I want to get the first 5 numbers that are divisible by 3 as well as 5 between the range of [1, 1000]. This code does not shows any error but it returns 'sum' and 'cnt' both to it's default values (i.e. 0) and seems to me that it's not entering the for loop.
P.S. I am not advance level programmer. I'm trying this stuff just for exploration, so if any one could explain the actual reason behind this.
It sounds like you do not understand how a for loop works. #Silvio Mayolo and #experiment unit 1998X commented some very helpful links. I would encourage you to read through those and get comfortable with them.
In your example, your for loop has a very complex header.
for(int i = 1; ((i <= 1000) && (i%3 == 0) && (i%5 == 0)); i++){
Let's break this apart into sections.
for -- this is the keyword that starts the for loop
int i = 1; -- now you have created a variable in your loop. It is an int called i, and it has a starting value of 1.
(the termination expression) -- If the termination expression returns false, then loop stops looping. Let's see how you used it
i <= 1000 -- now you have added a rule --> in order for the for loop to perform a loop, the number i must be less than or equal to 1000. Ok, that is simple enough, you are now going to have at least 1000 valid values for i thus far.
i%3 == 0 -- now you have added another rule --> in order for the loop to perform a loop, the number i must have no remainder when divided by 3. Unfortunately, that is a problem because your starting value for i is 1, as mentioned earlier, and 1/3 DOES have a remainder. Therefore, the loop stops before it even starts.
This is your problem. If you want to check and see if i%3 == 0, you should not put that check inside of your termination expression. It should go inside of the enclosing block within the for loop. And the same applies for i%5 == 0.
Here is a runnable example to help you understand.
public class SOQ_20220516
{
public static void main(String[] args)
{
int cnt = 0;
int sum = 0;
for(int i = 1; i <= 1000; i++)
{
if(cnt >= 5)
{
break;
}
if ((i%3 == 0) && (i%5 == 0))
{
System.out.println(i);
sum += i;
cnt++;
}
}
System.out.println(sum);
System.out.println(cnt);
}
}
public class SOQ_20220516
{
public static void main(String[] args)
{
int cnt = 0;
int sum = 0;
for(int i = 1; i <= 1000; i++)
{
if(cnt >= 5)
{
break;
}
if ((i%3 == 0) && (i%5 == 0))
{
System.out.println(i);
sum += i;
cnt++;
}
}
System.out.println(sum);
System.out.println(cnt);
}
}
Blockquote

how to avoid arraysoutofbound exception when using || [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 1 year ago.
I have a question when executing following codes:
if(column!=n-1){
if(returnValue[row][column+1] == 0) column++;
else {
row++;
direction = "down";
}
}
else {
row++;
direction = "down";
}
If you see the codes, I need to check whether the column is exceeding the boundary first and then do another checking, which have duplicated codes in the else section. Is there a better way to write this logic?
I will give you an example cause sounds similar to a matrix issue , please focus on for loops cause the main key is there:
// JAVA Code for Boundary elements of a Matrix
class GFG {
public static void printBoundary(int a[][], int m,
int n)
{
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (i == 0)
System.out.print(a[i][j] + " ");
else if (i == m - 1)
System.out.print(a[i][j] + " ");
else if (j == 0)
System.out.print(a[i][j] + " ");
else if (j == n - 1)
System.out.print(a[i][j] + " ");
else
System.out.print(" ");
}
System.out.println("");
}
}
/* Driver program to test above function */
public static void main(String[] args)
{
int a[][] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 1, 2, 3, 4 }, { 5, 6, 7, 8 } };
printBoundary(a, 4, 4);
}
}
in order to avoid getting out of bounds, you'd have to check if row & column are within the boundaries of the array. I do not expect either value to go below 0 as there is no decrement if your code, so I only checked the length, but not negative indices.
if (row < returnValue.length && column < returnValue[row].length - 1 && returnValue[row][column+1] == 0) column++;
else {
row++;
direction = "down";
}

Some test cases not running but some are in terms of probability

I have a program in which it rolls five dice and assigns a hand to the rolls. i.e. nothing, a pair, two pair, three of a kind, full house, four of a kind, five of a kind. The code runs 1000000 times and gives percentage chances for each roll. Below I have attached general percentages my code should output near:
Case 1, None alike, is 0.092533
Case 2, One pair, is 0.462799
Case 3, Two pair, is 0.231789
Case 4, Three of a kind, is 0.154192
Case 5, Full house, is 0.038595
Case 6, Four of a kind, is 0.019316
Case 7, Five of a kind, is 0.000776
However my code gives the following output:
Case 1, None alike is 0.093099
Case 2, One pair is 0.384768
Case 3, Two pair is 0.076921
Case 4, Three of a kind is 0.15485
Case 5, Full House is 0.270349
Case 6, Four of a kind is 0.019281
Case 7, Five of a kind is7.33E-4
I don't understand why my programs percentages are off for one pair, two pairs, and full house. I have gone through and tested my logic but it is sound from what I have seen. Originally, my one pair was correct but my two pair was 0.0. Below is my original logic which causes the two pair to be 0 and my pair to be correct.
I, however, changed it to the current logic to get the current output. I would appreciate another set of eyes to take a look and let me know if they could catch something. Below is my code:
Change 1 :
if (hand < 6) {
int counter3 = 0;
int counter2 = 0;
for (int j = 0; j < length; j++) {
if (counts[j] == 3) {
counter3++;
}
if (counts [j] == 2) {
counter2++;
}
}
if (counter3 == 1 && counter2 == 1) {
hand = 5;
}
}
Change 2:
if (hand < 4) {
int newcounter = 0;
for (int j = 0; j < length; j++) {
if (counts[j] == 2) {
newcounter++;
}
}
if (newcounter==2) {
hand = 3;
}
if (newcounter == 1) { hand = 2; }
}
Change 3 :
Please remove if( hand < 3) part of code.
Updated my answer. In your code the counter variable (when you're trying to check "full house") was becoming 2 due to two pairs (ex : counts = 020200) not due to full house (ex: counts = 300200). Hence, it wasn't counting the two pairs in the following code where it was supposed to because hand was already becoming 5, so it didn't go inside any other if parts below although it was supposed to go inside if(hand<3). Hope it will fix the issue.
See comment in code
if (hand < 4) {
int newcounter = 0;
boolean firstp = false;
boolean secondp = false;
for (int j = 0; j < length; j++) {
firstp = false;
secondp = false;
if (counts[j] == 2) {
firstp = true; <---- THIS
}
if (counts[j] == 2) {
secondp = true; <---- AND THIS will always hit together as j never changes from the first if to second if
// break;
}
}
if (firstp && secondp) {
hand = 3; <---- firstp always equal to secondp, I would be surprised to see hand ever = 2
}
}
I modified your code. The original logic is a little bit messy. I made some slight improvement but hopefully better. Not perfect though.
import java.util.*;
public class PokerDice {
public static void main(String[] args) {
double none = 0;
double pair = 0;
double twop = 0;
double threep = 0;
double full = 0;
double fourp = 0;
double fivep = 0;
for (int i = 0; i<=1000000; i++) {
int [] rolls = new int[5];
for (int j = 0; j < 5; j++) {
rolls[j] = (int)(1 + (Math.random()*(6)));
}
int[] counts = Counts(rolls);
boolean has_two = false;
boolean has_three = false;
none++;
for (int j = 0; j < counts.length; j++) {
if (counts[j] == 4) {
fourp++;
none--;
break;
}
if (counts[j] == 5) {
fivep++;
none--;
break;
}
if (counts[j] == 3) {
has_three = true;
if (has_two) {
full++;
pair--;
break;
} else {
none--;
threep++;
}
}
if (counts[j] == 2) {
if (has_two) {
twop++;
pair--;
break;
}
else if (has_three) {
full++;
threep--;
break;
} else {
has_two = true;
pair++;
none--;
}
}
}
}
fivep/=1000000;
fourp/=1000000;
full/=1000000;
threep/=1000000;
twop/=1000000;
pair/=1000000;
none/=1000000;
System.out.println("Poker Dice Probability Calculator");
System.out.println("Running 1,000,000 trials");
System.out.println();
System.out.println("Case 1, None alike is "+none);
System.out.println("Case 2, One pair is "+pair);
System.out.println("Case 3, Two pair is "+twop);
System.out.println("Case 4, Three of a kind is "+threep);
System.out.println("Case 5, Full House is "+full);
System.out.println("Case 6, Four of a kind is "+fourp);
System.out.println("Case 7, Five of a kind is"+fivep);
}
public static int[] Counts (int [] rolled) {
int one = 0;
int two = 0;
int three = 0;
int four = 0;
int five = 0;
int six = 0;
int len = rolled.length;
int [] rolltimes = new int[6];
for (int i = 0; i<len; i++) {
if (rolled [i] == 1) {
one++;
}
else if (rolled [i] == 2) {
two++;
}
else if (rolled [i] == 3) {
three++;
}
else if (rolled [i] == 4) {
four++;
}
else if (rolled [i] == 5) {
five++;
}
else if (rolled [i] == 6) {
six++;
}
}
rolltimes[0] = one;
rolltimes[1] = two;
rolltimes[2] = three;
rolltimes[3] = four;
rolltimes[4] = five;
rolltimes[5] = six;
return rolltimes;
}
}

Code seems to be stuck in a potential loop

I am writing an answer to a CCC question in java, but every time I input something it just takes infinite inputs. Can anyone help me stop this?
Your task is to write a program that verifies the validity of a well plan by verifying that the borehole will not intersect itself. A two-dimensional well plan is used to represent a vertical cross-section of the borehole, and this well plan includes some drilling that has occurred starting at (0, −1) and moving to (−1, −5). You will encode in your program the current well plan shown in the figure below:
Input Format:
The input consists of a sequence of drilling command pairs. A drilling command pair begins with one of four direction indicators (d for down, u for up, l for left, and r for right) followed by a positive length. There is an additional drilling command indicated by q (quit) followed by an integer, which indicates the program should stop the execution. You can assume that the input is such that the drill point will not:
rise above the ground, nor
be more than 200 units below ground, nor
be more than 200 units to the left of the original starting point, nor
be more than 200 units to the right of the original starting point.
Output Format:
The program should continue to monitor drilling assuming that the well shown in the figure has already been made. As we can see (−1, −5) is the starting position for your program. After each command, the program must output one line with the coordinates of the new position of the drill, and one of the two comments safe, if there has been no intersection with a previous position or DANGER if there has been an intersection with a previous borehole location. After detecting and reporting a self-intersection, your program must stop.
My code is:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<Integer> holeX = new ArrayList<>();
ArrayList<Integer> holeY = new ArrayList<>();
String direction;
boolean danger = false;
holeX.add(0);
holeX.add(0);
for (int i = 0; i < 4; i++) {
holeX.add(i);
}
holeX.add(3);
holeX.add(3);
holeX.add(4);
holeX.add(5);
holeX.add(5);
holeX.add(5);
holeX.add(6);
for (int i = -3; i > -8; i--) {
holeX.add(7);
}
for (int i = 6; i > -2; i--) {
holeX.add(i);
}
holeX.add(-1);
holeX.add(-1);
holeY.add(-1);
holeY.add(-2);
for (int i = 0; i < 4; i++) {
holeY.add(-3);
}
holeY.add(-4);
holeY.add(-5);
holeY.add(-5);
holeY.add(-5);
holeY.add(-4);
holeY.add(-3);
holeY.add(-3);
for (int i = -3; i > -8; i--) {
holeY.add(i);
}
for (int i = 6; i > -2; i--) {
holeY.add(-7);
}
holeY.add(-6);
holeY.add(-5);
do {
direction = sc.next();
int steps = sc.nextInt();
switch (direction) {
case "d":
for (int i = holeY.get(holeY.size() - 1); i > holeY.get(holeY.size() - 1) - steps; i--) {
holeY.add(i);
for (int j = 0; j < holeY.size() - 2; j++) {
if (Objects.equals(holeY.get(holeY.size() - 1), holeY.get(j)) && Objects.equals(holeX.get(holeX.size() - 1), holeX.get(j))) {
danger = true;
}
}
}
case "u":
for (int i = holeY.get(holeY.size() - 1); i < holeY.get(holeY.size() - 1) + steps; i++) {
holeY.add(i);
for (int j = 0; j < holeY.size() - 2; j++) {
if (Objects.equals(holeY.get(holeY.size() - 1), holeY.get(j)) && Objects.equals(holeX.get(holeX.size() - 1), holeX.get(j))) {
danger = true;
}
}
}
break;
case "l":
for (int i = holeX.get(holeX.size() - 1); i > holeX.get(holeX.size() - 1) - steps; i--) {
holeX.add(i);
for (int j = 0; j < holeX.size() - 2; j++) {
if (Objects.equals(holeX.get(holeX.size() - 1), holeX.get(j)) && i == holeY.get(j)) {
danger = true;
}
}
}
break;
case "r":
for (int i = holeX.get(holeX.size() - 1); i < holeX.get(holeX.size() - 1) + steps; i++) {
holeX.add(i);
for (int j = 0; j < holeX.size() - 2; j++) {
if (Objects.equals(holeX.get(holeX.size() - 1), holeX.get(j)) && i == holeY.get(j)) {
danger = true;
}
}
}
break;
default:
break;
}
if (danger == false && !"q".equals(direction)) {
System.out.println(holeX.get(holeX.size() - 1) + " " + holeY.get(holeY.size() - 1) + "safe");
System.out.print(" safe");
} else {
System.out.println(holeX.get(holeX.size() - 1) + " " + holeY.get(holeY.size() - 1) + " DANGER");
}
} while (!"q".equals(direction) && danger == false);
}
holeX and holeY are the coordinates of the drilled area.
Input:
l 2
d 2
r 1
q 0
Output:
-3 -5 safe
-3 -7 safe
-2 -7 safe
Well yes, you have an infinite loop. Let's take case "l" for example.
I used l and then 2.
for (int i = holeX.get(holeX.size() - 1); i > holeX.get(holeX.size() - 1) - steps; i--) {
holeX.add(i)...
You add something to the list and the condition gets re-evaluated, which leads to an infinite loop.
I don't know if it is what you want to do, but what helps is to extract the condition first into a variable, then the infinite loop stops.

program running with showing progress bar in netbean but result does not come [closed]

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
I am defining an array to be a 121 array if all its elements are either 1 or 2 and it begins with one or more 1s followed by one or more 2s and end with same number of 1s that it begins with.
However i am not getting result while I was running my program.If program was ok I must get result 1 for given array {1,1,2,2,2,1,1}.
please help me.
public class OneTwoOne {
public static void main(String[] args) {
System.out.println(OneTwoOne.is121Array(new int[]{1, 1, 2, 2, 2, 1, 1}));
}
public static int is121Array(int[] a) {
int i, t1 = 0, t2 = 0, te = 0, tb = 0, tc = 0;
for (i = 0; i < a.length; i++) {//checking 1's and 2's in an array
if (a[i] == 1) {
t1 = 1;
}
if (a[i] == 2) {
t2 = 2;
}
}
for (i = 0; i < a.length; i++) {//counting number of 1's at begining of array
while (a[i] == 1) {
tb++;
}
break;
}
for (i = a.length; i >= 0; i--) {//counting number of 1's at end of array
while (a[i] == 1) {
te++;
}
break;
}
for (i = 0; i < a.length; i++) {//counting total number of 1's in an array
if (a[i] == 1) {
tc++;
}
}
if (t1 > 0 && t2 > 0 && t1 == t2 && te + tb == tc) {
//1's and 2's must be greater thna 0 and begining 1's and end 1's must be equal
//their sum is equal to total 1's in an array
return 1;
} else {
return 0;
}
}
}
You are using while loop instead of "if" clause, also the for loop limit is also unnecessarily long enough which is causing wrong result. I have made some changes in your method:
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
//StackOverflow question.
//http://stackoverflow.com/questions/32045039/array-elements-beginning-and-ending-with-1s-by-equal-number-at-both-end-and-oth/32045312#32045312
/* Name of the class has to be "Main" only if the class is public. */
class OneTwoOne {
static int i, t1 = 0, t2 = 0, te = 0, tb = 0, tc = 0;
public static void main(String[] args) {
int a [] = new int[]{1, 1, 2, 2, 2, 1, 1};
int retunValue = OneTwoOne.is121Array(a);
System.out.println("Number of 1s in starting ::"+te +"\n Number of 1s in the end ::"+ tb +"");
System.out.println("Return value :: "+retunValue );
}
public static int is121Array(int[] a) {
for (i = 0; i < a.length; i++) {//checking 1's and 2's in an array
if (a[i] == 1) {
t1 = 1;
}
if (a[i] == 2) {
t2 = 2;
}
}
int length = a.length;
for (i = 0; i < length/2; i++) {//counting number of 1's at begining of array
if (a[i] == 1) {
tb++;
}
}
for (i = a.length-1; i >= length/2; i--) {//counting number of 1's at end of array
if (a[i] == 1) {
te++;
}
}
if (te == tb)
return 1;
else
return 0;
}
}
You may run this program here. You may access the complete code here.

Categories

Resources