Click here to Skip to main content
15,886,032 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Select x elements from list of length n. It cannot be first and last element, and all selected elements must not be adjacent to each other.

If we assume a list of length 10 from 0 to 9, feasible examples:
1 5 8 (x = 3)
2 4 (x = 2)
1 3 5 8 (x = 4)

Examples that do not meet the requirements:
0 9 (x = 2)
1 2 3 (x = 3)
3 5 6 9 (x = 4)

There is a certain maximum value of x and going above that these requirements can't be met, but this is something that I can handle on my own.

I know that you can for example do:
C#
var selected = list.OrderBy(x => Guid.NewGuid()).Take(x).ToList();

But this won't meet any of these constraints. You can remove first and last elements before ordering, but still second requirement is not met.

What I have tried:

I have already mentioned above things that I have already tried.
Posted
Updated 12-Sep-22 1:34am

1 solution

First, generate a collection of indices that match the criteria:
The way I'd do it is to create a collection containing all valid indexes at the start (i.e. 0 to N-2 to exclude the first and last elements) - Enumerable.Range will do that for you.So if N = 8, and x = 3 then
N = 8: 1 2 3 4 5 6
Then generate a random index in that collection, and remove it and the values one larger and one smaller (if present)
i = 3: 
index in original table = 4
       1 2 6

Generate a random index again and repeat until x has been met or you can't get another value.

At the end, you can use the values to index into your original collection.
Try it on paper and you'll see what I mean.
 
Share this answer
 
Comments
CPallini 12-Sep-22 7:39am    
5.
Member 15047625 12-Sep-22 7:57am    
Ok thats smart. I have already did it on my own but it's definitely suboptimal - iterate through collection (except first and last element) and pick them with certain probability. Once selected, skip next adjacent element. If enough items have been selected exit, if not enough finish the job and get the rest by brute force without randomness (while respecting constraints).
OriginalGriff 12-Sep-22 8:24am    
Except your question specifically requires randomness! :D

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900