Task

Given a string of characters A, C, G, and T representing a DNA sequence write a routine to mutate the sequence, (string) by:

 Choosing a random base position in the sequence.
 Mutate the sequence by doing one of either:
 Swap the base at that position by changing it to one of A, C, G, or T. (which has a chance of swapping the base for the same base)
 Delete the chosen base at the position.
 Insert another base randomly chosen from A,C, G, or T into the sequence at that position.
 Randomly generate a test DNA sequence of at least 200 bases
 "Pretty print" the sequence and a count of its size, and the count of each base in the sequence
 Mutate the sequence ten times.
 "Pretty print" the sequence after all mutations, and a count of its size, and the count of each base in the sequence.
Extra credit

 Give more information on the individual mutations applied.
 Allow mutations to be weighted and/or chosen.
#BASE$="ACGT"
#SEQLEN=200
#PROTOCOL=#True
 
Global dna.s
Define i.i
 
Procedure pprint()
  Define p.i, cnt.i, sum.i
 
  For p=1 To Len(dna) Step 50
    Print(RSet(Str(p-1)+": ",5))
    PrintN(Mid(dna,p,50))
  Next  
  PrintN("Base counts:")
  For p=1 To 4
    cnt=CountString(dna,Mid(#BASE$,p,1)) : sum+cnt
    Print(Mid(#BASE$,p,1)+": "+Str(cnt)+", ")
  Next
  PrintN("Total: "+Str(sum))  
EndProcedure
 
Procedure InsertAtPos(basenr.i,position.i)  
  If #PROTOCOL : PrintN("Insert base "+Mid(#BASE$,basenr,1)+" at position "+Str(position)) : EndIf
  dna=InsertString(dna,Mid(#BASE$,basenr,1),position)
EndProcedure
 
Procedure EraseAtPos(position.i)
  If #PROTOCOL : PrintN("Erase base "+Mid(dna,position,1)+" at position "+Str(position)) : EndIf
  If position>0 And position<=Len(dna)
    dna=Left(dna,position-1)+Right(dna,Len(dna)-position)
  EndIf  
EndProcedure
 
Procedure OverwriteAtPos(basenr.i,position.i) 
  If #PROTOCOL : PrintN("Change base at position "+Str(position)+" from "+Mid(dna,position,1)+" to "+Mid(#BASE$,basenr,1)) : EndIf
  If position>0 And position<=Len(dna)
    position-1
    PokeS(@dna+2*position,Mid(#BASE$,basenr,1),-1,#PB_String_NoZero)  
  EndIf  
EndProcedure
 
If OpenConsole()=0 : End 1 : EndIf
For i=1 To #SEQLEN : dna+Mid(#BASE$,Random(4,1),1) : Next
PrintN("Initial sequence:")
pprint()
 
For i=1 To 10
  Select Random(2)
    Case 0 : InsertAtPos(Random(4,1),Random(Len(dna),1))
    Case 1 : EraseAtPos(Random(Len(dna),1))
    Case 2 : OverwriteAtPos(Random(4,1),Random(Len(dna),1))
  EndSelect
Next
 
PrintN("After 10 mutations:")
pprint()
Input()