Skip to content

Instantly share code, notes, and snippets.

@ianterrell
Created May 26, 2009 18:05
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ianterrell/118194 to your computer and use it in GitHub Desktop.
Save ianterrell/118194 to your computer and use it in GitHub Desktop.
class Fairish
def initialize(probability, unfair_low, unfair_high, min_rolls)
@probability, @unfair_low, @unfair_high, @min_rolls = probability, unfair_low, unfair_high, min_rolls
@rolls, @hits = 0, 0
end
def fire!
hit = if @rolls >= @min_rolls && observed_probability > @unfair_high
false
elsif @rolls >= @min_rolls && observed_probability < @unfair_low
true
else
rand <= @probability
end
@hits += 1 if hit
@rolls += 1
return hit
end
private
def observed_probability
@hits.to_f / @rolls
end
end
class Random
def initialize(probability)
@probability = probability
end
def fire!
rand <= @probability
end
end
trials = 100000
trial_size = 10
random_out_of_bounds_low = 0
random_out_of_bounds_high = 0
fairish_out_of_bounds_low = 0
fairish_out_of_bounds_high = 0
probability = 0.2
lower_bound = 0.1
upper_bound = 0.4
min_rolls = trial_size / 2
trials.times do |n|
fairish = Fairish.new probability, lower_bound, upper_bound, min_rolls
fairish_hits = 0
random = Random.new probability
random_hits = 0
trial_size.times do |x|
fairish_hits += 1 if fairish.fire!
random_hits += 1 if random.fire!
end
fairish_out_of_bounds_low += 1 if fairish_hits.to_f / trial_size < lower_bound
fairish_out_of_bounds_high += 1 if fairish_hits.to_f / trial_size > upper_bound
random_out_of_bounds_low += 1 if random_hits.to_f / trial_size < lower_bound
random_out_of_bounds_high += 1 if random_hits.to_f / trial_size > upper_bound
end
puts "Fairish was out of bounds #{(fairish_out_of_bounds_low + fairish_out_of_bounds_high).to_f/trials * 100}% of the time (#{fairish_out_of_bounds_low.to_f/trials * 100}% low and #{fairish_out_of_bounds_high.to_f/trials * 100}% high)."
puts "Random was out of bounds #{(random_out_of_bounds_low + random_out_of_bounds_high).to_f/trials * 100}% of the time (#{random_out_of_bounds_low.to_f/trials * 100}% low and #{random_out_of_bounds_high.to_f/trials * 100}% high)."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment