public
Last active

Ruby program to simulate coin tosses until a selected pattern is matched. Two distinct patterns are examined and compared statistically.

  • Download Gist
coins.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
#!/usr/bin/env ruby
# coins.rb
# count average flips until HTH is reached
#
 
def flip ; rand(2) == 1 ? 'H' : 'T' ; end
 
# 'HTH'.count_flips
 
class String
def count_flips
target = self.to_s
src = ''
count = 0
while (target != src) # loop until we match the target
src += flip # append new toss
count += 1 # count flips
src.slice!(0,1) if src.size > target.size
end
count # return flip count
end
end
 
# Enumerable didn't include this -- why?
class Array
def sum
self.reduce(:+)
end
def average
Float(self.sum) / self.nitems
end
end
 
# average_flips
#
# count coin flips until a target is reached
# do this repeated for a day, then average those counts.
#
# Simulate human-speed coin flips by estimating time for each flip, and
# assuming constant flipping for 24 hours, without a break.
 
$flip_time = 4 # 4 seconds per flip
$max_flips_per_day = 24 * 60 * 60 / $flip_time
 
class String
def flip_stats
target = self
 
counts = []
(1..$max_flips_per_day).each{|i| counts += [target.count_flips]}
min_count, max_count = counts.minmax
average_count = counts.average
[min_count, max_count, average_count]
end
end
 
['HTH', 'HTT'].each {|target|
puts "Computing #{target} stats.." if $DEBUG
(min, max, avg) = target.flip_stats
printf "Target: %s Coin flip stats: min: %4.1f max: %5.1f avg: %5.1f\n", target, min, max, avg
}
exit

Sample output:

$ ./coins.rb 
Target: HTH  Coin flip stats: min:  3.0  max:  69.0  avg:  10.0
Target: HTT  Coin flip stats: min:  3.0  max:  53.0  avg:   8.0

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.