Skip to content

Instantly share code, notes, and snippets.

@stevenpetryk
Created March 31, 2013 04:48
Show Gist options
  • Save stevenpetryk/5279588 to your computer and use it in GitHub Desktop.
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.
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