require 'spec_helper' module WeightedShuffle describe Dealer do describe '#weighted_shuffle' do [[ [[:a, 1], [:b, 2]], [:a, :b] ], [ [[1, 1], [2, 3]], [1, 2] ], [ [[2.0, 1], [:a, 1.5], ['a', 2.3]], [2.0, :a, 'a'] ]] .each do |input, output| it "returns a permutation of #{output} given #{input}" do output.permutation.to_a.should include( Dealer.new(input).weighted_shuffle) end it 'gives correct relative frequency for first position' do weights = input.map(&:last) # calculate probabiities sum = weights.sum probabilities = weights.map { |e| e.to_f / sum } # establish frequencies size = 1000 sample = size.times.map { Dealer.new(input).weighted_shuffle } frequencies = input.map(&:first) .map do |e| sample.select { |s| s.first == e }.count.to_f / size end # calculate sum of absolute values of differences diff = probabilities.zip(frequencies).map { |p,f| (p - f).abs }.sum diff.should < 0.1 end end end end end