'A' => 1, 'G' => 2, 'AG' => 1, 'GG' => 1, 'AGG' => 1, #### use warnings; use strict; open GENE, '<', '\test.txt' or die("Unable to read: $!"); my @rolling = (undef, undef, undef); my %count; my $cnt; until (eof GENE) { my $char; read(GENE,$char,1); next unless $char=~/[AGCT]/; #make sure it's a valid char; shift @rolling; push @rolling, $char; next unless defined $rolling[2]; $count{$rolling[2]}++; #one-char count next unless defined $rolling[1]; $count{join('',@rolling[1,2])}++; #two-char count next unless defined $rolling[0]; $count{join('',@rolling)}++; #three-char count } #### my @chars = qw[A C G T]; for my $aleph (0..$#chars) { $count{$aleph}=0; for my $beth (0..$#chars) { $count{$aleph.$beth}=0; for my $gimal (0..$#chars) { $count{$aleph.$beth.$gimal}=0; } } } #### 60 wallclock secs (59.19 usr + 0.03 sys = 59.22 CPU) @ 0.02/s (n=1) #### for ( reverse(0..$#rolling) ) { next unless defined $_-@rolling; $count{join('',@rolling[$_-@rolling,-1])}++; }