Ruby program to simulate coin tosses until a selected pattern is matched. Two distinct patterns are examined and compared statistically.
#!/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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Sample output: