2012-07-07 19 views
6

पुनरावृत्ति के बिना सभी संभावित क्रमपरिवर्तनों को सूचीबद्ध करने के लिए मैं नीचे अपना सी # कोड कैसे बदल सकता हूं? उदाहरण के लिए: 2 पासा रोल का नतीजा 1,1,2 का उत्पादन करेगा, इसका मतलब है कि 2,1,1 प्रकट नहीं होना चाहिए।सी #: पुनरावृत्ति के बिना डाइस क्रमपरिवर्तन

नीचे मेरी कोड है:

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; 
    } 

उत्तर

0

मैं भी गणित पर बुरा कर रहा हूँ, इस या उपयोगी नहीं हो सकता ...

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(); 
     } 
    } 
} 

थ्रीडिइस.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's 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] + ">"; 
     } 
    } 
} 

शुभकामनाएँ।

5

सरल संभव तरह से मैं के बारे में सोच सकता है:

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)); 
     } 
    } 
} 
0

सवाल का महत्वपूर्ण हिस्सा है कि आप अलग सेट करना चाहते हैं (आदेश की परवाह किए बिना) है। तो उदाहरण के लिए, [1, 2, 1] का पासा रोल [1, 1, 2] के पासा रोल के बराबर है।

मुझे यकीन है कि इस बिल्ली को त्वचा के कई तरीके हैं, लेकिन पहला विचार जो दिमाग में आता है वह समानता कॉम्पैयर बनाने के लिए है जो आपके इच्छित तरीके से पासा की सूची की तुलना करेगा, और उसके बाद LINQ का उपयोग करें Distinct() विधि। यहाँ

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; 
     } 
    } 

और कोड यह का उपयोग करता है:

यहाँ EqualityComparer, जो 2 List<int> का उपयोग करके (आदेश की परवाह किए बिना) का कहना है कि वे बराबर अगर तत्वों सब बराबर हैं कर रहे हैं। मैं LINQ का उपयोग कर रहा सभी संयोजनों की सूची का निर्माण करने के ... आप भी नेस्टेड for छोरों के साथ ऐसा कर सकता है, लेकिन मैं किसी कारण से यह बेहतर पसंद है:

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]); 
    } 

आशा है कि मदद करता है!

1

मैंने द्विपक्षीय गुणांक के साथ काम करने के लिए सामान्य कार्यों को संभालने के लिए एक कक्षा लिखी है, जो आपकी समस्या के तहत समस्या का प्रकार है। यह निम्न कार्य करता है:

  1. किसी भी एन के लिए एक अच्छा प्रारूप में सभी के-इंडेक्स आउटपुट को किसी फ़ाइल को के लिए चुनें। के-इंडेक्स को अधिक वर्णनात्मक तारों या अक्षरों के साथ प्रतिस्थापित किया जा सकता है। यह विधि इस प्रकार की समस्या को काफी तुच्छ हल करती है।

  2. क्रमबद्ध द्विपदीय गुणांक तालिका में एंट्री के उचित सूचकांक में के-इंडेक्स को परिवर्तित करता है। यह तकनीक पुरानी प्रकाशित तकनीकों की तुलना में बहुत तेज है जो पुनरावृत्ति पर भरोसा करती है। यह पास्कल के त्रिभुज में अंतर्निहित गणितीय संपत्ति का उपयोग करके करता है। मेरे पेपर इस बारे में बात करते हैं। मेरा मानना ​​है कि मैं इस तकनीक को खोजने और प्रकाशित करने वाला पहला व्यक्ति हूं, लेकिन मैं गलत हो सकता हूं।

  3. इंडेक्स को एक क्रमबद्ध बिनोमियल गुणांक तालिका में संबंधित के-इंडेक्स में परिवर्तित करता है।

  4. द्विपक्षीय गुणांक की गणना करने के लिए Mark Dominus विधि का उपयोग करता है, जो अतिप्रवाह होने की संभावना कम है और बड़ी संख्या में काम करता है।

  5. कक्षा .NET C# में लिखा गया है और एक सामान्य सूची का उपयोग करके समस्या से संबंधित वस्तुओं (यदि कोई है) को प्रबंधित करने का एक तरीका प्रदान करता है। इस वर्ग के निर्माता को इटटेबल नामक एक बूल वैल्यू लेता है, जब सत्य ऑब्जेक्ट्स को प्रबंधित करने के लिए एक सामान्य सूची बनायेगा। यदि यह मान गलत है, तो यह तालिका नहीं बनाएगा। उपरोक्त 4 विधियों को करने के लिए तालिका को बनाने की आवश्यकता नहीं है। तालिका तक पहुंचने के लिए एक्सेसर विधियां प्रदान की जाती हैं।

  6. एक संबंधित टेस्ट क्लास है जो दिखाती है कि कक्षा और उसके तरीकों का उपयोग कैसे करें। इसका व्यापक रूप से 2 मामलों के साथ परीक्षण किया गया है और कोई ज्ञात बग नहीं है।

इस कक्षा के बारे में पढ़ने और कोड डाउनलोड करने के लिए, Tablizing The Binomial Coeffieicent देखें।

0

यहां रिकर्सन का उपयोग करके जेनेरिक सी # संस्करण है (मूल रूप से रिकर्सिव विधि डाइस की संख्या लेती है या पासा फेंकने की संख्या लेती है) और सभी संयोजन तारों को वापस कर देता है (पूर्व में, '3' के लिए प्रश्न के अनुसार - वहां 56 ऐसे संयोजन होंगे)।

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); 
      } 
     } 

नीचे इसी रहे हैं परीक्षण ...

[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); 
      } 
     }