93 lines
2.3 KiB
V
93 lines
2.3 KiB
V
import rand
|
|
import rand.seed
|
|
|
|
const bases = "ACGT"
|
|
|
|
// 'w' contains the weights out of 300 for each
|
|
// of swap, delete or insert in that order.
|
|
fn mutate(dna string, w [3]int) string {
|
|
le := dna.len
|
|
// get a random position in the dna to mutate
|
|
p := rand.intn(le) or {0}
|
|
// get a random number between 0 and 299 inclusive
|
|
r := rand.intn(300) or {0}
|
|
mut bytes := dna.bytes()
|
|
match true {
|
|
r < w[0] { // swap
|
|
base := bases[rand.intn(4) or {0}]
|
|
println(" Change @${p:3} ${[bytes[p]].bytestr()} to ${[base].bytestr()}")
|
|
bytes[p] = base
|
|
}
|
|
r < w[0]+w[1] { // delete
|
|
println(" Delete @${p:3} ${bytes[p]}")
|
|
bytes.delete(p)
|
|
//copy(bytes[p:], bytes[p+1:])
|
|
bytes = bytes[0..le-1]
|
|
}
|
|
else { // insert
|
|
base := bases[rand.intn(4) or {0}]
|
|
bytes << 0
|
|
bytes.insert(p,bytes[p])
|
|
//copy(bytes[p+1:], bytes[p:])
|
|
println(" Insert @${p:3} $base")
|
|
bytes[p] = base
|
|
}
|
|
}
|
|
return bytes.bytestr()
|
|
}
|
|
|
|
// Generate a random dna sequence of given length.
|
|
fn generate(le int) string {
|
|
mut bytes := []u8{len:le}
|
|
for i := 0; i < le; i++ {
|
|
bytes[i] = bases[rand.intn(4) or {0}]
|
|
}
|
|
return bytes.bytestr()
|
|
}
|
|
|
|
// Pretty print dna and stats.
|
|
fn pretty_print(dna string, rowLen int) {
|
|
println("SEQUENCE:")
|
|
le := dna.len
|
|
for i := 0; i < le; i += rowLen {
|
|
mut k := i + rowLen
|
|
if k > le {
|
|
k = le
|
|
}
|
|
println("${i:5}: ${dna[i..k]}")
|
|
}
|
|
mut base_map := map[byte]int{} // allows for 'any' base
|
|
for i in 0..le {
|
|
base_map[dna[i]]++
|
|
}
|
|
mut bb := base_map.keys()
|
|
bb.sort()
|
|
|
|
println("\nBASE COUNT:")
|
|
for base in bb {
|
|
println(" $base: ${base_map[base]:3}")
|
|
}
|
|
println(" ------")
|
|
println(" Σ: $le")
|
|
println(" ======\n")
|
|
}
|
|
|
|
// Express weights as a string.
|
|
fn wstring(w [3]int) string {
|
|
return " Change: ${w[0]}\n Delete: ${w[1]}\n Insert: ${w[2]}\n"
|
|
}
|
|
|
|
fn main() {
|
|
rand.seed(seed.time_seed_array(2))
|
|
mut dna := generate(250)
|
|
pretty_print(dna, 50)
|
|
muts := 10
|
|
w := [100, 100, 100]! // use e.g. {0, 300, 0} to choose only deletions
|
|
println("WEIGHTS (ex 300):\n${wstring(w)}")
|
|
println("MUTATIONS ($muts):")
|
|
for _ in 0..muts {
|
|
dna = mutate(dna, w)
|
|
}
|
|
println('')
|
|
pretty_print(dna, 50)
|
|
}
|