fork download
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4.  
  5. public class Test
  6. {
  7.  
  8. static Random random = new Random();
  9.  
  10. public static List<int> GenerateRandom(int count, int min, int max)
  11. {
  12.  
  13. // initialize set S to empty
  14. // for J := N-M + 1 to N do
  15. // T := RandInt(1, J)
  16. // if T is not in S then
  17. // insert T in S
  18. // else
  19. // insert J in S
  20. //
  21. // adapted for C# which does not have an inclusive Next(..)
  22. // and to make it from configurable range not just 1.
  23.  
  24. if (max <= min || count < 0 ||
  25. // max - min > 0 required to avoid overflow
  26. (count > max - min && max - min > 0))
  27. {
  28. // need to use 64-bit to support big ranges (negative min, positive max)
  29. throw new ArgumentOutOfRangeException("Range " + min + " to " + max +
  30. " (" + ((Int64)max - (Int64)min) + " values), or count " + count + " is illegal");
  31. }
  32.  
  33. // generate count random values.
  34. HashSet<int> candidates = new HashSet<int>();
  35.  
  36. // start count values before max, and end at max
  37. for (int top = max - count; top < max; top++)
  38. {
  39. // May strike a duplicate.
  40. // Need to add +1 to make inclusive generator
  41. // +1 is safe even for MaxVal max value because top < max
  42. if (!candidates.Add(random.Next(min, top + 1))) {
  43. // collision, add inclusive max.
  44. // which could not possibly have been added before.
  45. candidates.Add(top);
  46. }
  47. }
  48.  
  49. // load them in to a list, to sort
  50. List<int> result = candidates.ToList();
  51.  
  52. // shuffle the results because HashSet has messed
  53. // with the order, and the algorithm does not produce
  54. // random-ordered results (e.g. max-1 will never be the first value)
  55. for (int i = result.Count - 1; i > 0; i--)
  56. {
  57. int k = random.Next(i + 1);
  58. int tmp = result[k];
  59. result[k] = result[i];
  60. result[i] = tmp;
  61. }
  62. return result;
  63. }
  64.  
  65. public static List<int> GenerateRandom(int count)
  66. {
  67. return GenerateRandom(count, 0, Int32.MaxValue);
  68. }
  69.  
  70.  
  71. // TEST CODE BELOW HERE
  72.  
  73. class Counter {
  74. public int Count { get; set; }
  75. }
  76.  
  77. public static string IntsToString(List<int> data) {
  78. return string.Join(", ", data.Select(x => x.ToString()).ToArray());
  79. }
  80.  
  81. public static void Main()
  82. {
  83. try {
  84. List<int> vals = GenerateRandom(10);
  85. Console.WriteLine("Result: " + vals.Count);
  86. vals.ForEach(Console.WriteLine);
  87.  
  88. Console.WriteLine();
  89.  
  90. GenerateRandom(10, Int32.MinValue, Int32.MaxValue).ForEach(Console.WriteLine);
  91.  
  92. Console.WriteLine();
  93.  
  94. SortedDictionary<string,Counter> counts = new SortedDictionary<string,Counter>();
  95. for (var i = 0; i < 24000; i++)
  96. {
  97. List<int>varray = GenerateRandom(3, 0, 4);
  98. //varray.Sort();
  99. string v = IntsToString(varray);
  100. if (!counts.ContainsKey(v))
  101. {
  102. counts.Add(v, new Counter());
  103. }
  104. //Console.WriteLine("Processing " + v + " with counts " + counts[v].Count);
  105. counts[v].Count = counts[v].Count + 1;
  106.  
  107. }
  108.  
  109. foreach (string key in counts.Keys)
  110. {
  111. Console.WriteLine("{0} -> {1}", key, counts[key].Count);
  112. }
  113. }
  114. catch (Exception e)
  115. {
  116. Console.WriteLine("{0} Exception caught.", e);
  117. }
  118. }
  119. }
  120.  
Success #stdin #stdout 0.51s 34520KB
stdin
Standard input is empty
stdout
Result: 10
1170697438
120105513
855090899
763869798
775127055
1193185824
778291465
565942465
1570240628
3835490

1385019287
-404232386
556571568
-1518374403
-777106293
1231209584
-897704110
-1961167793
2082881277
1931032930

0, 1, 2 -> 1016
0, 1, 3 -> 1069
0, 2, 1 -> 1005
0, 2, 3 -> 1001
0, 3, 1 -> 962
0, 3, 2 -> 956
1, 0, 2 -> 1038
1, 0, 3 -> 936
1, 2, 0 -> 1064
1, 2, 3 -> 985
1, 3, 0 -> 1024
1, 3, 2 -> 949
2, 0, 1 -> 1048
2, 0, 3 -> 1004
2, 1, 0 -> 982
2, 1, 3 -> 991
2, 3, 0 -> 965
2, 3, 1 -> 1043
3, 0, 1 -> 1042
3, 0, 2 -> 983
3, 1, 0 -> 944
3, 1, 2 -> 949
3, 2, 0 -> 1000
3, 2, 1 -> 1044