Most likely sum of two dices - java

I have two dices where the user can chooses the amount of faces on. I want to write a code to output the most likely outcome. For example if the user chooses 2 6-sided dices, then the outcome should be 7. But if the user chooses one 3-sided and one 4-sided dice, the output should be 4 and 5. I have seen examples where you calculate how likely each different sum is in different loops, but I am wondering if there is an easier way to go since I only care about the MOST likely sum, and not all sums.
Any advice or help would be appreciated!
Edit. Since it has not been appreciated to print all different attempts that I have done since there has been complaints about unnecessary code to read, I will link you to different examples I have tried, but then deleted since they seemed to be unnecessarily long for my problem. https://coderanch.com/t/517923/java/Dice-probability-program-nested-loops I realized that that example wasn't fitted since that required an amount of rolls that I will not determine. I then tried to simply try all different possible combinations by using a while loop but I got stuck in the middle and therefore chose not go with it.
Now I only have:
Scanner scanner = new Scanner (System.in);
while (scanner.hasNextInt()) {
int x,y;
x=scanner.nextInt();
y=scanner.nextInt();
if (x==y) {
int z = x+1;
System.out.println(z)
} else {
int z= ((x+y)/2)+1;
System.out.println(z);
}
}
Problem: if there are two different numbers of faces, the variable z only prints out ONE of the sum that are equally as likely to occur.

Let a and b be the number of sides and assume a is less than (or equal to) b. Then all sums between a+1 and b+1 and have the same likelihood (of a/(a+b)) and that likelihood is also maximal. How you want to return this in your code is up to you.

Related

How to sort Collection in this specific way?

I had a final exam of OOP 1 (we use Java) at university back in december, and I did not pass. The thing was that I had to sort something in a kinda-specific way, and I can't figure out how to properly implement this. I will translate just a part of the exercise (I will do it with help of Google Translate):
"... John loves natural numbers, and he likes mostly the even numbers other than the odd numbers. Inside each subset, he prefers the smallest ones."
HERE is the original exercise (in spanish)
OK, so, I have to do this inside a class called Natural, and I have to be able to sort it in that custom way (described above). This is which I am not able to do. I know (a teacher told me after the exam) that I had to implement Comparable<T>.
(I know this part) After that, I had to instantiate a LinkedList<Natural>, read numbers from a file, sort them and put them (having being sorted) into another file.
Sorry if this is confusing, my English is really bad.
This is what I have in my class Natural:
public class Natural implements Comparable<Natural> {
public Integer numNatural;
public int compareTo(Natural otroNatural) {
Integer numNatural2 = ((Natural) otroNatural).numNatural;
if (this.numNatural > numNatural2) return 1;
else if (this.numNatural < numNatural2) return -1;
else return 0;
}
How can I make my program to understand that I need to put first the even numbers, and inside the even numbers, the smallest ones? After that, the smallest odd numbers should be sorted also.
You have several cases, and it would help to consider these individually.
even number vs even number
even number vs odd number
odd number vs even number
odd number vs odd number
For the second and third case you can already return 1/-1 as you know the answer without further logic. For the other two cases you need to compare as you've already shown in your answer.

Coin toss using random numbers does not appear exactly random

I wanted a random number generator to simulate a coin toss and here's what i did
public class CoinToss
{
public static void main(String args[])
{
int num=(int)(1000*Math.random());
if(num<500)
System.out.println("H");
else
System.out.println("T");
}
}
The results were discouraging as i got 16 Heads and 4 tails in 20 runs.
That does not appear to be random. Its possible but i want a general opinion if the program is correct ? Am i missing something mathematically ?
Modified your code a little and it seems to be random enough.
code:
int h = 0;
int t = 0;
for (int i = 0; i < 1000; i++) {
int num = (int) (1000 * Math.random());
if (num < 500) {
h++;
} else {
t++;
}
}
System.out.println("T:" + t);
System.out.println("H:" + h);
output:
T:506
H:494
I guess this is the thing with randomness ^^
20 runs is not a big enough sample size to assess how random it is. Think of it this way: if you did 4 runs and got 4 heads, you'd think, "Wow, that's not random at all." But in fact if you took 4 coins, and flipped them 16 times, you'd expect to get all 4 heads at least once. So if you do a small number of runs, and you get results that aren't equally divided between heads and tails, that doesn't mean it's not random.
Or look at it this way: if you wrote some code that just printed "Heads" then "Tails" then "Heads" and so on, you'd get exactly half heads and half tails. But that's not random at all! It's just a repeating pattern.
So the moral of the story is not to be surprised when random results look uneven over short runs. Try re-writing your code so that it counts how many heads and how many tails, and let it flip about a million or so, and see if you don't get about 500,000 each. It should be a little more or a little less, because random doesn't give you exact, but it should be closer.
your code seems to be correct although you could implement it easier:
Random r = new Random();
int num = r.nextInt(2);
if (num == 0)
System.out.println("H");
else
System.out.println("T");
Random#nextInt(int i) returns a random Integer between 0 and i-1
A pseudorandom number generator (PRNG), also known as a deterministic random bit generator (DRBG), is an algorithm for generating a sequence of numbers whose properties approximate the properties of sequences of random numbers.
The PRNG-generated sequence is not truly random, because it is completely determined by a relatively small set of initial values, called the PRNG's seed
Although sequences that are closer to truly random can be generated
Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin. John von Neumann
You need way more inputs in order to get equal number of each. For such small number of outputs sometimes you will get them close to each other in terms of numbers, sometimes one side will "show" way more then other. Actually, probability of having 4 tails and 16 heads is 0.462% which is somewhat "realistic" to happen... Try to play with it more with higher number of runs and see how it behaves.
And btw think about this input:
6 6 6 6 6 6 6 6 6 6
Doesn't seems random, right? But it exist in decimal of number π at some point, so its a part of random series. Its just a question of series size, so you must think in that way when you work with random numbers. Think more about random generator rather than about results. You are using correct function since its based on System.nanoTime(), so generator is right, but your result is to small.

Getting exponents in a method without using Math.pow()

This was the problem I was given:
Create method lastDigit that is passed two positive integers. The first integer is the base and the second integer is the exponent. lastDigit will return the last digit of base^exponent. You need to think before you write your code. Hint: You do not need to actually find the product of base^exponent.
Then I need to use the method to find answer the questions below:
1) What is the last digit of 3^400?
2) What is the last digit of (3^0)(3^1)(3^2)(3^3)…(3^10)?
3) What is the last digit of the product of (3^0)(3^1)(3^2)…..(3^400)?
Here's the code that I wrote:
public static int lastDigit(int m, int n){
int p=1;
for(int i=1; i<=n; i++)
p=p*m;
return p%10;
}
However when I was trying to find the answers to the questions, I keep getting -1 for both the first and third questions, and 1 for the second question. Is there something wrong with the code, or how can I get the right answer?
You or a program you wrote may be suffering from Integer Overflow.
This is caused by chronic limitation of the int type.
Symptoms include
Negative integers that are really supposed to be positive
Small numbers that are supposed to be big
This condition can be controlled by ensuring that your int values don't exceed 2 billion.
If symptoms persist, see a debugger, or print out intermediate values.
*side effects may include frustration, throwing your computer out of a window, and/or deleting important system files.
But in all reality, let's say that you have a base of seven.
7=7
7*7=49
49*7=343
The last digit is 3.
However, if you, only take the last digit in between operations,
7*7 =49 -> 9
9*7 =63
The last digit is still three.
Doing this keeps the number well below the int limit.
This is actually what the p=(p*m)%10; solution is:
p= (p*m) %10
multiply the previous digit by the exponent take the last digit
The int variable is overflowing. Try changing p=p*m to p=(p*m)%10.

Creating java array to convert numeric score to alphabetic grade

novice java programmer, new to arrays, working on an assignment of the following prompt:
Write a program that will plot the grade distribution of scores of a test. The scores are inputted one at a time and the loop will break when a score of 0 (zero) is entered. The output will print a * for each score in the letter grade and will place the letter grades on the horizontal axis below the graph.
My main issue is in the creation of an array that enables me to sum the number of scores in each grade (A, B, C...). I am prohibited from the use of if or switch statements in this conversion. I'm wondering where to start in the creation of this array. Thanks!
Does it have to be an array? If not, a Map is a good choice for this type of scenario. The keys of the map are the various grades (A, B, C, etc) and the value of each key is an integer (or long) to hold the number of grades for that key. So, the basic logic is to get the counter from the map for the grade (i.e. key), increment it and put it back into the map.
If you don't mind using external libraries, then Guava's Multiset is an even better fit.
EDIT: OK so you need to use an array, but one challenge (if I read your post correctly) is that you can't use if or switch statements (presumably to access the array). One possible way around this is to assign 'A' to index 0, 'B' to index 1, etc. Then you can use the following notation for array indexing:
char gradeAsChar = ...; //I'll leave this to you to get the grade as an (uppercase) char
gradesArray[gradeAsChar - 'A'] = gradesArray[gradeAsChar - 'A'] + 1;
'A' - 'A' is 0, 'B' - 'A' is 1, etc. The above, of course, is ripe for index out of bounds issues if the character is unexpected so you'll need some error handling there.
Of course, if you don't care about memory efficiency (which you always should while coding!), you can make a new array like so:
int[] grades = new int[101];
Then whenever a user enters an input, you can do something like:
int grade = input.nextInt();
grades[grade] = grades[grade] + 1;
You can figure out the number of grades that equal A by running something like:
int A = 0;
for (int i = 91; i < 101; i++){
A += grades[i];
}
That's what I thought of when you said you weren't allowed to use if or switch statements. Let me know if it helped. Again, terribly inefficient, but at least you keep track of all the scores you have. That's a plus.
This should be a rough runtime of O(n), but could be better I think.
Good luck!
EDIT: You can do a more efficient version of the method above by using the concept of integer division. What is integer division you may ask, it's when you divide two integers, say 10/3 and the answer might be 3.333 but java discards the fractional parts so that the answer is 3.
Therefore, if you divide by 10, you can use the result to get which scores are A and so forth. For example: 92/10 = 9, 97/10 = 9, 83/10 = 8, etc. The caveat is that the score is from 91-100 for A so you have to subtract 1 before applying this concept.
This should reduce the array from 101 elements to 10 since you are only keeping track of the number in the tens digit, which is more important anyways. You may be able to further optimize this but again, this isn't my homework so I don't want to spend too much time on it. I thought of this when I woke up :).
Hope this gave you some food for thought!

Finding a prime number at least a 100 digits long that contains 273042282802155991

I am new to Java and one of my class assignments is to find a prime number at least 100 digits long that contains the numbers 273042282802155991.
I have this so far but when I compile it and run it it seems to be in a continuous loop.
I'm not sure if I've done something wrong.
public static void main(String[] args) {
BigInteger y = BigInteger.valueOf(304877713615599127L);
System.out.println(RandomPrime(y));
}
public static BigInteger RandomPrime(BigInteger x)
{
BigInteger i;
for (i = BigInteger.valueOf(2); i.compareTo(x)<0; i.add(i)) {
if ((x.remainder(i).equals(BigInteger.ZERO))) {
x.divide(i).equals(x);
i.subtract(i);
}
}
return i;
}
Since this is homework ...
There is a method on BigInteger that tests for primality. This is much much faster than attempting to factorize a number. (If you take an approach that involves attempting to factorize 100 digit numbers you will fail. Factorization is believed to be an NP-complete problem. Certainly, there is no known polynomial time solution.)
The question is asking for a prime number that contains a given sequence of digits when it is represented as a sequence of decimal digits.
The approach of generating "random" primes and then testing if they contain those digits is infeasible. (Some simple high-school maths tells you that the probability that a randomly generated 100 digit number contains a given 18 digit sequence is ... 82 / 1018. And you haven't tested for primality yet ...
But there's another way to do it ... think about it!
Only start writing code once you've figured out in your head how your algorithm will work, and done the mental estimates to confirm that it will give an answer in a reasonable length of time.
When I say infeasible, I mean infeasible for you. Given a large enough number of computers, enough time and some high-powered mathematics, it may be possible to do some of these things. Thus, technically they may be computationally feasible. But they are not feasible as a homework exercise. I'm sure that the point of this exercise is to get you to think about how to do this the smart way ...
One tip is that these statements do nothing:
x.divide(i).equals(x);
i.subtract(i);
Same with part of your for loop:
i.add(i)
They don't modify the instances themselves, but return new values - values that you're failing to check and do anything with. BigIntegers are "immutable". They can't be changed - but they can be operated upon and return new values.
If you actually wanted to do something like this, you would have to do:
i = i.add(i);
Also, why would you subtract i from i? Wouldn't you always expect this to be 0?
You need to implement/use miller-rabin algorithm
Handbook of Applied Cryptography
chapter 4.24
http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf

Categories