Генератор взвешенных писем - PullRequest
0 голосов
/ 05 февраля 2019

Я работаю над программой, которая создает смешанные группы букв, для этого я создаю 2 взвешенных генератора букв, один для согласных, один для гласных.

В настоящее время у меня есть генератор взвешенных чисел, использующий хэши для взвешивания, и я могу вызвать функцию выбора букв с количеством букв, которые я хочу вернуть (например, pick_vowel (3))

def pick_vowel(x)
  vowels = { A: 15, E: 21, I: 13, O: 13, U: 5 }
  v_choice = []
  vowels.map {|letter, number| number.times {v_choice << letter}}
  x.times {print v_choice.shuffle!.pop}
end

Идея состоит в том, чтобы затем передать полученную строку в функцию, которая дает все возможные комбинации определенной длины, используя следующий код:

def solver(vowel)
  puts (2..9).flat_map{|size| board.combination(size).map(&:join)}
end

, но когда я передаю строку, я получаю следующеесообщение об ошибке (в данном случае x = 6):

in `block in solver': undefined method `combination' for 6:Integer (NoMethodError)

Я хочу преобразовать выходную строку в массив, но, насколько я могу судить, в выходной строке есть целое число, поэтомуметод массива не будет применяться к нему.

Как запретить выводу содержать целое число в конце?

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Предположим,

vowels = { A: 5, E: 8, I: 4, O: 7, U: 3, Y: 1 }

Я понимаю, что значения этого хэша являются весами отрисовки связанных ключей.Сначала вы строите (по-другому):

v_choice = vowels.flat_map { |k,v| [k]*v }
  #=> [:A, :A, :A, :A, :A,
  #    :E, :E, :E, :E, :E, :E, :E, :E,
  #    :I, :I, :I, :I,
  #    :O, :O, :O, :O, :O, :O, :O,
  #    :U, :U, :U,
  #    :Y] 

Затем вы выполняете

x.times {print v_choice.shuffle!.pop}    

Предположим, что первый случай перемешивания производит следующее:

v_choice
  #=> [:O, :O, :E, :U, :U, :O, :A, :E, :E, :E, :U, :I, :A, :I,
  #    :E, :A, :O, :O, :E, :E, :O, :A, :I, :A, :O, :E, :I, :Y] 

, а затем

print v_choice.pop

печатает "Y" и удаляет только :Y из v_choice.Следовательно, (с вероятностью 1) :Y будет отображаться случайным образом не более, что противоречит тому факту, что оно имеет положительный вес.

Если значения vowels являются не весами, а числами в конечном набореиз гласных можно сильно упростить.После вычисления v_choice нужно только написать

puts v_choice.sample(x).join
  # EOOYEIIEOI

или

puts v_choice.shuffle[0,x].join
  # EOOUOEEIAE

Теперь давайте предположим, что значения vowels действительно являются весами.Тогда нам нужно только написать

x = 10
x.times { print v_choice.sample }
# OAEYEUAOAO

Если значения vowels велики, v_choice соответственно велика.Это повлияет на требования к памяти, но не на скорость выполнения.Если бы требования к памяти были дорогими (вряд ли, возможно), можно было бы сделать следующее.

tot_wts = vowels.values.sum.to_f
  #=> 28.0
cum = 0
cum_dist = vowels.map do |v,wt|
  cum_wt = cum + wt/tot_wts
  cum = cum_wt
  [v, cum_wt]
end
  #=> [[:A, 0.17857142857142858],
  #    [:E, 0.4642857142857143],
  #    [:I, 0.6071428571428572],
  #    [:O, 0.8571428571428572],
  #    [:U, 0.9642857142857143],
  #    [:Y, 1.0]]

В случае ошибки округления мы могли бы установить

cum_dist[-1][-1] = 1.0

Затем мы можем произвеститаким образом, взвешенная выборка.

x = 10
x.times do
  rn = rand
  print cum_dist.find { |_,cum| rn < cum }.first
end
# EAAOOEEIOA

Обратите внимание, что мы не можем записать

print cum_dist.find { |_,cum| rand < cum }.first

, потому что значение, возвращаемое rand, будет постоянно меняться в блоке find.

Этот метод, так называемый «метод обратного преобразования», обычно используется для генерации дискретных случайных величин в имитационных моделях.

0 голосов
/ 05 февраля 2019

Проблема здесь:

x.times {print v_choice.shuffle!.pop}

Выше напечатано значение x раз, а возвращает значение x.Вот как работает Integer#times.

Вместо этого вам нужно:

x.times.map { v_choice.shuffle!.pop }

Или, лучше,

v_choice.shuffle!.pop(x)

, поскольку Array#pop принимает аргумент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...