class Array
 
        def each_group( group_length, &block )
 
                self.length.div(group_length).times do |i|
 
                        yield self [i * group_length .. (i + 1) * group_length - 1]
 
                end
 
        end
 
        
 
        def apply_hash( hsh )
 
                result = self.dup
 
                self.each_with_index do |element, index|
 
                        result [index] = hsh [element] if hsh.has_key?( element )
 
                end
 
                result
 
        end
 
end
 
 
 
class InformationMolecule
 
 
        attr_reader :sequence
 
 
        def initialize( sequence )
 
                @sequence = []
 
                if sequence.is_a?( String ) 
 
                        sequence.each_byte do |nt|
 
                                @sequence.push( nt.chr.upcase.to_sym )
 
                        end
 
                elsif sequence.is_a?( Array )
 
                        sequence.each do |nt|
 
                                @sequence.push( nt.to_s.upcase.to_sym )
 
                        end
 
                end
 
        end
 
        
 
        def each_codon( &block )
 
                @sequence.each_group( 3, &block )
 
        end
 
        
 
end
 
 
class DNA < InformationMolecule
 
 
        def initialize( sequence )
 
                super
 
                @@dna2dna = { :A => :T, :T => :A, :C => :G, :G => :C }
 
                @@dna2rna = { :A => :U, :T => :A, :C => :G, :G => :C }
 
        end
 
 
        def to_rna
 
                RNA.new( @sequence.apply_hash( @@dna2rna ) )
 
        end
 
        
 
        def to_cdna
 
                DNA.new( @sequence.apply_hash( @@dna2dna ) )
 
        end
 
 
end
 
 
class RNA < InformationMolecule
 
 
        def initialize( sequence )
 
                super
 
                @@rna2dna = { :A => :T, :U => :A, :C => :G, :G => :C }
 
                @@rna2rna = { :A => :U, :U => :A, :C => :G, :G => :C }
 
                @@genetic_code = {
 
                        :UUU => :f, :UUC => :f, :UUA => :l, :UUG => :l,
 
                        :UCU => :s, :UCC => :s, :UCA => :s, :UCG => :s,
 
                        :UAU => :y, :UAC => :y, :UAA => :STOP, :UAG => :STOP,
 
                        :UGU => :c, :UGC => :c, :UGA => :STOP, :UGG => :w,
 
                        :CUU => :l, :CUC => :l, :CUA => :l, :CUG => :l,
 
                        :CCU => :p, :CCC => :p, :CCA => :p, :CCG => :p,
 
                        :CAU => :h, :CAC => :h, :CAA => :q, :CAG => :q,
 
                        :CGU => :r, :CGC => :r, :CGA => :r, :CGG => :r,
 
                        :AUU => :i, :AUC => :i, :AUA => :i, :AUG => :m,
 
                        :ACU => :t, :ACC => :t, :ACA => :t, :ACG => :t,
 
                        :AAU => :n, :AAC => :n, :AAA => :k, :AAG => :k,
 
                        :AGU => :s, :AGC => :s, :AGA => :r, :AGG => :r,
 
                        :GUU => :v, :GUC => :v, :GUA => :v, :GUG => :v,
 
                        :GCU => :a, :GCC => :a, :GCA => :a, :GCG => :a,
 
                        :GAU => :d, :GAC => :d, :GAA => :e, :GAG => :e,
 
                        :GGU => :g, :GGC => :g, :GGA => :g, :GGG => :g
 
                }
 
        end
 
 
        def to_dna
 
                DNA.new( @sequence.apply_hash( @@rna2dna ) )
 
        end
 
        
 
        def to_crna
 
                RNA.new( @sequence.apply_hash( @@rna2rna ) )
 
        end
 
        
 
        def to_protein
 
                aa_sequence = []
 
                self.each_codon do |codon|
 
                        aa = @@genetic_code [codon.join.to_sym]
 
                        break if aa == :STOP
 
                        aa_sequence.push( aa )
 
                end
 
                Protein.new( aa_sequence )
 
        end
 
 
end
 
 
class Protein
 
 
        attr_reader :sequence
 
        attr_reader :full_name_sequence
 
 
        def initialize( aa_sequence )
 
                @sequence = []
 
                if aa_sequence.is_a?( String ) 
 
                        aa_sequence.each_byte do |aa|
 
                                @sequence.push( aa.chr.upcase.to_sym )
 
                        end
 
                elsif aa_sequence.is_a?( Array )
 
                        aa_sequence.each do |aa|
 
                                @sequence.push( aa.to_sym )
 
                        end
 
                end
 
                @@aa_code = {
 
                        :f => :Phenylalanine,
 
                        :l => :Leucine,
 
                        :i => :Isoleucine,
 
                        :m => :Methionine,
 
                        :v => :Valine,
 
                        :s => :Serine,
 
                        :p => :Proline,
 
                        :t => :Threonine,
 
                        :a => :Alanine,
 
                        :y => :Tyrosine,
 
                        :h => :Histidine,
 
                        :q => :Glutamine,
 
                        :n => :Asparagine,
 
                        :k => :Lysine,
 
                        :d => :"Aspartic acid",
 
                        :e => :"Glutamic acid",
 
                        :c => :Cysteine,
 
                        :w => :Tryptophan,
 
                        :r => :Arginine,
 
                        :g => :Glycine
 
                }
 
                @full_name_sequence = @sequence.apply_hash( @@aa_code )
 
        end
 
 
end
 
 
#nt = ""
 
#File.open( "nt sequence.txt").each { |line| nt += line.chomp }
 
#File.open( "aa sequence.txt", "w" ).puts( DNA.new( nt ).to_rna.to_protein.full_name_sequence )
 
 
puts DNA.new( "gattacctcggguuu" ).to_rna.to_protein.full_name_sequence
 
  |