Генератор комбинации двоичных последовательностей, в рубине - PullRequest
0 голосов
/ 04 декабря 2011

Код работает, но чувствует себя очень грубо, предложения?

Цель кода - указать длину массива, а затем как можно быстрее сгенерировать все возможные уникальные двоичные комбинации с этой длиной массива.

КОД:

class Array
  def sequence(i = 0, *a)
    return [a] if i == size
    self[i].map {|x|
      sequence(i+1, *(a + [x]))
    }.inject([]) {|m, x| m + x}
  end
end


[(0..1),(0..1),(0..1)].sequence

ВЫХОДЫ:

[[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]

Ответы [ 2 ]

6 голосов
/ 04 декабря 2011

перестановка и repeat_permutation встроены, так что вы можете сделать:

def sequence(n)
  [0, 1].repeated_permutation(n).to_a
end
p sequence(3) #=>[[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]
2 голосов
/ 04 декабря 2011

«Все уникальные двоичные комбинации» с n битами - не что иное, как (0 ... 2 ** n), поэтому единственной задачей является эффективное преобразование целого числа в его двоичное представление, и следующее решение является не полагаться на генерацию / манипуляцию строк:

def sequence(n)
  ret = []
  (2**n).times do |number|
    ret << []
    (n - 1).downto(0) do |bit|
      ret.last << number[bit]
    end
  end

  ret
end

sequence(3) 
# => [[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]

Или, если вы предпочитаете версию, более ориентированную на операции со списком, это почти то же самое:

def sequence(n)
  (0...2**n).map {|number|
    (1..n).map {|bit|
      number[n-bit]
    }
  }
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...