Creating a frequency table of dice occurrences in C# - c#

I am fairly new at programming and am currently picking up C#.
What I have is two dice rolled at random for 50 rolls
Both dice totals added together to give a sum for each roll.
My question is, how can I create a frequency table that will count the amount of times a certain number is rolled at the end of 50 dice rolls.
Below is what I am trying to achieve. Tally chart of each number rolled (from both dice)
1: |||
2: ||||
3: ||||||
4: |||||
5: ||||||||
6: ||
Here is my code so far,
class Program
{
const int DICE_ROLLS = 51;
static void Main(string[] args)
{
Random random = new Random();
int[] firstDice = new int[DICE_ROLLS];
int[] secondDice = new int[DICE_ROLLS];
int diceSum = 0;
for (int roll = 1; roll <= 50; roll++)
{
firstDice[roll] = GenerateNumber(random);
secondDice[roll] = GenerateNumber(random);
diceSum = firstDice[roll] + secondDice[roll];
Console.WriteLine("ROLL {0}: {1} + {2} = {3}", roll, firstDice[roll], secondDice[roll], diceSum);
}
Console.WriteLine();
Console.WriteLine("~~~~~~~~~~~~~~~~");
Console.WriteLine("Number Frequency");
}
static int GenerateNumber (Random random)
{
return random.Next(1, 7);
}
}

Try this:
const int DICE_ROLLS = 51;
static void Main(string[] args)
{
Random random = new Random();
int[] firstDice = new int[DICE_ROLLS];
int[] secondDice = new int[DICE_ROLLS];
int[] count = new int[6];
int diceSum = 0;
for (int roll = 0; roll <= DICE_ROLLS - 1; roll++)
{
firstDice[roll] = GenerateNumber(random);
secondDice[roll] = GenerateNumber(random);
diceSum = firstDice[roll] + secondDice[roll];
Console.WriteLine("ROLL {0}: {1} + {2} = {3}", roll + 1, firstDice[roll], secondDice[roll], diceSum);
}
Console.WriteLine();
Console.WriteLine("~~~~~~~~~~~~~~~~");
Console.WriteLine("Number Frequency");
var allRolls = firstDice.Concat(secondDice).ToList();
for(var i = 1; i <= 6; i++)
{
Console.Write(i + ": ");
for(var j = 0; j < allRolls.Count(c => c == i); j++)
Console.Write("|");
Console.WriteLine();
}
}
static int GenerateNumber (Random random)
{
return random.Next(1, 7);
}
Gives:
~~~~~~~~~~~~~~~~
Number Frequency
1: ||||||||||||||||||||
2: |||||||||||
3: ||||||||||||||||||
4: ||||||||||||||||
5: |||||||||||||||||||||
6: ||||||||||||||||

Assuming 6 sided dice, a Dictionary might be a good option.
var rolls = new SortedDictionary<int, int> { {1,0}, {2,0}, {3,0}, {4,0}, {5,0}, {6,0} };
for(int i = 0; i < 50; i++)
{
var first = Random.Next(1, 7);
var second = Random.Next(1, 7);
rolls[first]++;
rolls[second]++;
// Rest of rolling display code
}
// Header display code
foreach(var roll in rolls)
{
Console.Write("{0}: ", roll.Key);
for(int i = 0; i < rolls.Value; i++)
{
Console.Write("|");
}
Console.WriteLine();
}
You could even easily customize it based on different sided dice by generating the initial dictionary values based on a variable like
int sides = 12;
var rolls = new SortedDictionary<int, int>();
foreach(var value in Enumerable.Range(1, sides))
{
rolls.Add(value, 0);
}
The you could replace the Random.Next(1, 7) with Random.Next(1, sides) and have a pretty generic program for rolling dice and counting their frequency.

This works:
var rnd = new Random();
Console.WriteLine(
String.Join(
Environment.NewLine,
Enumerable
.Range(0, 50)
.Select(n => rnd.Next(1, 7))
.ToLookup(x => x)
.Select((xs, n) =>
String.Format("{0}: {1}", n + 1, new String('|', xs.Count())))));
I get this (for example):
1: |||||||
2: |||||||
3: |||||||||||
4: |||||||||
5: ||||||||
6: ||||||||

Related

Lottery program that generates 6 random numbers between 1 and 59 C#

I have created a simple program which randomly generates 6 winning numbers. While the program works, I would also like for it to ensure that the same number isn't outputted twice as well as sorting them into numerical order when outputted. How would I go about doing such a thing while sticking to similar techniques already used? My code is down below. Any help is very much appreciated.
int temp;
int[] lotto = new int[6];
Random rand = new Random();
for (int i = 0; i < 6; i++)
{
temp = rand.Next(1, 59);
lotto[i] = temp;
}
Console.Write($"The lotterry winning numbers are: ");
for (int i = 0; i < 6; i++)
{
Console.Write(lotto[i] + " ");
}
Console.ReadKey();
Based on a Fisher-Yates shuffle, but saves some work because we know we don't need all the values (if we only need 6 values out of 10 million potentials, we only need to take the first six iterations of the fisher-yates algorithm).
public IEnumerable<int> DrawNumbers(int count, int MaxNumbers)
{
var r = new Random(); //ideally, make this a static member somewhere
var possibles = Enumerable.Range(1, MaxNumbers).ToList();
for (int i = 0; i < count; i++)
{
var index = r.Next(i, MaxNumbers);
yield return possibles[index];
possibles[index] = possibles[i];
}
}
var lottoNumbers = DrawNumbers(6, 59);
Console.Write("The lotterry winning numbers are: ");
Console.WriteLine(string.Join(" ", lottoNumbers.OrderBy(n => n)));
See it work here:
https://dotnetfiddle.net/NXYkpU
You can use Linq to create sequence [1..59] and order it by random to shuffle it.
Random rand = new Random();
var winners = Enumerable.Range(1, 59)
.OrderBy(x => rand.Next())
.Take(6)
.OrderBy(x => x)
.ToList();
Console.WriteLine(String.Join(" ", winners));
int temp;
int[] lotto = new int[6];
Random rand = new Random();
int i = 0;
while(i < 6)
{
temp = rand.Next(1, 59);
//check if lotto contains just generated number, if so skip that number
bool alreadyExist = false;
foreach (int item in lotto)
{
if (item == temp)
{
alreadyExist = true;
break;
}
}
if (alreadyExist)
continue;
lotto[i] = temp;
i++;
}
Console.Write($"The lotterry winning numbers are: ");
// Sort array in ascending order.
Array.Sort(lotto);
for (int j = 0; j < 6; j++)
{
Console.Write(lotto[j] + " ");
}
Console.ReadKey();
I would probably do it Dmitri's way because it is quick and obvious and performance isn't that important with an array this size.
But just for fun, this is slightly more efficient.
IEnumerable<int> GetNumbers(int min, int max, int count)
{
var random = new Random();
var size = max - min + 1;
var numbers = Enumerable.Range(min, size).ToArray();
while (count > 0)
{
size--;
var index = random.Next(0, size);
yield return numbers[index];
numbers[index] = numbers[size];
count--;
}
}
This solution creates an array containing all possible values and selects them randomly. Each time a selection is made, the array is "shrunk" by moving the last element to replace the element that was chosen, preventing duplicates.
To use:
var numbers = GetNumbers(1, 59, 6).ToList();
foreach (var number in numbers.OrderBy(x => x))
{
Console.WriteLine(number);
}

Generate and store 7 random numbers in a array

I made a program to generate 7 random numbers for a lottery using a array. I have generated a random number between 1, 50 but every number shows in order and not on the same line. I would also like to store the auto generated numbers in a array to use. I am not sure how to fix this any help would be appreciated
static void AutoGenrateNumbers()
{
int temp;
int number = 0;
int[] lotto = new int[7];
Random rand = new Random();
for (int i = 0; i <= 50; i++)
{
number = 0;
temp = rand.Next(1, 50);
while (number <= i)
{
if (temp == number)
{
number = 0;
temp = rand.Next(1, 50);
}
else
{
number++;
}
}
temp = number;
Console.WriteLine($"the new lotto winning numbers are:{number}Bonus:{number}");
}
}
Is this what you need?
static void AutoGenrateNumbers()
{
int temp;
int[] lotto = new int[7];
Random rand = new Random();
for (int i = 0; i < 7; i++)
{
temp = rand.Next(1, 50);
lotto[i]= temp;
}
Console.Write($"the new lotto winning numbers are: ");
for (int i = 0; i < 6; i++)
{
Console.Write(lotto[i]+" ");
}
Console.Write($"Bonus:{lotto[6]}");
}
edit: if you want the numbers to be unique:
static void AutoGenrateNumbers()
{
int temp;
int[] lotto = new int[7];
Random rand = new Random();
for (int i = 0; i < 7; i++)
{
do
{
temp = rand.Next(1, 50);
}
while (lotto.Contains(temp));
lotto[i]= temp;
}
Console.Write($"the new lotto winning numbers are: ");
for (int i = 0; i < 6; i++)
{
Console.Write(lotto[i]+" ");
}
Console.Write($"Bonus:{lotto[6]}");
}
A better way to do this is just to generate all the numbers 1-50, shuffle them and then just take 7. Using Jon Skeet's Shuffle extension method found here:
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
T[] elements = source.ToArray();
for (int i = elements.Length - 1; i >= 0; i--)
{
int swapIndex = rng.Next(i + 1);
yield return elements[swapIndex];
elements[swapIndex] = elements[i];
}
}
Now your code is very simple:
static void AutoGenrateNumbers()
{
var lotto = Enumerable.Range(0, 50).Shuffle(new Random()).Take(7);
Console.WriteLine("the new lotto winning numbers are: {0}", string.Join(",", lotto));
}
Fiddle here
Just to add to the existing answers tried to do that in one LINQ statement:
static void Main(string[] args)
{
var rand = new Random();
Enumerable
.Range(1, 7)
.Aggregate(new List<int>(), (x, y) =>
{
var num = rand.Next(1, 51);
while (x.Contains(num))
{
num = rand.Next(1, 51);
}
x.Add(num);
return x;
})
.ForEach(x => Console.Write($"{x} "));
}
The result is something like:
34 24 46 27 11 17 2

Looking for a way to shorten my code

This is my code:
static void Main(string[] args)
{
Console.Write("How many tests would you like to do? 1 to 10: ");
int tests = Convert.ToInt32(Console.ReadLine());
Console.WriteLine();
}
can someone help me out with my code please? i have no idea what im doing
Thanks
Make an array int[] counts = new int[13] and just use counts[total]++;; at the end, loop over it:
for(int i = 2 ; i <= 12 ; i++)
// etc
(note: you could use an array of 11 items and constantly handle the off-by-two, but... it probably isn't worth it)
Something like:
static void Main()
{
Console.WriteLine("Investigation 1");
Console.WriteLine("===============");
Console.WriteLine();
Console.Write("How many sets of tests? 1 to 10: ");
int sets = Convert.ToInt32(Console.ReadLine());
Console.WriteLine();
Random r = new Random();
int[] counts = new int[13];
for (int ctr = 0; ctr < 36 * sets; ctr++)
{
int a = r.Next(1, 7), b = r.Next(1, 7), total = a + b;
Console.WriteLine($"Roll {(ctr + 1)}: {a} + {b} = {total}");
counts[total]++;
}
Console.WriteLine("=======================");
Console.WriteLine();
Console.WriteLine("Total Expected Actual");
Console.WriteLine("===== ======== ======");
for(int i = 2; i <= 12; i++)
{
var expected = sets * (6 - Math.Abs(7 - i));
Console.WriteLine($" {i} {expected} {counts[i]}");
}
}
For a histogram:
var maxCount = counts.Max(); // needs "using System.Linq;" at the top
for (int i = 2; i <= 12; i++)
{
var width = ((Console.WindowWidth - 10) * counts[i]) / maxCount; // make it proportional
Console.WriteLine($"{i}\t{new string('*', width)}");
}

How to let the user create many dice?

So right now, this code can only let you 2 dice ten times, but if i wanted the user to enter any number of dice, how do i do that?
static void Main(string[] args)
{
Random numgen = new Random();
int dice1 = 0;
int dice2 = 1;
for (int roll = 0; roll <=10; roll++)
{
dice1 = numgen.Next(1,7);
dice2 = numgen.Next(1,7);
Console.WriteLine(dice1 + "\t" + dice2);
}
Console.ReadLine();
}
Since it doesn't seem to look like you need to save any of your dice rolls, but rather just output them to the screen I would omit the dice ints.
public void RollDice(int NumberOfDice)
{
Random numgen = new Random();
for (int roll = 0; roll <= 10; roll++)
{
for (int i = 0; i < NumberOfDice; i++)
{
Console.WriteLine(numgen.Next(1, 7) + "\t" + numgen.Next(1, 7));
}
}
Console.ReadLine();
}

C# console application that can find every combination of some numbers but only writes if they can divide by 3

I have to perform a task. pls help me. İ want a c sharp console application that can find every combination of some numbers but only writes if they can divide by 3.
We have 15 card in a bag. we will take 3 cards randomly(without replacement) . After that we will add them(card1+card2+card3) and if their result can divide by 3 then we will write them to console.[(card1+card2+card3)/3]=0
Not sure where to begin with this. Any help is greatly appreciated!
You can get some idea from this I think.
public List<int[]> getCombinations(int[] inArray)
{
List<int[]> outList = new List<int[]>();
for (int i = 0; i < inArray.Length; i++)
for (int j = i + 1; j < inArray.Length; j++)
for (int k = j + 1; k < inArray.Length; k++)
{
int[] outCombination = new int[] { inArray[i], inArray[j], inArray[k] };
outList.Add(outCombination);
}
return outList;
}
static void Main(string[] args)
{
int[] inArray = new int[] { 0, 1, 2, 3, 4, 5 };
// Returned list of combinations...
Program ns = new Program();
List<int[]> Combinations = ns.getCombinations(inArray);
// example: Displaying the results...
foreach (int[] outArray in Combinations)
{
Console.Write(outArray[0] + "," + outArray[1] + "," + outArray[2]);
}
}
Given 3 numbers, you can tell if they are divisible by 3 using the modulus operator:
List<int> numbers = new List<int> {4, 8, 11}; // Represents three random cards
// This will be set to true if the sum of the numbers is evenly divisible by 3
bool numbersAreDivisibleByThree = numbers.Sum() % 3 == 0;
Here is an example of how this could be used:
private static void Main()
{
var cardBag = new List<int>();
var drawnCards = new List<int>();
// Add 15 numbers to the cardBag
for (int i = 1; i <= 15; i++)
{
cardBag.Add(i);
}
// Draw 3 cards at random
var rnd = new Random();
while (drawnCards.Count < 3)
{
var candidateCard = cardBag[rnd.Next(15)];
// In this implementation, we only add unique cards
if (!drawnCards.Contains(candidateCard))
drawnCards.Add(candidateCard);
}
// This will be set to true if the sum of the numbers is evenly divisible by 3
bool numbersAreDivisibleByThree = drawnCards.Sum() % 3 == 0;
// Output results to console
Console.WriteLine("The three random cards drawn from the deck are: {0}",
string.Join(", ", drawnCards));
Console.WriteLine("The sum of the cards is: {0}", drawnCards.Sum());
Console.WriteLine("Is the sum of the cards evenly divisible by three? {0}.",
numbersAreDivisibleByThree);
}
Since you seem like a noob, here is an easy way of looking at it (although not the most efficient and least costly):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RandomGeneratorPractice
{
class Program
{
static void Main(string[] args)
{
Random random = new Random();
int randomNumber1 = random.Next(1, 15);
int randomNumber2 = random.Next(1, 15);
int randomNumber3 = random.Next(1, 15);
bool bln = true;
while(bln)
{
if (randomNumber1 == randomNumber2)
{
randomNumber2 = random.Next(1, 15);
bln = true;
}
else if (randomNumber2 == randomNumber3 || randomNumber1==randomNumber3)
{
randomNumber3 = random.Next(1,15);
bln = true;
}
else if ((randomNumber1 != randomNumber2) && (randomNumber1 != randomNumber3) && (randomNumber2 != randomNumber3))
{
bln = false;
}
}
int dividend = randomNumber1 + randomNumber2 + randomNumber3;
double divisor = 3;
double quotient = (randomNumber1 + randomNumber2 + randomNumber3) / 3;
Console.WriteLine("(" + randomNumber1 + "+" + randomNumber2 + "+" + randomNumber3 + ") / 3 = " + (dividend / divisor));
if (dividend % divisor == 0)
{
Console.WriteLine("You CAN divide by 3 evenly");
}
else
{
Console.WriteLine("You CANNOT divide by 3 evenly");
}
Console.WriteLine("Press ENTER to exit...");
Console.Read();
}
}
}

Categories