97 lines
2.9 KiB
Plaintext
97 lines
2.9 KiB
Plaintext
use rand::prelude::*;
|
|
use std::collections::HashMap;
|
|
use std::fmt::{Display, Formatter, Error};
|
|
|
|
pub struct Seq<'a> {
|
|
alphabet: Vec<&'a str>,
|
|
distr: rand::distributions::Uniform<usize>,
|
|
pos_distr: rand::distributions::Uniform<usize>,
|
|
seq: Vec<&'a str>,
|
|
}
|
|
|
|
impl Display for Seq<'_> {
|
|
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
|
|
|
let pretty: String = self.seq
|
|
.iter()
|
|
.enumerate()
|
|
.map(|(i, nt)| if (i + 1) % 60 == 0 { format!("{}\n", nt) } else { nt.to_string() })
|
|
.collect();
|
|
|
|
let counts_hm = self.seq
|
|
.iter()
|
|
.fold(HashMap::<&str, usize>::new(), |mut m, nt| {
|
|
*m.entry(nt).or_default() += 1;
|
|
m
|
|
});
|
|
|
|
let mut counts_vec: Vec<(&str, usize)> = counts_hm.into_iter().collect();
|
|
counts_vec.sort_by(|a, b| a.0.cmp(&b.0));
|
|
let counts_string = counts_vec
|
|
.iter()
|
|
.fold(String::new(), |mut counts_string, (nt, count)| {
|
|
counts_string += &format!("{} = {}\n", nt, count);
|
|
counts_string
|
|
});
|
|
|
|
write!(f, "Seq:\n{}\n\nLength: {}\n\nCounts:\n{}", pretty, self.seq.len(), counts_string)
|
|
}
|
|
}
|
|
|
|
impl Seq<'_> {
|
|
pub fn new(alphabet: Vec<&str>, len: usize) -> Seq {
|
|
let distr = rand::distributions::Uniform::new_inclusive(0, alphabet.len() - 1);
|
|
let pos_distr = rand::distributions::Uniform::new_inclusive(0, len - 1);
|
|
|
|
let seq: Vec<&str> = (0..len)
|
|
.map(|_| {
|
|
alphabet[thread_rng().sample(distr)]
|
|
})
|
|
.collect();
|
|
Seq { alphabet, distr, pos_distr, seq }
|
|
}
|
|
|
|
pub fn insert(&mut self) {
|
|
let pos = thread_rng().sample(self.pos_distr);
|
|
let nt = self.alphabet[thread_rng().sample(self.distr)];
|
|
println!("Inserting {} at position {}", nt, pos);
|
|
self.seq.insert(pos, nt);
|
|
}
|
|
|
|
pub fn delete(&mut self) {
|
|
let pos = thread_rng().sample(self.pos_distr);
|
|
println!("Deleting {} at position {}", self.seq[pos], pos);
|
|
self.seq.remove(pos);
|
|
}
|
|
|
|
pub fn swap(&mut self) {
|
|
let pos = thread_rng().sample(self.pos_distr);
|
|
let cur_nt = self.seq[pos];
|
|
let new_nt = self.alphabet[thread_rng().sample(self.distr)];
|
|
println!("Replacing {} at position {} with {}", cur_nt, pos, new_nt);
|
|
self.seq[pos] = new_nt;
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
|
|
let mut seq = Seq::new(vec!["A", "C", "T", "G"], 200);
|
|
println!("Initial sequnce:\n{}", seq);
|
|
|
|
let mut_distr = rand::distributions::Uniform::new_inclusive(0, 2);
|
|
|
|
for _ in 0..10 {
|
|
let mutation = thread_rng().sample(mut_distr);
|
|
|
|
if mutation == 0 {
|
|
seq.insert()
|
|
} else if mutation == 1 {
|
|
seq.delete()
|
|
} else {
|
|
seq.swap()
|
|
}
|
|
}
|
|
|
|
println!("\nMutated sequence:\n{}", seq);
|
|
}
|