ruby – 所有可能的条件排列

我想知道
Ruby中是否有一种优雅的方式来提出一些整数的所有排列(重复),其要求是1)引入的整数必须按从左到右的升序排列2)零不受此规则的约束.

下面,我有三位数的输出子集和整数0,1,2,3,4,5,6,7,8,9.这只是总答案的一个子集,特别是它是以5开头的子集.我已经在其中包含了几个注释.

500  - Zero is used twice
505  - 5 is used twice.  Note that 504 is not included because 5 was introduced on the left  and 4 < 5
506
507
508
509
550
555
556
557
558
559
560
565 - Though 5 < 6, 5 can be used twice because 5 was introduced to the left of 6.
566
567
568
569
570
575
577
578 
579
580
585
588
589
590
595
599

我需要能够以任意长的输出长度(不仅仅是3,像这个例子)来做,我需要能够为特定的整数集做到这一点.但是,零将始终是排序规则不适用的整数.

最佳答案 这可行:

class Foo
  include Comparable
  attr :digits

  def initialize(digits)
    @digits = digits.dup
  end

  def increment(i)
    if i == -1                     # [9,9] => [1,0,0]
      @digits.unshift 1
    else
      succ = @digits[i] + 1
      if succ == 10                # [8,9] => [9,0]
        @digits[i] = 0
        increment(i-1)
      else
        @digits[i] = @digits[0,i].sort.detect { |e| e >= succ } || succ
      end
    end
    self
  end

  def succ
    Foo.new(@digits).increment(@digits.length-1)
  end

  def <=>(other)
    @digits <=> other.digits
  end

  def to_s
    digits.join
  end

  def inspect
    to_s
  end

end

range = Foo.new([5,0,0])..Foo.new([5,9,9])
range.to_a
#=> [500, 505, 506, 507, 508, 509, 550, 555, 556, 557, 558, 559, 560, 565, 566, 567, 568, 569, 570, 575, 577, 578, 579, 580, 585, 588, 589, 590, 595, 599]

递增数字的主要规则是:

@digits[i] = @digits[0,i].sort.detect { |e| e >= succ } || succ

这会将剩余的数字排序到当前数字(“向左”引入的数字),并检测第一个等于或大于后继数的元素.如果找不到,则使用后继本身.

点赞