Generating unique sorted partitions in Ruby

只谈情不闲聊 提交于 2020-01-01 06:14:41

问题


I'm trying to generate the set of sequences as shown below, not in any particularly order, but here its shown as a descending sequence. Note that each sequence also descends as I'm interested in combinations, not permutations. I'd like to store each sequence as an array..or the set of sequences as an array of arrays more preferably, but first things first.

6                   
5   1               
4   2               
4   1   1           
3   3               
3   2   1           
3   1   1   1       
2   2   2           
2   2   1   1       
2   1   1   1   1   
1   1   1   1   1   1

Right now I am simply focusing on generating these sets and I'm trying to do it recursively. Essentially..these are all the sequences of numbers when combines will give some total..in this case 6. But notice how when the first number is 3, the set of numbers which follows is simply the set of sequences that gives a total of 3. In other words 6(target total) - 3 (first number) = 3 (set of sequences that give total of 3). Thus, should be able to do this recursively.

I tried to code as follows (and yes, this is my first language and yes, I've only been studying for about a week so I'm sure its all screwed up) but so far no luck. I think if I can just get the very core of the recursion working and put the values of all the objects to the screen so I can trace it line by line, I think I can move ahead, but between the logic and the syntax, I'm at a stand still.

My logic is:

  • define a method that passes 'count' representing the total being targeted.
  • create an array which is going to hold a given sequence of values
  • create an index which represents the position in the array (ignoring zero position).
  • define 'delta' and initialize it to the value of 'count' and have it represent the remaining target sum of the rest of the array. (since there is nothing in the array initially, the delta is the same as the count.)

Then, cycle through the possibilities for the next(first) value of the sequence starting from 1 and ending, obviously, with the maximum possible, which is the value of 'count' itself. Determine the new delta for each value in the cycle.

If the delta is 0, you are done otherwise determine this new sequence which will give this new delta. Likely need to append the new sequence to the current sequence as well.

i=0

    def seq(count)
        cvc=Array.new  # array to hold the number values
        i=i+1  # position index for the array
        puts 'i is ' + i.to_s
        delta=count 
        puts ' delta is ' + delta.to_s

        for value in 1..delta do  # value represents the number value
                cvc[i]=value
                puts 'cvc[i] is ' + cvc[i].to_s
                delta = delta-cvc.sum
                puts 'new delta is '+ delta.to_s
            if delta >1  then count=delta
                    seq(count)
            end
        end
    end

回答1:


Here's a solution:

def expand(n, max = n)
  return [[]] if n == 0
  [max, n].min.downto(1).flat_map do |i|
    expand(n-i, i).map{|rest| [i, *rest]}
  end
end

expand(6) # => [[6], [5, 1], [4, 2], [4, 1, 1], [3, 3], [3, 2, 1], [3, 1, 1, 1], [2, 2, 2], [2, 2, 1, 1], [2, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1]] 


来源:https://stackoverflow.com/questions/10889379/generating-unique-sorted-partitions-in-ruby

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!