Let's look at the geometric interpretation of your assignment.
Let our range of admissible numbers [a, b] , and we need to create an array of length n . Then we need to throw n different numbers on the segment [a, b] n so that the distance between them is at least 5.
[ a _ _ _ _ _ * _ _ _ _ _ _ * _ _ _ _ _ _ _ _ _ _ _ _ _ b ] | | |<--- >=5 --->|
We add to each of the numbers a “neighborhood” with a diameter of 2. Then it turns out that we need to inscribe in the segment [a - 2, b + 2] n such non-intersecting neighborhoods:
[ A _ _ _ _ _ * * * * * _ _ * * * * * _ _ _ _ _ _ _ _ _ _ _ _ _ B ]
( A = a - 2 , B = b + 2 ). In this case, the beginning of the neighborhood must also have integer coordinates.
We collapse each of the neighborhoods into a point, and the length of the entire segment will decrease by 4 * n .
Now our picture is simplified: for the segment of length (b + 2) - (a - 2) + 1 - 4 * n you need to throw n different points. And this is a well-known task. It is solved with the help of the classic random sampling with a tank , here is the code in C #. We modify it for our needs:
int[] Generate(int a, int b, int n) { int max = (b + 2) - (a - 2) + 1 - 4 * n; if (n > max) throw new Exception("Задача неразрешима"); int[] result = ReservoirSampling(n, max); // выборка неотсортирована, сортируем Arrays.sort(result); // и возвращаем нужные индексы: for (int i = 0; i < n; i++) result[i] += a + (4 * i); return result; } int[] ReservoirSampling(int n, int max) { Random r = new Random(); // этот экземпляр нужно сделать глобальным int[] result = new int[n]; for (int i = 0; i < n; i++) result[i] = i; for (int i = n; i < max; i++) { int j = r.nextInt(i + 1); if (j < n) result[j] = i; } return result; }
Check: http://ideone.com/yCLwqg