Probability of getting a particular sum from n m-sided dice c# - c#

I am trying to generate a probability of getting a specific number from n dice, with no guarantee of them having the same number of sides. (eg, 1d6 + 2d10)
I know there is a really expensive way of doing it (With recursion), but if there is a mathematical way of determining the chance of an event happening, that would be way better.

One way to do this:
Create an output array count with length sum(sides all dice)+1, i.e. so that the max that can possibly be rolled works as an index.
This represents the number of ways that the index can be rolled. Initialise this with [0] = 1.
For each dice of N sides, enumerate the results of each possible rolled value.
Copy the existing count array into prev, say, and create a new empty count array
for roll = 1 to N, for total = 0 to count.length-1-roll, count[total+roll]+=prev[total]
Now the probability of rolling value = count[value] / sum(count)
Notes:
This isn't, as you feared, either really expensive or needs recursion. This will be O(N^2) where N as the total faces on all dice.
This will compute the probability of all outputs not just the one output that you're interested in, which may be an issue if the total faces is extremely large and the value you're interested in small. You could cap the count array at length (value you're interested in) + 1, if necessary, and compute the total number of rolls as the product of each die face as you process it rather than from sum(count) as I've suggested above.

#Rup already gave one standard solution, the bottom up dynamic programming method.
The top down approach is to write your recursive function..and then memoize it. That is when your function is called you first check whether you have seen this before (ie you look into a dictionary to see if you have a "memo" to yourself about the answer), and if you haven't you calculate the answer and save it. Then you return the memoized answer.
The usual tradeoffs apply:
Top down is easier to figure out and write.
Bottom up lets you see that you don't need to store 2 dice answers when you have the 3 dice ones, and therefore reduces working memory requirements.
Therefore it is good to know both approaches, but I always reach for a top down approach first.

Here I generated from 2 dice rolling
1 Randon() will be generated from n faces
2 here n times is rolled on
3 sum is displayed for n rolled
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dicerolling
{
class Program
{
static void Main(string[] args)
{
Random x = new Random();
int throw_times = 1;
int sum = 0;
int[] dice = new int[2];
dice[0] = x.Next(1, 7);
dice[1] = x.Next(1, 7);
Console.WriteLine("enter the no of rollings :");
var n = int.Parse(Console.ReadLine());
for (int i = 1; i <= n; i++)
{
dice[0] = x.Next(1, 7);
dice[1] = x.Next(1, 7);
int total_var = dice[0] + dice[1];
sum += dice[0] + dice[1] ;//total in array
Console.Write("Throw " + throw_times + ": " + dice[0] + " d " + dice[1] + " = ");
Console.WriteLine(total_var);
throw_times++;
Array.Sort(dice);
for (int a = dice.Length - 1; a >= 0; a--)
{
int s = dice[a];
Console.WriteLine("#" + s);
}
}
Console.WriteLine("Total sum: " + sum);//only returns sum of last 2 rolls
Console.ReadLine();
}
}
}

Related

Creating 1000 arrays and sorting them using the bubble and selection sort (C#) [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am new to programming. C# is my first programming language.
I have an assignment where I have to create and test out a bubble sort algorithm and a selection sort algorithm using arrays. I think I understand those now.
The next part of the assignment I am having some trouble on.
I have to write a program that will ask the user for a number (n) and create 1000 arrays of n size.
So if the user enters 5 for the number, my program has to create and sort 1000 arrays that are of length 5.
I have to use the bubble sort and the selection sort methods I created.
After I do that, I have to initiate a variable called running_time to 0. I have to create a for loop that iterates 1000 times and in the body of the loop i have to create an array of n random integers.
Then I have to get the time and set this to the start time. My professor said to notice that the sort is started after each array is built, so I should time the sort process only.
Then I have to get the time and set it to end time. I have to subtract the start time from end time and add the result to the total time.
Once the program has run, note
1. the number of items sorted
2. the average running time for each array (total time/1000)
Then I have to repeat the process using 500, 2500, and 5000 as the size of the array.
This is my code for creating one array with n number of spaces and filled with random integers.
//Asks the user for number
Console.WriteLine("Enter a number: ");
n = Convert.ToInt32(Console.ReadLine());
//Creates an array of the length of the user entered number
int[] randArray = new int[n];
//Brings in the random class so we can use it.
Random r = new Random();
Console.WriteLine("This is the array: ");
//For loop that will put in a random number for each spot in the array.
for (int i = 0; i < randArray.Length; i++) {
randArray[i] = r.Next(n);
Console.Write(randArray[i] + " ");
}
Console.WriteLine();
THIS IS MY CODE FOR THE BUBBLE SORT ALGORITHM:
//Now performing bubble sort algorithm:
for (int j = 0; j <= randArray.Length - 2; j++) {
for (int x = 0; x <= randArray.Length - 2; x++) {
if (randArray[x] > randArray[x + 1]) {
temp = randArray[x + 1];
randArray[x + 1] = randArray[x];
randArray[x] = temp;
}
}
}
//For each loop that will print out the sorted array
foreach (int array in randArray) {
Console.Write(array + " ");
}
Console.WriteLine();
THIS IS MY CODE FOR THE SELECTION SORT ALGORITHM:
//Now performing selection sort algorithm
for (int a = 0; a < randArray1.Length - 1; a++) {
minkey = a;
for (int b = a + 1; b < randArray1.Length; b++) {
if (randArray1[b] < randArray1[minkey]) {
minkey = b;
}
}
tempSS = randArray1[minkey];
randArray1[minkey] = randArray1[a];
randArray1[a] = tempSS;
}
//For loop that will print the array after it is sorted.
Console.WriteLine("This is the array after the selection sort algorithm.");
for (int c = 0; c < randArray1.Length; c++) {
Console.Write(randArray1[c] + " ");
}
Console.WriteLine();
This is very overwhelming as I am new to this and I am still learning this language.
Can someone guide me on the beginning on how to create 1000 different arrays filled with random numbers and then the rest. I would appreciate it greatly. Thank you.
So you have a several questions that has overwhelmed you.
Let's look at each one
Take user input
Console.WriteLine("Enter a length");
while (!int.TryParse(Console.ReadLine(), out var length))
Console.WriteLine("omg! you had one job");
Calling a method with an out argument
Starting with C# 7.0, you can declare the out variable in the argument
list of the method call, rather than in a separate variable
declaration. This produces more compact, readable code, and also
prevents you from inadvertently assigning a value to the variable
before the method call. The following example is like the previous
example, except that it defines the number variable in the call to the
Int32.TryParse method.
Fill Array
private static Random _rand = new Random();
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
...
public static string RandomString(int length)
{
var result = Enumerable.Range(0, length)
.Select(s => chars[_rand.Next(length)])
.ToArray();
return new string(result);
}
Create array of random chars
var arr = Enumerable.Range(0, size)
.Select(i => RandomString(length)).ToArray();
How to time something
var sw = Stopwatch.StartNew();
// something to time
var milliseconds = sw.ElapsedMilliseconds
Now map it all together, I'll leave these details up to you
Additional Resources
Enumerable.Range(Int32, Int32) Method
Generates a sequence of integral numbers within a specified range.
Enumerable.Select Method
Projects each element of a sequence into a new form.
Stopwatch Class
Provides a set of methods and properties that you can use to
accurately measure elapsed time.
Random Class
Represents a pseudo-random number generator, which is a device that
produces a sequence of numbers that meet certain statistical
requirements for randomness.

c# Normalized power for Polar cycle

List<int> NPower = new List<int>();
List<double> list = new List<double>();
try
{
for (int i = 1; i < dataGridView1.Rows.Count; i++)
{
for (int n = 0; n < i + 30; n++)
{
NPower.Add(Convert.ToInt32(dataGridView1.Rows[i + n].Cells[6].Value));
}
}
average = NPower.Average();
total = Math.Pow(average, 4);
NPower.Clear();
}
catch (Exception)
{
average = NPower.Average();
NP = Convert.ToInt32(Math.Pow(average, (1.0 / 3.0)));
label19.Text = "Normalised Power: " + NP.ToString();
NPower.Clear();
}
Hi so i'm trying to calculate the normalized power for a cycling polar cycle. I know that for the normalized power you need to:
1) starting at the 30 s mark, calculate a rolling 30 s average (of the preceeding time points, obviously).
2) raise all the values obtained in step #1 to the 4th power.
3) take the average of all of the values obtained in step #2.
4) take the 4th root of the value obtained in step #3.
I think i have done that but the normalized power comes up with 16 which isnt correct. Could anyone look at my code to see if they could figure out a solution. Thankyou, sorry for my code i'm still quite new to this so my code might be in the incorrect format.
I'm not sure that I understand your requirements or code completely, but a few things I noticed:
Since you're supposed to start taking the rolling average after 30 seconds, shouldn't i be initialized to 30 instead of 1?
Since it's a rolling average, shouldn't n be initialized to the value of i instead of 0?
Why is the final result calculated inside a catch block?
Shouldn't it be Math.Pow(average, (1.0 / 4.0)) since you want the fourth root, not the third?

learning C#, need help understanding this code

I am learning C# and I came to this "for" function and something really bothers me about it:
int[] arrayNumbers = new int[numberAmmount];
// take "numberAmmount" as 5 so numberAmmount = 5;
for (int i = 0; i < numberAmmount; i++)
{
Console.Write("{0} Number: ", i + 1);
numberAmmount[i] = int.Parse(Console.ReadLine());
}
Isn't "i++" in for function the same i as in the Console.Write "i + 1"
Shouldn't i after the first cycle be 2?
and after the second cycle be 4 because of the i + 1 in console.write???
Basically I am trying to get in a number from the user which will be the amount of numberAmmount and by this for function i give every numberAmmount[x] a value and then have my program decide the highest and the lowest number but I don't understand why the i + 1 doesn't add an extra 1
edit: got it thanks
The syntax i + 1 does not have an assignment operator. That code is printing the value of i plus a constant. So when your loop is looping from 0...n Console.write is printing the counting value of each loop 1...n+1.

Why is there a strong correlation between random number and correct guesses?

In trying to test whether knowing the history of a random number could help predict the future results, I found a strong, unexpected correlation between the average of the number generated, and the number of correct guesses.
The test was supposed to simulate flipping a coin (heads = 0, tails = 1) and if previous attempts were biased towards heads then guess tails and vice versa.
Why is the sum of the generated numbers always nearly equal to the number of correct guesses in the following LinqPad program?
void Main()
{
var rnd = new Random();
var attempts = 10000000;
var correctGuesses = 0;
long sum = 0;
decimal avg = 0.5m;
for (int i = 0; i < attempts; i++)
{
var guess = avg < 0.5m ? 1 : 0;
var result = rnd.Next(0, 2);
if (guess == result)
{
correctGuesses += 1;
}
sum += result;
avg = (decimal)sum/(decimal)attempts;
}
attempts.Dump("Attempts");
correctGuesses.Dump("Correct Guesses");
avg = (decimal)sum / (decimal)attempts;
avg.Dump("Random Number Average");
}
Have a made an error in the code? Is this a natural relationship? I expected the averages to converge at 0.5 as I increased the number of attempts because the distribution is fairly even - I tested this with 10bn calls to Random.Next(0,2) - but I did not expect the sum of generated numbers to correlate to the number of correct guesses.
Your error is this line:
avg = (decimal)sum/(decimal)attempts;
Makes no sense to divide the sum (based over i to that point) by attempts. Divide by i (EDIT: more precisely i+1) instead for avg to give you something meaningful.
The Random class, without a seed, generates a random number using the current time as seed, meaning that a call of the rnd.Next method in your cycle will result in the same number several times over, depending on how fast your machine goes through the cycle.

Algorithm for creating unique bingo faces

Does anyone know of an algorithm that can generate unique bingo card faces? I'm looking to implement this algorithm in C#.
Thanks,
get 5 sets containing 15 numbers each (1-15 for set 1, 16-30 for set 2...)
select 5 different numbers in sets 1,2,4,5
select 4 different numbers in set 3
To check if that card already exists
Check each existing card for top left correspondance with new card
if both numbers are equal, then move to the second number
if you get 24 times the same number at the same place then both cards are equal and new card must be rejected
This is an interesting problem, but as Michael Madsen reported, given the number of possibilities, you would probably be better generate them randomly and after, check if you have duplicates. (Unless you want to generate all 111 quadrillion possibilities, which I hope you have data storage space for!)
Here's a function for generating a random subset of integers from a given range which you might find useful:
private static IEnumerable<int> RandomSubsetOfRange(int min, int max, int count)
{
Random random = new Random();
int size = max - min + 1;
for (int i = 0; i <= size; i += 1)
{
if (random.NextDouble() <= ((float)count / (float)(size - i + 1)))
{
yield return min + i;
count -= 1;
}
}
}

Categories

Resources