Created
March 31, 2013 04:48
-
-
Save stevenpetryk/5279588 to your computer and use it in GitHub Desktop.
This is just a nifty little script I wrote that will solve a Punnett square. I plan to make it into a full-featured gem that will be used a future project.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Geneticist | |
# The syntax is easy here. If you know how to set up a Punnett Square in real life, | |
# it's pretty self explanatory. | |
# | |
# # Checking for green eyes | |
# square = Geneticist::PunnettSquare.new('Gg', 'gg') | |
# square.result | |
# #=> {"Gg"=>2, "gg"=>2} | |
# | |
# # Checking a cross between a spider ball python and a pastel ball python | |
# square = Geneticist::PunnettSquare.new('Sspp', 'ssPp') | |
# square.result | |
# #=> {"PpSs"=>4, "ppSs"=>4, "Ppss"=>4, "ppss"=>4} | |
class PunnettSquare | |
attr_accessor :male, :female | |
attr_reader :offspring, :result | |
def initialize(male, female) | |
@male, @female = punnett_permute(male), punnett_permute(female) | |
@result = cross | |
end | |
private | |
def cross | |
@offspring = @male.map do |top_trait| | |
@female.map do |left_trait| | |
punnett_sort(top_trait + left_trait) | |
end | |
end.flatten | |
@offspring.inject(Hash.new(0)) { |h,v| h[v] += 1; h } | |
end | |
# Sorts string to the Punnett square standard | |
# | |
# punnett_sort('bBAAcC') # => 'AABbCc' | |
# | |
def punnett_sort(string) | |
string.split('').sort { |x, y| x.downcase <=> y.downcase }.each_slice(2).map { |a| a.sort.join }.join | |
end | |
# Rearranges arr to form the headers of a Punnett square | |
# | |
# punnett_permute('AaBb') # => ['AB', 'Ab', 'aB', 'ab'] | |
# | |
def punnett_permute(arr) | |
arr = arr.split('') if arr.kind_of? String | |
# I'm not even entirely sure how this works. | |
arr.permutation(arr.length/2).to_a.map(&:join).select do |permutation| | |
permutation.split('').each_with_index.select do |e, i| | |
# I mean what the hell is this I don't even | |
e.downcase == arr[((i+1)*2)-1].downcase | |
end.count == permutation.length | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment