I haven't been programming for a while, I wanted to do a simple project to warm myself up and get back into the game; I made this simple tool that finds the probabilities of coin toss combinations. Enter a number to get all combinations with that many flips, or enter a string to search for that combination, i.e. H**H
would find all combinations starting and ending with heads.
module Every
def every(&block)
arys = map do |ary|
base_ary = eval ary.inspect.split(':')[1] rescue nil
base_ary.nil? ? ary : base_ary
end
longest = arys.max_by(&:count).count
arys.map!.with_index do |ary, i|
cyc = ary * ( longest / ary.count + 1 )
self[i].is_a?(Enumerator) ? cyc[0...longest] : ary
end
arys.transpose.each &block
end
end
class Array
# I didn't have to use this module, but I had written it in the past
# and this seemed like a good place to use it
include Every
end
class CoinToss
attr_accessor :outcomes, :reference, :iterations, :combins, :occrs
def initialize(outcomes = ["H", "T"], reference = gets.chomp.upcase)
@outcomes = outcomes.each &:to_s
if (Integer reference rescue false)
@iterations = reference.to_i
@reference = "*" * @iterations
else
set = @outcomes.join("*")
raise ArgumentError, "Invalid Characters" unless reference =~ /\A[#{set}]+\z/
@reference = reference
@iterations = @reference.length
end
@combins = @outcomes.repeated_permutation(@iterations).to_a
@occrs = 0
ref = [@reference.chars]
# every loop ref is repeated but combins is iterated
[ref.cycle, @combins].every do |r, c|
# replaces `*` in ref with regex string for characters from `outcomes`
@template = r.join.gsub "*", "[#{@outcomes.join}]"
@occrs += 1 unless !(c.join =~ /#{@template}/) # +1 if it matches the template
end
end
def get_combins(match_marker = "~")
@combins.each do |c|
# m is blank if combin doesn't match the template
m = !(c.join =~ /#{@template}/) ? "" : match_marker
line = Array c.join
# skips marker when reference contains only `*`
line << m unless @reference.chars.all? { |r| r == "*" }
puts line.join(" ")
end
end
def get_probability(rationalize = true, match_word = "out of")
puts Rational(occrs, combins.length) if rationalize
puts [@occrs, match_word, @combins.length].join(" ") unless rationalize
end
end
tosses = CoinToss.new
tosses.get_combins
tosses.get_probability(rationalize = false)
tosses.get_probability(rationalize = true)
Thanks for any advice.