Search code examples
rubycombinatoricsrandomized-algorithm

How to randomly permute elements from two lists while respecting a non-consecutive ordering constraint?


I am part of a study where subjects are given input from 4 categories (1, 2, 3, 4) and each category has 4 words (a, b, c, d). The order of the words needs to be randomized for each subject, but consecutive words should be from different categories.

I am fairly new to coding and have been working on an algorithm that can do this, but it is getting pretty long and complicated, and I feel there should be a simpler way to do it that is less prone to errors. Any help would be much appreciated!


Solution

  • Here is a "brute force" (computationally inefficient, but simple) method.

    1. Produce a randomized list.
    2. Check whether the list meets the criteria.
    3. Repeat until you have collected as many valid lists as you need.
        source = ["1a","1b","1c","1d","2a","2b","2c","2d","3a","3b","3c","3d","4a","4b","4c","4d"]
        valid = []
        num_valid = 100
        
        until valid.length >= num_valid do
          candidate = source.shuffle
        
          if candidate.each_cons(2).all? {|a,b| a[0] != b[0] }
            valid |= [candidate]
          end
        end
    

    When the example code above terminates, valid will contain 100 different valid lists.