Last active
November 29, 2022 18:46
-
-
Save eminarican/1df79932a6127e6fddf64b2d4bee80db to your computer and use it in GitHub Desktop.
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
pub enum Pentose { | |
Ribose, | |
Deoxyribose | |
} | |
pub enum OrganicBase { | |
Uracil, | |
Adenine, | |
Thymine, | |
Guanine, | |
Cytosine | |
} | |
use std::{ | |
io::*,fmt::*,time::*, | |
thread::*,process::* | |
}; | |
impl OrganicBase { | |
pub fn from(kind: char) -> Self { | |
use OrganicBase::*; | |
match kind { | |
'u' => Uracil, | |
'a' => Adenine, | |
't' => Thymine, | |
'g' => Guanine, | |
'c' => Cytosine, | |
_ => { | |
println!("invalid kind of organic base detected: '{}'", kind); | |
exit(1) | |
} | |
} | |
} | |
} | |
pub struct NucleicAcidChain { | |
pub kind: Pentose, | |
pub chain: Vec<Codon> | |
} | |
impl NucleicAcidChain { | |
pub fn new(kind: Pentose) -> Self { | |
NucleicAcidChain { | |
kind, | |
chain: vec![] | |
} | |
} | |
} | |
pub type Codon = (OrganicBase, OrganicBase, OrganicBase); | |
pub type Protein = Vec<CodonKind>; | |
fn main() { | |
let data = read_line(); | |
println!("creating new dna chain..."); | |
sleep(Duration::new(1,0)); | |
let dna = read_dna(data); | |
println!("transcrypting dna into rna..."); | |
sleep(Duration::new(1,0)); | |
let rna = transcrypt_dna(dna); | |
println!("translating rna into protein..."); | |
sleep(Duration::new(1,0)); | |
let protein = translate_rna(rna); | |
println!("protein chain content:"); | |
for amino_acid in protein { | |
println!("{}", amino_acid) | |
} | |
} | |
fn read_line() -> String { | |
let mut data = String::new(); | |
stdin().lock().read_line(&mut data).unwrap(); | |
data.replace("\n", "") | |
} | |
fn read_dna(data: String) -> NucleicAcidChain { | |
let len = data.len(); | |
if (len < 6) | (len % 3 != 0) { | |
println!("data should have a correct encoding for codon groups"); | |
exit(1) | |
} | |
let mut dna = NucleicAcidChain::new(Pentose::Deoxyribose); | |
let bytes = data.as_bytes(); | |
for x in 0..len/3 { | |
dna.chain.push(( | |
OrganicBase::from(bytes[3*x] as char), | |
OrganicBase::from(bytes[3*x+1] as char), | |
OrganicBase::from(bytes[3*x+2] as char), | |
)) | |
} | |
dna | |
} | |
fn transcrypt_dna(dna: NucleicAcidChain) -> NucleicAcidChain { | |
let mut rna = NucleicAcidChain::new(Pentose::Ribose); | |
let f = |kind: OrganicBase| { | |
use OrganicBase::*; | |
match kind { | |
Adenine => Uracil, | |
Thymine => Adenine, | |
Guanine => Cytosine, | |
Cytosine => Guanine, | |
Uracil => { | |
println!("uracil can't exist on dna"); | |
exit(1) | |
}, | |
} | |
}; | |
for x in dna.chain { | |
rna.chain.push((f(x.0), f(x.1), f(x.2))) | |
} | |
rna | |
} | |
fn translate_rna(rna: NucleicAcidChain) -> Protein { | |
let mut protein = Protein::new(); | |
for codon in rna.chain { | |
let kind = CodonKind::from(codon); | |
if kind != CodonKind::End { | |
protein.push(kind) | |
} | |
} | |
protein | |
} | |
#[derive(PartialEq)] | |
pub enum CodonKind { | |
End, | |
Ala, | |
Arg, | |
Asn, | |
Asp, | |
Cys, | |
Gln, | |
Glu, | |
Gly, | |
His, | |
Ile, | |
Leu, | |
Lys, | |
Met, | |
Phe, | |
Pro, | |
Ser, | |
Thr, | |
Trp, | |
Tyr, | |
Val, | |
} | |
impl CodonKind { | |
pub fn from(codon: Codon) -> Self { | |
use CodonKind::*; | |
use OrganicBase::{ | |
Uracil as U, | |
Adenine as A, | |
Guanine as G, | |
Cytosine as C, | |
}; | |
match codon { | |
(A,U,G) => Met, | |
(U,G,G) => Trp, | |
(A,A,U)|(A,A,C) => Asn, | |
(G,A,U)|(G,A,C) => Asp, | |
(U,G,U)|(U,G,C) => Cys, | |
(C,A,A)|(C,A,G) => Gln, | |
(G,A,A)|(G,A,G) => Glu, | |
(C,A,U)|(C,A,C) => His, | |
(A,A,A)|(A,A,G) => Lys, | |
(U,U,U)|(U,U,C) => Phe, | |
(U,A,U)|(U,A,C) => Tyr, | |
(U,A,A)|(U,A,G)|(U,G,A) => End, | |
(A,U,U)|(A,U,C)|(A,U,A) => Ile, | |
(G,C,U)|(G,C,C)|(G,C,A)|(G,C,G) => Ala, | |
(G,G,U)|(G,G,C)|(G,G,A)|(G,G,G) => Gly, | |
(C,C,U)|(C,C,C)|(C,C,A)|(C,C,G) => Pro, | |
(A,C,U)|(A,C,C)|(A,C,A)|(A,C,G) => Thr, | |
(G,U,U)|(G,U,C)|(G,U,A)|(G,U,G) => Val, | |
(C,G,U)|(C,G,C)|(C,G,A)|(C,G,G)|(A,G,A)|(A,G,G) => Arg, | |
(U,U,A)|(U,U,G)|(C,U,U)|(C,U,C)|(C,U,A)|(C,U,G) => Leu, | |
(U,C,U)|(U,C,C)|(U,C,A)|(U,C,G)|(A,G,U)|(A,G,C) => Ser, | |
_ => { | |
println!("this shouldn't happen"); | |
exit(1) | |
} | |
} | |
} | |
} | |
impl Display for CodonKind { | |
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | |
use CodonKind::*; | |
match self { | |
End => write!(f, "Stop"), | |
Ala => write!(f, "Alanine"), | |
Arg => write!(f, "Arginine"), | |
Asn => write!(f, "Asparagine"), | |
Asp => write!(f, "Aspartate"), | |
Cys => write!(f, "Cysteine"), | |
Gln => write!(f, "Glutamine"), | |
Glu => write!(f, "Glutamate"), | |
Gly => write!(f, "Glycine"), | |
His => write!(f, "Histidine"), | |
Ile => write!(f, "Isoleucine"), | |
Leu => write!(f, "Leucine"), | |
Lys => write!(f, "Lysine"), | |
Met => write!(f, "Methionine"), | |
Phe => write!(f, "Phenylalanine"), | |
Pro => write!(f, "Proline"), | |
Ser => write!(f, "Serine"), | |
Thr => write!(f, "Threonine"), | |
Trp => write!(f, "Tryptophan"), | |
Tyr => write!(f, "Tyrosine"), | |
Val => write!(f, "Valine"), | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment