I'm learning Java - came across this problem:
Write a program that rolls n dice, where the dice are all d-sided. By using simulation, report an approximate value for the probability of rolling a total of x or more, using the dice, where x, n and d are all given as inputs. For example, if n = 2, d = 6 and x = 7, the program should report 58.3% probability (approximately).
This is what I came up with
public class Main {
public double calcProbability(int n, int d, int x){
int[] sums = new int[(int)Math.pow(d, n)]; //Creates an array of max size needed
int counter = 0;
int occurrences = 0; //No. of times that the number being added to the array is greater than d
for(int i=1;i<=d;i++){
for(int j=1;j<=d;j++){
if((i+j)>=x){
occurrences++;
}
sums[counter]=(i+j);
counter++;
}
}
return (double)occurrences/Math.pow(d, n); //Returning probability
}
public static void main(String[] args) {
System.out.println(new Main().calcProbability(2, 6, 7));
}
}
It works fine for n=2 (I think), since I'm using two nested for loops. But I'm having trouble figuring out how to vary the number of for loops with n (this will allow me to add all the possible totals to the array - the rest of the code should work fine as is).
Would appreciate some guidance.
Thanks everybody, after taking into account everyone's contribution, here's the revised method:
public double calcProbability(int n, int d, int x){
Random random = new Random(); //Random numbers simulate dice rolling
int occurrences = 0; //No. of times that the number is greater than d
for(int i=0;i<100000;i++)
{
int sum = 0;
for(int j=0;j<n;j++)
{
sum+=random.nextInt(d)+1;
}
if(sum>=x) {
occurrences++;
}
}
return (double)occurrences/100000; //Will be an approximation
}
It was pointless storing those numbers then counting the number of occurrences - rather just count the occurrence when it takes place and move on.
Microsoft BASIC had a nesting limit of 8. @Davislor: The error message refers to the stack size in the compiler, which is also a program, and which is recursively processing the nested-looped construct.
Two nested for loops: O(n²) In the above nested loop example, outer loop is running n times and for every iteration of the outer loop, inner loop is running (n - i) times. So total number of nested loop iteration = (n - 1) + (n - 2) + (n - 3)…..
get(index); for (string v : focus. values) { values[index] = v; if (index < focuses. size() - 1) { // there is at least one other focus CreateCombinations(focuses, index+1, values); } else { // all values pinned down StringBuilder sb = new StringBuilder(values[0]); for (int i = 1; i < values. length; ++i) { sb.
There are no limits. Or, more precisely, there are no maximum limits on the user. There are minimum limits on the compiler, however. So you can have 127 nested loops/if/switch and 12-dimensional arrays and be sure that any compliant compiler will be able to compile you.
For the purpose of dynamic loops, the answer is as follows. However, skip to second paragraph for a more recommended way of doing this. The way to get dynamic loops is with recursion. I can elaborate more if you want, but on a high level, what you have is a parameter that specifies the nth dice and decrements, and when it reaches the 0th dice, then the recursion ends. You'll have to change quite a bit with the variables, and move them into parameters or globals so you can keep updating them with the function.
In the case of this problem, I would approach it quite differently. Create a function called Roll that takes two parameters: a range of the the dice values and the amount of dice to roll. I'll leave the specifics of the function of to you, but it involves generating random numbers a certain amount of times. Since the problem requires simulation, call this Roll function some high number of times, and then use an array to keep track of the answers that come out. At that point, do the division and percentages to get a good approximation.
Maybe you should just iterate over possible results of dice rolling in one loop.
A result is a integer array of size n
with value all in [1, d].
And your code will be:
int occurrences = 0;
int count = 0;
Result result = new Result(n, 1); // n times 1.
while(result != null)
{
if (result.Sum >= x) occurrences++;
count++;
GetNextResult(result);
}
double probability = occurrences / (double) count;
Where GetNextResult
return the next possible result or null
if the input is [d, d, ..., d]
.
Of course you have to code Result
class correctly.
Thanks everybody, after taking into account everyone's contribution, here's the revised method:
public double calcProbability(int n, int d, int x){
Random random = new Random(); //Random numbers simulate dice rolling
int occurrences = 0; //No. of times that the number is greater than d
for(int i=0;i<100000;i++)
{
int sum = 0;
for(int j=0;j<n;j++)
{
sum+=random.nextInt(d)+1;
}
if(sum>=x) {
occurrences++;
}
}
return (double)occurrences/100000; //Will be an approximation
}
It was pointless storing those numbers then counting the number of occurrences - rather just count the occurrence when it takes place and move on
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With