This is homework assignment for school, but I'm begging for someone to just correct my code. I've been working at this for two days and I think I have everything worked out except I can't get it to work as a 2D Array, so I set this up temporarily just to try to figure things out, but I'm digging myself deeper into a hole I think.
The assignment requires that two dice be rolled 36,000 times and then the results for each sum be displayed on the right, and the sum of the two dice on the left, like this in a 2D array:
12 850
11 1020
10 1200
...
2 900
I've got the right column displaying correctly, but the left column won't display the sums, it just displays "System.Int32[]" a bunch of times.
Here's the code:
Random rand = new Random();
const int ARRAY_SIZE = 13;
const double DICE_ROLLS = 36000;
int sum = 0;
int die1 = 0;
int die2 = 0;
int[] sums = new int[ARRAY_SIZE];
int[] dice = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
for (int i = 0; i < DICE_ROLLS; i++ )
{
die1 = rand.Next(1, 7);
die2 = rand.Next(1, 7);
sum = die1 + die2;
sums[sum] += 1;
}
for (int i = 2; i < sums.Length; i++)
{
Console.WriteLine("{0,2} {1,8}", dice, sums[i]);
}
In the spirit of the homework assignment, rather than fixing the code outright, I will try to explain the parts you need to fix, and let you do the actual fixing.
The primary issue in your code is that you are trying to print dice as the value for the left column of the output, rather than individual elements of dice (e.g. dice[i]).
Note, however, that you can't just use dice[i], because your dice array has fewer elements in it than the sums array. If you just replaced dice with dice[i] in your WriteLine() statement, you'd get an index-out-of-bounds exception.
IMHO, the best way to address this is to initialize sums with 11 elements instead of 13, and then when tracking the sums (i.e. in your first loop), subtract 2 from the actual sum value to get the index for the sums array:
sums[sum - 2] += 1;
Then in your second loop, you can safely just use i to index both arrays.
I hope that helps. Please feel free to ask for any clarifications and good luck with your assignment.
Since you'll be using a 2d array you'll want to do something like this:
var rand = new Random();
const double diceRolls = 36000;
var sums = new[,] {{2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}, {10, 0}, {11, 0}, {12, 0}};
for (var i = 0; i < diceRolls; i++)
{
var die1 = rand.Next(1, 7);
var die2 = rand.Next(1, 7);
var sum = die1 + die2;
sums[sum - 2, 1] += 1;
}
for (var i = 0; i < sums.GetLength(0); i++)
{
Console.WriteLine("{0,2} {1,8}", sums[i, 0], sums[i, 1]);
}
Note 1: sum - 2. Since the array length is only 11 you need to subtract 2 from the dice value. (0-10 instead of 2-12).
Note 2: sums.GetLength(0). If you use sums.Length you'll get 22 since there actually are 22 elements in the array. You need to get the length for rank 0
Note 3: Since you're dealing with 2d arrays you'll have the sum of the dice roll in sum[i, 0] and the total count in sum[i, 1].
Related
I am using this library for combinatorics:
https://github.com/eoincampbell/combinatorics/
What I need is to find n-th permutation and count elements of fairly large sets (up to about 30 elements), but I get stopped in my tracks before even starting, check out this code:
int[] testSet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
var permutation = new Permutations<int>(testSet);
var test = permutation.Count;
Everything works peachy just until 20 element large set, once I add 21st, permutations stop working right, eg.
here is what permutation.Count returns:
-4249290049419214848
which is far from being the right number.
I am assuming that it all boils down to how huge numbers I use - overflowing ints/longs that library uses. That is why, I am asking for an advice - is there a library? approach? or a fairly quick to implement way to have combinatorics work on bigintegers?
Thanks!
Get the number of possible permuations.
The number of permutations is defined by nPr or n over r
n!
P(n,r) = --------
(n - r)!
Where:
n = Number of objects
r = the size of the result set
In your example, you want to get all permutations of a given list. In this case n = r.
public static BigInteger CalcCount(BigInteger n, BigInteger r)
{
BigInteger result = n.Factorial() / (n - r).Factorial();
return result;
}
public static class BigIntExtensions
{
public static BigInteger Factorial(this BigInteger integer)
{
if(integer < 1) return new BigInteger(1);
BigInteger result = integer;
for (BigInteger i = 1; i < integer; i++)
{
result = result * i;
}
return result;
}
}
Get the nTh permutation
This one depends on how you create/enumerate the permutations. Usually to generate any permutation you do not need to know all previous permutations. In other words, creating a permutation could be a pure function, allowing you to directly create the nTh permutation, without creating all possible ones.
This, however, depends on the algorithms used. But will potentially be a lot faster to create the permutation only when needed (in contrast to creating all possible permutations up front -> performance and very memory heavy).
Here is a great discussion on how to create permutations without needing to calculate the previous ones: https://stackoverflow.com/a/24257996/1681616.
This is too long for a comment, but wanted to follow up on #Iqon's solution above. Below is an algorithm that retrieves the nth lexicographical permutation:
public static int[] nthPerm(BigInteger myIndex, int n, int r, BigInteger total)
{
int j = 0, n1 = n;
BigInteger temp, index1 = myIndex;
temp = total ;
List<int> indexList = new List<int>();
for (int k = 0; k < n; k++) {
indexList.Add(k);
}
int[] res = new int[r];
for (int k = 0; k < r; k++, n1--) {
temp /= n1;
j = (int) (index1 / temp);
res[k] = indexList[j];
index1 -= (temp * j);
indexList.RemoveAt(j);
}
return res;
}
Here is a test case and the result of calling nthPerm using the code provided by #Iqon.
public static void Main()
{
int[] testSet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
BigInteger numPerms, n, r;
n = testSet.Length;
r = testSet.Length;
numPerms = CalcCount(n, r);
Console.WriteLine(numPerms);
BigInteger testIndex = new BigInteger(1234567890987654321);
int[] myNthIndex = nthPerm(testIndex, (int) n, (int) r, numPerms);
int[] myNthPerm = new int[(int) r];
for (int i = 0; i < (int) r; i++) {
myNthPerm[i] = testSet[myNthIndex[i]];
}
Console.WriteLine(string.Join(",", myNthPerm));
}
// Returns 1,12,4,18,20,19,7,5,16,11,6,8,21,15,13,2,14,9,10,17,3
Here is a link to ideone with working code.
You can useJNumberTools
List<String> list = new ArrayList<>();
//add elements to list;
JNumberTools.permutationsOf(list)
.uniqueNth(1000_000_000) //next 1 billionth permutation
.forEach(System.out::println);
This API will generate the next nth permutation directly in lexicographic order. So you can even generate next billionth permutation of 100 items.
for generating next nth permutation of given size use:
maven dependency for JNumberTools is:
<dependency>
<groupId>io.github.deepeshpatel</groupId>
<artifactId>jnumbertools</artifactId>
<version>1.0.0</version>
</dependency>
I have an array like this
int[] intnumber = new int[]{10,25,12,36,100,54,68,75,63,24,1,6,9,5};
I want to find the greatest number and make it In order from largest to smallest
like this
100,75,68,63,54,36,25,24,12,10,9,6,5,1
int[] intnumber = new int[] { 10, 25, 12, 36, 100, 54, 68, 75, 63, 24, 1, 6, 9, 5 };
int maxValue = intnumber.Max();
You can sort the array for viewing elements in ascending order
Array.Sort(intnumber);
Array.Reverse(intnumber);
foreach (var str in intnumber )
{
MessageBox.Show(str.ToString());
}
Try this,
int[] intnumber = new int[] { 10, 25, 12, 36, 100, 54, 68, 75, 63, 24, 1, 6, 9, 5 };
//Maximum Value
int maxValue = intnumber.Max();
//Maximum Index
int maxIndex = intnumber.ToList().IndexOf(maxValue);
You can use :
int[] intnumber = new int[]{10,25,12,36,100,54,68,75,63,24,1,6,9,5};
Array.Sort(intnumber );
Array.Reverse(intnumber );
int max = intnumber[0];
exactly output that you want.
int[] intnumber = new int[] { 10,25,12,36,100,54,68,75,63,24,1,6,9,5 };
Array.Sort<int>(intnumber ,
new Comparison<int>(
(i1, i2) => i2.CompareTo(i1)
));
intnumber .Dump();
P.S. To run this demo you need to follow these steps:
1.Download LINQPad.
2.Download the demo file, open it with LINQPad and hit F5.
I found my answer with your helps
Console.WriteLine("How many Numbers Do you want? ");
int counter = int.Parse(Console.ReadLine());
double[] numbers = new double[counter];
for (int i = 0; i < numbers.Length; i++)
{
Console.Write((i + 1) + " : ");
numbers[i] = Convert.ToDouble(Console.ReadLine());
}
Console.WriteLine("_______________________________________________");
Array.Sort(numbers);
Array.Reverse(numbers);
foreach (double item in numbers)
{
Console.WriteLine(item);
}
Console.WriteLine("_______________________________________________");
Console.WriteLine("The Greatest Number is " + numbers[0]);
Console.ReadKey();
Let intNumbers be the array that you are using, Then you can use the .Max() method of the Array Class to get the maximum value, that is the greatest number. If you want to Sort the Current array means You have to use the .Sort() method. The requirement is simply Printing the Array in descending order means you have to use the .OrderBy()
int[] inputNumbers = new int[] { 15, 12, 11, 23, 45, 21, 2, 6, 85, 1 };
Console.WriteLine("Input Array is : {0}\n",String.Join(",",inputNumbers.OrderByDescending(x=>x)));
Console.WriteLine("Max value in the array is : {0}\n",inputNumbers.Max());
Console.WriteLine("Array in descending order : {0}\n",String.Join(",",inputNumbers.OrderByDescending(x=>x)));
Here is a working Example
int max = Integer.MIN_VALUE;
for (int i =0; i < intnumber.length; i++)
{
int num = intnumber[i];
//Check to see if num > max. If yes, then max = num.
}
System.out.println(max);
I'm working on a project in C# that involves keeping track of the top five high scores for a rock paper scissors game. Right now I have an array to hold the top five scores (which are integers), I sort the array in descending order, and I use a for loop to compare the score just earned by the user to the scores currently in the array. If the new score is higher than one in the array, right now the new score just takes the space in the array that the lower one occupied.
For example, if the scores were 9, 8, 5, 3, 1 and the user scored a 6, the scores would then look like this: 9, 8, 6, 3, 1. I wondered if there's a way for me to shift the lower scores over and insert the new one, so the list would look like this: 9, 8, 6, 5, 3.
This is the code I currently have, where successPercent is the score, calculated as wins divided by losses and ties:
int[] scoreArray = { 84, 25, 36, 40, 50 };
Array.Sort(scoreArray);
Array.Reverse(scoreArray);
for (int x = 0; x <= scoreArray.Length; ++x)
{
if (successPercent > scoreArray[x])
{
scoreArray[x] = Convert.ToInt32(successPercent);
break;
}
}
Something like this can do the trick:
Create temporary list
Add new score
Sort it by descending order
Take top 5...
int[] scoreArray = { 84, 25, 36, 40, 50 };
var tempList = new List<int>(scoreArray );
int newScore = ...;//Get the new score
tempList.Add(newScore);
scoreArray = tempList.OrderByDescending(x=>x)
.Take(5)
.ToArray();
You can do this without creating a new list.
[Algo]: Replace the smallest number by the new number and then sort!
int[] scoreArray = { 5, 3, 9, 8, 1 };
int new_number = 6;
//Replaces smallest number by your new number
int min_index = Array.IndexOf(scoreArray, scoreArray.Min());
scoreArray[min_index] = new_number;
Array.Sort(scoreArray);
Array.Reverse(scoreArray);
I believe your way is correct and more effient than creating redundant lists, just you are calling the Reverse method unnecessarily.Instead, leave your elements sorted in ascending order, then loop through the array, and sort it in descending order.
int[] scoreArray = { 84, 25, 36, 40, 50 };
int userScore = 100;
Array.Sort(scoreArray);
for (int x = 0; x <= scoreArray.Length; ++x)
{
if (userScore > scoreArray[x])
{
scoreArray[x] = Convert.ToInt32(userScore);
break;
}
}
Array.Sort(scoreArray,(x,y) => y.CompareTo(x));
Note: My first solution was throwing away the second highest score so I have deleted it.
I'm sure there's a word for what I,m looking for but since I don't know it I can't find the answear to my problem, what I have is a jagged array of double and I want the value at index 0 to be the value of index 1 same for the index 1 going to the 2 until the end of the array and the last index being pish to the index 0
Example :
Original
private double[][] array = { {1, 2, 3, 4}, {5, 6, 7, 8}, ...}
Become (After the modification)
I know it's seems I'm redeclaring the array that's not the point, it's just to show you what it should be after.
private double[][] array = { {4, 1, 2, 3}, {8, 5, 6, 7}, ...}
EDIT
If you know the word or somethings about what I'm looking for, could you say so in the comment I will delete the question and look further into it
This is usually called rotating. You can achieve it a for-loop, but note that since your rotating to the right, it's easier to work your way from back to front, like this:
for(var i = 0; i < array.Length; i++)
{
var len = array[i].Length;
if (len > 1) {
var last = array[i][len - 1];
for(var j = len - 1; j > 0; j--)
{
array[i][j] = array[i][j - 1];
}
array[i][0] = last;
}
}
You could easily use a List of Queue instead of a jagged array. Below an example of how your jagged array could look like and how to move elements:
var queues = new List<Queue<double>>();
//first queue (1,2,3,4)
var queue = new Queue<double>();
queue.Enqueue(4);
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queues.Add(queue);
//second queue (5,6,7,8)
var queue2 = new Queue<double>();
queue.Enqueue(8);
queue.Enqueue(7);
queue.Enqueue(6);
queue.Enqueue(5);
queues.Add(queue2);
//an example of how to "rotate"
var lastItem = queues[0].Dequeue(); // (1,2,3)
queues[0].Enqueue(lastItem); // (4,1,2,3)
I am trying to write a function which iterates through an array and when it finds a certain type of value it will shift it to the right a defined number of places.
I know how to shift elements by temporarily storing a value, shifting the right side elements to the left and then writing the temporary value in the correct place.
The bit I am struggling with is if the certain character appears near the end of the array I need it to wrap around and continue from the start of the array, so is circular.
So an array shifting, for example, capital letters to the right 3 places and special characters to the left 1 place:
{ M, y, N, a, m, e, P} becomes...
{ y, M, P, a, N, m, e}
To shift an element of 8 to the right 3 places I have below, but this only works if 8 appears earlier than 3 elements from the end of the array and will not wrap around.
input array:
{0, 1, 2, 3, 4, 5, 6, 7, **8**, 9}
desired output:
{0, **8**, 1, 2, 3, 4, 5, 6, 7, 9}
int[] array = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int i = array.Length - 1; i >= 0; i--)
{
if (array[i] == 8)
{
int temp = array[i];
int j = 0;
for (j = i; j < i + 3; j++)
{
array[j] = array[j + 1];
}
array[j] = temp;
}
}
Just use modulo arithmetic so that instead of writing to the element at index j as you shift, instead write to the element at index j % array.Length. Thusly:
public void FindAndShift<T>(T[] array, T value, int shift) {
int index = Array.IndexOf(array, value);
int shiftsRemaining = shift;
for(int currentPosition = index; shiftsRemaining > 0; shiftsRemaining--) {
array[currentPosition % array.Length] = array[(currentPosition + 1) % array.Length];
}
array[(index + shift) % array.Length] = value;
}
I have excluded error checking.
You can do it with an if statement, check if there is room enough before the end of the array and if it isn't you have to calculate how many steps to shift in the beginning of the array aswell.
I also think that you can do it by calculating the positions modulo the length of the array when you do the shifting, I can't try it at the moment but the logic in my head says that it should work.