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.
use strict;
use warnings;
use feature 'say';
 
my @bases = <A C G T>;
 
my $dna;
$dna .= $bases[int rand 4] for 1..200;
 
my %cnt;
$cnt{$_}++ for split //, $dna;
 
sub pretty {
    my($string) = @_;
    my $chunk = 10;
    my $wrap  = 5 * ($chunk+1);
    ($string =~ s/(.{$chunk})/$1 /gr) =~ s/(.{$wrap})/$1\n/gr;
}
 
sub mutate {
    my($dna,$count) = @_;
    my $orig = $dna;
    substr($dna,rand length $dna,1) = $bases[int rand 4] while $count > diff($orig, $dna) =~ tr/acgt//;
    $dna
}
 
sub diff {
    my($orig, $repl) = @_;
    for my $i (0 .. -1+length $orig) {
        substr($repl,$i,1, lc substr $repl,$i,1) if substr($orig,$i,1) ne substr($repl,$i,1);
    }
    $repl;
}
 
say "Original DNA strand:\n" . pretty($dna);
say "Total bases: ". length $dna;
say "$_: $cnt{$_}" for @bases;
 
my $mutate = mutate($dna, 10);
%cnt = ();
$cnt{$_}++ for split //, $mutate;
say "\nMutated DNA strand:\n" . pretty diff $dna, $mutate;
say "Total bases: ". length $mutate;
say "$_: $cnt{$_}" for @bases;
 