C #: swapping cubes without repeating

How can I change my C # code below to list all possible permutations without repetition? For example: the result of 2 roll cubes will give 1,1,2, so 2,1,1 should not appear.

Below is my code:

string[] Permutate(int input) { string[] dice; int numberOfDice = input; const int diceFace = 6; dice = new string[(int)Math.Pow(diceFace, numberOfDice)]; int indexNumber = (int)Math.Pow(diceFace, numberOfDice); int range = (int)Math.Pow(diceFace, numberOfDice) / 6; int diceNumber = 1; int counter = 0; for (int i = 1; i <= indexNumber; i++) { if (range != 0) { dice[i - 1] += diceNumber + " "; counter++; if (counter == range) { counter = 0; diceNumber++; } if (i == indexNumber) { range /= 6; i = 0; } if (diceNumber == 7) { diceNumber = 1; } } Thread.Sleep(1); } return dice; } 
+6
source share
5 answers

The easiest way I could think of:

 List<string> dices = new List<string>(); for (int i = 1; i <= 6; i++) { for (int j = i; j <= 6; j++) { for (int k = j; k <= 6; k++) { dices.Add(string.Format("{0} {1} {2}", i, j, k)); } } } 
+5
source

I wrote a class to handle common functions for working with the binomial coefficient, which is the type of problem your problem relates to. It performs the following tasks:

  • Prints all K-indices in a good format for any N that selects K to a file. K-indices can be replaced with more descriptive strings or letters. This method allows you to solve this type of problem is quite trivial.

  • Converts K-indices to the corresponding record index in the table of sorted binomial coefficients. This method is much faster than older published iteration-based methods. He does this using the mathematical property inherent in the Pascal Triangle. My article talks about this. I believe that I am the first to discover and publish this technique, but I could be wrong.

  • Converts an index into a sorted table of binomial coefficients into the corresponding K-indices.

  • Uses the Mark Dominus method to calculate a binomial coefficient, which is much less likely to overflow and works with large numbers.

  • The class is written in .NET C # and provides a way to manage the objects associated with the problem (if any) using a common list. The constructor of this class takes a bool value called InitTable, which, when true, will create a general list for storing objects to be managed. If this value is false, then it will not create a table. You do not need to create a table to complete the methods described above. To access the table, access methods are provided.

  • There is a related test class that shows how to use the class and its methods. It has been extensively tested with 2 cases and there are no known errors.

To read about this class and download the code, see Tablizing the Binomial Coeffieicent .

+1
source

I am not good at math, it may or may not be useful ...

Program.cs

 namespace Permutation { using System; using System.Collections.Generic; class Program { static void Main(string[] args) { Console.WriteLine("Generating list."); var dice = new List<ThreeDice>(); for (int x = 1; x <= 6; x++) { for (int y = 1; y <= 6; y++) { for (int z = 1; z <= 6; z++) { var die = new ThreeDice(x, y, z); if (dice.Contains(die)) { Console.WriteLine(die + " already exists."); } else { dice.Add(die); } } } } Console.WriteLine(dice.Count + " permutations generated."); foreach (var die in dice) { Console.WriteLine(die); } Console.ReadKey(); } } } 

ThreeDice.cs

 namespace Permutation { using System; using System.Collections.Generic; public class ThreeDice : IEquatable<ThreeDice> { public ThreeDice(int dice1, int dice2, int dice3) { this.Dice = new int[3]; this.Dice[0] = dice1; this.Dice[1] = dice2; this.Dice[2] = dice3; } public int[] Dice { get; private set; } // IEquatable implements this method. List.Contains() will use this method to see if there a match. public bool Equals(ThreeDice other) { // Get the current dice values into a list. var currentDice = new List<int>(this.Dice); // Check to see if the same values exist by removing them one by one. foreach (int die in other.Dice) { currentDice.Remove(die); } // If the list is empty, we have a match. return currentDice.Count == 0; } public override string ToString() { return "<" + this.Dice[0] + "," + this.Dice[1] + "," + this.Dice[2] + ">"; } } } 

Good luck.

0
source

The important part of the question is that you need different sets (regardless of order). So, for example, the roll of the bone [1, 2, 1] is equal to the roll of the die [1, 1, 2].

I'm sure there are several ways for this cat, but the first thought that comes to mind is to create an EqualityComparer that will compare the list of bones the way you want, and then use LINQ with Distinct() .

Here is the EqualityComparer that takes 2 List<int> and says that they are equal if all elements are equal (regardless of order):

  private class ListComparer : EqualityComparer<List<int>> { public override bool Equals(List<int> x, List<int> y) { if (x.Count != y.Count) return false; x.Sort(); y.Sort(); for (int i = 0; i < x.Count; i++) { if (x[i] != y[i]) return false; } return true; } public override int GetHashCode(List<int> list) { int hc = 0; foreach (var i in list) hc ^= i; return hc; } } 

And here is the code that uses it. I use LINQ to create a list of all the combinations ... you can also do this with nested for loops, but for some reason I like this for some reason:

  public static void Main() { var values = new[] { 1,2,3,4,5,6 }; var allCombos = from x in values from y in values from z in values select new List<int>{ x, y, z }; var distinctCombos = allCombos.Distinct(new ListComparer()); Console.WriteLine("#All combos: {0}", allCombos.Count()); Console.WriteLine("#Distinct combos: {0}", distinctCombos.Count()); foreach (var combo in distinctCombos) Console.WriteLine("{0},{1},{2}", combo[0], combo[1], combo[2]); } 

Hope this helps!

0
source

Here is a general version of C # with recursion (basically, the recursive method takes the number of dice or the number of times the dice were rolled) and returns all combinations of strings (for example, for "3" according to the question - there will be 56 such combinations).

 public string[] GetDiceCombinations(int noOfDicesOrnoOfTossesOfDice) { noOfDicesOrnoOfTossesOfDice.Throw("noOfDicesOrnoOfTossesOfDice", n => n <= 0); List<string> values = new List<string>(); this.GetDiceCombinations_Recursive(noOfDicesOrnoOfTossesOfDice, 1, "", values); return values.ToArray(); } private void GetDiceCombinations_Recursive(int size, int index, string currentValue, List<string> values) { if (currentValue.Length == size) { values.Add(currentValue); return; } for (int i = index; i <= 6; i++) { this.GetDiceCombinations_Recursive(size, i, currentValue + i, values); } } 

Below are the relevant tests ...

 [TestMethod] public void Dice_Tests() { int[] cOut = new int[] { 6, 21, 56, 126 }; for(int i = 1; i<=4; i++) { var c = this.GetDiceCombinations(i); Assert.AreEqual(cOut[i - 1], c.Length); } } 
0
source

Source: https://habr.com/ru/post/919921/


All Articles