How can I correctly implement probability in Java? - java

I seem to have a problem I don't know why its happening its starting to look like witchcraft. This is the way I tried to implement probability:
int odd = (int)(100.0 * Math.random()); //Number between 1 and 100
if(odd<=50){ //50% chance
System.out.println("Lucky");
}
However, when I place it like this odd is ALWAYS inferior to 50, if I change the "<" to a ">" it ALWAYS generates number bigger than 50, which makes as the if statement happens every time.

I think you just had bad luck or whatever, so you got 10 or 100 times depending on how often you tested it, a larger or smaller number. Because your code works, I'm sure of it.

It is running well for me, and I do not find something wrong in your code. It may just generated many random numbers in a row that satisfied the statement.

I don't understand which problem did you have. I tried this code:
int b = 0;
for(int i = 0; i <100000;i++){
int odd = (int) (100.0 * Math.random()); //Number between 1 and 100
if (odd < 50) { //50% chance
System.out.println("Lucky");
b++;
} else {
System.out.println("Unlucky");
}
}
System.out.println("Lucky tries : " + b);
System.out.println("Unlucky tries : " + (100000 - b));
}
And it gave me the following result
Lucky tries : 50060
Unlucky tries : 49940

Related

Euclid's algorithm shows wrong conclusion

Homework of mine is to create and Euclid's algorithm in java. The task binds me to use both while-loop and if statement. Futhermore - if statement has to be placed inside while-loop.
During this task i faced already infinity-loop problem, somehow manage to get pass it. Now my Euclid's algorithm is giving multiple answers (instead of one) and futhermore they are wrong...
I have searched a couple of topics over here, but none of answers shown in there gave me an answer. I tried to rewrite whole code, and also diffrent conditions for while-loop and if statement.
import java.lang.*;
class EuklidesAlgorithm {
public static void main (String[] args) throws java.lang.Exception{
int a = 25648;
int b = 15468;
while (a % b != 0 ){
int modulo = a % b;
if (modulo == 0){
break;
}else {
modulo = a % b;
System.out.println(" Checking for GCD");
a = b;
b = modulo;
}
System.out.println(" Number " + b + " is GDC of numbers(" + a + "," + b + ").");
}
}
}
I would like it to give a single answer what is GCD for a and b.
First of all the condition :
modulo==0
will alaways be false inside the loop...
and you dont have to change variable prices inside the loop and you also don't have to print answers in every loop so...
the if statement is probably goind to be used to check if any of those two numbers is 0 or if the result is 0 but you can do both

What would cause a for loop to decrement when it's supposed to increment?

I wrote a method to calculate how long ago a father was twice as old as his son and in how many years from now this would be true. Unexpectedly, it returns "-2 years ago" for an 8-year-old father and a 3-year-old son. Equally unexpectedly, it returns "-1 years from now" for a 3-year-old father and a 2-year-old son. I am not concerned about how to improve the code because I already know how to do this. Instead, I am puzzled about why the for loop counter appears to be decrementing when it's supposed to increment.
Here is my code.
public class TwiceAsOld {
public static void twiceAsOld (int currentFathersAge, int currentSonsAge) {
int yearsAgo;
int yearsFromNow;
int pastFathersAge = currentFathersAge;
int pastSonsAge = currentSonsAge;
int futureFathersAge = currentFathersAge;
int futureSonsAge = currentSonsAge;
for (yearsAgo = 0; pastFathersAge != 2 * pastSonsAge; yearsAgo++) {
pastFathersAge--;
pastSonsAge--;
}
System.out.println("The father was last twice as old as the son " + yearsAgo + " years ago.");
for (yearsFromNow = 0; futureFathersAge != 2 * futureSonsAge; yearsFromNow++) {
futureFathersAge++;
futureSonsAge++;
}
System.out.println("The father will be twice as old as the son in " + yearsFromNow + " years from now.");
}
public static void main(String[] args) {
twiceAsOld(8, 3);
twiceAsOld(3, 2);
}
}
With twiceAsOld(8, 3), the for loop's increment appears to have reversed itself to count down from 0 instead of up. With twiceAsOld(3, 2), the -1 might stand for an error indicating that the father has never been twice as old as his son and never will be. What I don't understand is what would cause a for loop to start decrementing the i value when it's supposed to increment. I was expecting the counter to increment indefinitely until the program ran out of memory.
I already know how to improve this program, but I am curious about how the counter in a for loop can decrease when it's supposed to increase. Can anybody explain this?
(UPDATE: Thanks everyone for your answers. I can't believe I forgot about integer overflow. I tried making the variables longs instead of integers, but this made the program even slower. Anyway, now I realize that the counter was incrementing all along until it overflew and landed at a negative value.)
It became negative because that is what happens in Java when an int calculation overflows.
Take a look at
https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.18.2
It says that
If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format. If overflow occurs, then the sign of the result is not the same as the sign of the mathematical sum of the two operand values.
Didn't you notice that your program runs quite slowly? :)
For the (8, 3) years ago case, your for loop keeps looping and looping, trying to find a year that the father is twice as old, but as we know, the father will only become twice as old in the future, but not in the past. The for loop doesn't know this and it will try very hard to find such a year. It tries so hard that yearsAgo is incremented past the max value of int. This causes an overflow, and the value of yearsAgo will "wrap back around" to the minimum value of int, which is a negative number. And then this negative number will get incremented many many times, until -2.
The same goes for the other case.
To fix this, you can add if statements to check if the results are negative:
public static void twiceAsOld (int currentFathersAge, int currentSonsAge) {
int yearsAgo;
int yearsFromNow;
int pastFathersAge = currentFathersAge;
int pastSonsAge = currentSonsAge;
int futureFathersAge = currentFathersAge;
int futureSonsAge = currentSonsAge;
for (yearsAgo = 0; pastFathersAge != 2 * pastSonsAge; yearsAgo++) {
pastFathersAge--;
pastSonsAge--;
}
// Here!
if (yearsAgo >= 0) {
System.out.println("The father was last twice as old as the son " + yearsAgo + " years ago.");
}
for (yearsFromNow = 0; futureFathersAge != 2 * futureSonsAge; yearsFromNow++) {
futureFathersAge++;
futureSonsAge++;
}
if (yearsFromNow >= 0) {
System.out.println("The father will be twice as old as the son in " + yearsFromNow + " years from now.");
}
}
You can also stop the loop when it reaches negative values to make your program faster:
for (yearsAgo = 0; pastFathersAge != 2 * pastSonsAge && yearsAgo >= 0; yearsAgo++) {
When I debug your code I can see that yearsAgo is incrementing without bound, causing pastFathersAge and pastSonsAge to go into negatives. This is causing negative integer overflow. This happens because your condition pastFathersAge != 2 * pastSonsAge is never met (rather, never NOT met). Not until your futureFathersAge has gone all the way through the negatives, back into positives, and finally settles on -2.
The moral of the story is to make certain that your terminating condition for your loop can always can be met. Don't use !=, use >= or <= instead.

How to get exact chance of three variables?

I am struggling to calculate the estimated chance of user to get an item. He have got 15 tries(which may vary), chance to get into group of items and then chance to get exact item. I can see two ways of doing it, but none is perfect. Please take a look:
int userTries = 15;//Variable holding number of how many tries user has to get an item
double groupChance = 17;//Chance for user to get any item from the group
double itemChance = 80;//Chance for user to get specific item from the group
double simpleChance = groupChance * itemChance * userTries / 100.0;
int correctionTries = 10000;
int totalPassed = 0;
for (int i = 0;i < correctionTries;i++)
{
for (int x = 0;x < userTries;x++)
{
//Rnd.chance is checking if input chance was rolled, if chance is 17 then this method will return true in 17 tries out of 100
if (Rnd.chance(groupChance))
if (Rnd.chance(itemChance))
{
totalPassed++;
break;
}
}
}
double iterationChance = (double) totalPassed / (double) correctionTries * 100.0;
System.out.println("simple=" + simpleChance + " iteration=" + iterationChance);
When groupChance and itemChance are low(like 1 & 1), then simpleChance gives very good results, but when chances are high(like 17 & 80) then they vary a lot from iteration result. The problem with iteration solution is that when one I increase one of the chances, result actually be lower because of bad luck in calculated chances. I could increase correctionTries to solve that issue, but chance will be different when calculating same values once again and it also would have significant impact to performance.
Do you know any way to calculate that chance with low performance impact and good estimation that stays the same after calculating it once again?
I assume that the groupChance and itemChance are probabilities (in percent) to get into the specific group and to get the specific item in the group..
If so, then the probability to get this specific Item is groupChance/100 * itemChance/100 = 0.17*0.8 = 0.136 = 13.6%
not clear either what simpleChance should be => to get the specific item at least once after 15 tries?? exactly once after 15 tries?? to get it 15 times in a row?
if you want to get it 15 times in a row, then the chance is (groupChance/100 * itemChance/100 ) ^ userTries = 0.000000000000101
if you want to get it at least once after 15 tries, then the chance is 1 - ( 1 - groupChance/100 * itemChance/100 ) ^ userTries = 0.88839

Add Two Binary Numbers Recursively, w/o Bitwise Operations; Java Homework

I think I've gotten mostly to a solution for a homework problem.
This is for a 201 CS class. Right now I just want to get the logic right. At present, it doesn't operate as intended, but it's close.
We don't want to use .toBinary, bitwise, or anything else. We also haven't been taught stringBuilder, so I'd like to avoid using it.
There's a System.out.println(); within the method which provides the correct answer if you read the console from bottom to top.
public static void main(String[] args) {
System.out.println(addBin(1100111011,1101110011));
}
public static String addBin(int num1,int num2){
String result = "";
if(num1 > 0 || num2 > 0){
int part1 = num1%10, part2 = num2%10;
int rem1 = num1/10, rem2 = num2/10;
result += Integer.toString((part1 + part2)%2);
//System.out.println(result);
int carry = (part1 + part2) /2;
addBin(rem1 + carry, rem2);
return result;
}
return result;
}
So, this example adds 1100111011 and 1101110011 with the output
0
1
1
1
0
1
0
1
0
1
1
0
when the correct answer is 11010101110.
I'm having trouble understanding how to properly "pop" the "result" part properly. Could you please help me understand this process, possibly within the context of this problem?
Thanks!
As you can see from your output, you are getting the correct result in the reverse order but you are not appending any of your older result to the ones that are being currently computed.
Inside your if condition, you are calling the addBin() function but you are not using the result that it gives anywhere. Just change that line to the following:
result = addBin(rem1 + carry, rem2)+result;
That should effective append all your results in front of the current answer so that you do not get the result in backwards direction. Hope this helps.

Questions over BigInteger?

import java.math.BigInteger;
public class ProjectEuler {
public static void main(String[] args) {
BigInteger bi = new BigInteger("600851475143");
int div = 7;
while (bi.compareTo(new BigInteger("1")) != 0) {
while (bi.mod(new BigInteger(div + "")).compareTo(new BigInteger("0")) == 0) {
bi = bi.divide(new BigInteger(div + ""));
}
div += 2;
}
System.out.println("" + div);
}
}
I was just looking over one of the basic but famous problems of "What is the largest prime factor of the number 600851475143". I found this solution different, i have a couple of questions on how this works.
The first condition checks whether the number equals 1 or not. From there i am not able to understand the rest of the code.
new BigInteger(div +""). why do we concatenate + "" here?
How is the div = 7 decided?
The author decided to "hard-code" his knowledge of the number itself to decide that the first three primes are not among the divisors
The first condition checks whether the number equals 1 or not. From there i am not able to understand the rest of the code.
The rest of the code looks like this in "regular" integers:
while (bi % div == 0) {
bi /= div;
}
div += 2;
new BigInteger(div +"") why do we concatenate + "" here
That is a short way of making an object a String. BigInteger has a parameter that takes String, so the alternative to this approach would be calling Integer.toString(div).
Note that this is not the most efficient solution: one could speed this up by observing that you could stop trying to divide when you reach the square root of the original number, because you can be sure that the next divisor will be the number itself.
How is the div = 7 decided?
Probably the author noticed that the number isn't divisible by 2 nor 3 nor 5. To know how the author did this, he/she should have known this rules: Divisibility Rules and Tests
The first condition checks whether the number equals 1 or not. From there i am not able to understand the rest of the code.
The author is making sure that the number is not BigInteger("1") since it's dividing the number and storing the results in bi in the loop iterations. Note this:
bi = bi.divide(new BigInteger(div + ""));
new BigInteger(div +""). why do we concatenate + "" here?
It uses the BigInteger(String) constructor. The author n̶a̶i̶v̶e̶l̶y̶ makes a new String by adding the int with an empty String.

Categories

Resources