78 lines
2.2 KiB
Text
78 lines
2.2 KiB
Text
import "random" for Random
|
|
import "./fmt" for Fmt
|
|
import "./sort" for Sort
|
|
|
|
var rand = Random.new()
|
|
var bases = "ACGT"
|
|
|
|
// 'w' contains the weights out of 300 for each
|
|
// of swap, delete or insert in that order.
|
|
var mutate = Fn.new { |dna, w|
|
|
var le = dna.count
|
|
// get a random position in the dna to mutate
|
|
var p = rand.int(le)
|
|
// get a random number between 0 and 299 inclusive
|
|
var r = rand.int(300)
|
|
var chars = dna.toList
|
|
if (r < w[0]) { // swap
|
|
var base = bases[rand.int(4)]
|
|
Fmt.print(" Change @$3d $q to $q", p, chars[p], base)
|
|
chars[p] = base
|
|
} else if (r < w[0] + w[1]) { // delete
|
|
Fmt.print(" Delete @$3d $q", p, chars[p])
|
|
chars.removeAt(p)
|
|
} else { // insert
|
|
var base = bases[rand.int(4)]
|
|
Fmt.print(" Insert @$3d $q", p, base)
|
|
chars.insert(p, base)
|
|
}
|
|
return chars.join()
|
|
}
|
|
|
|
// Generate a random dna sequence of given length.
|
|
var generate = Fn.new { |le|
|
|
var chars = [""] * le
|
|
for (i in 0...le) chars[i] = bases[rand.int(4)]
|
|
return chars.join()
|
|
}
|
|
|
|
// Pretty print dna and stats.
|
|
var prettyPrint = Fn.new { |dna, rowLen|
|
|
System.print("SEQUENCE:")
|
|
var le = dna.count
|
|
var i = 0
|
|
while (i < le) {
|
|
var k = i + rowLen
|
|
if (k > le) k = le
|
|
Fmt.print("$5d: $s", i, dna[i...k])
|
|
i = i + rowLen
|
|
}
|
|
var baseMap = {}
|
|
for (i in 0...le) {
|
|
var v = baseMap[dna[i]]
|
|
baseMap[dna[i]] = (v) ? v + 1 : 1
|
|
}
|
|
var bases = []
|
|
for (k in baseMap.keys) bases.add(k)
|
|
Sort.insertion(bases) // get bases into alphabetic order
|
|
System.print("\nBASE COUNT:")
|
|
for (base in bases) Fmt.print(" $s: $3d", base, baseMap[base])
|
|
System.print(" ------")
|
|
System.print(" Σ: %(le)")
|
|
System.print(" ======\n")
|
|
}
|
|
|
|
// Express weights as a string.
|
|
var wstring = Fn.new { |w|
|
|
return Fmt.swrite(" Change: $d\n Delete: $d\n Insert: $d\n", w[0], w[1], w[2])
|
|
}
|
|
|
|
var dna = generate.call(250)
|
|
prettyPrint.call(dna, 50)
|
|
var muts = 10
|
|
var w = [100, 100, 100] // use e.g. {0, 300, 0} to choose only deletions
|
|
Fmt.print("WEIGHTS (ex 300):\n$s", wstring.call(w))
|
|
Fmt.print("MUTATIONS ($d):", muts)
|
|
for (i in 0...muts) dna = mutate.call(dna, w)
|
|
System.print()
|
|
prettyPrint.call(dna, 50)
|