| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Acme::DoubleHelix; | 
| 2 |  |  |  |  |  |  | our $VERSION = '0.01'; | 
| 3 |  |  |  |  |  |  |  | 
| 4 |  |  |  |  |  |  | my $promoter =' | 
| 5 |  |  |  |  |  |  | CG | 
| 6 |  |  |  |  |  |  | T--A | 
| 7 |  |  |  |  |  |  | A---T | 
| 8 |  |  |  |  |  |  | A----T | 
| 9 |  |  |  |  |  |  | C----G | 
| 10 |  |  |  |  |  |  | T----A | 
| 11 |  |  |  |  |  |  | A---T | 
| 12 |  |  |  |  |  |  | G--C | 
| 13 |  |  |  |  |  |  | AT | 
| 14 |  |  |  |  |  |  | CG | 
| 15 |  |  |  |  |  |  | C--G | 
| 16 |  |  |  |  |  |  | G---C | 
| 17 |  |  |  |  |  |  | G----C | 
| 18 |  |  |  |  |  |  | C----G | 
| 19 |  |  |  |  |  |  | A----T | 
| 20 |  |  |  |  |  |  | C---G | 
| 21 |  |  |  |  |  |  | G--C | 
| 22 |  |  |  |  |  |  | TA | 
| 23 |  |  |  |  |  |  | '; | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | my (%dict)    = qw/00 A 01 C 10 G 11 T/; | 
| 26 |  |  |  |  |  |  | my (%inverse) = qw/A 00 C 01 G 10 T 11/; | 
| 27 |  |  |  |  |  |  | my (%spouse)   = qw/A T T A C G G C/; | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | sub encode($) { | 
| 31 | 0 |  |  | 0 | 1 | 0 | local $_ = unpack "b*", shift; | 
| 32 | 0 |  |  |  |  | 0 | my (@offset) = qw/1 0 0 0 1 2 3 4 5 5 4 3 2 1 0 0 0 1/; | 
| 33 | 0 |  |  |  |  | 0 | my (@dist)   = qw/0 2 3 4 4 4 3 2 0 0 2 3 4 4 4 3 2 0/; | 
| 34 | 0 |  |  |  |  | 0 | s/(..)/$dict{$1}/g; | 
| 35 | 0 |  |  |  |  | 0 | my ($dh, $i); | 
| 36 | 0 |  |  |  |  | 0 | for my $base (split //){ | 
| 37 | 0 |  |  |  |  | 0 | $dh .= join q//, | 
| 38 |  |  |  |  |  |  | q/ /x$offset[($i%@offset)], "$base", q/-/x$dist[($i++%@dist)], "$spouse{$base}\n"; | 
| 39 |  |  |  |  |  |  | } | 
| 40 | 0 |  |  |  |  | 0 | $promoter.$dh; | 
| 41 |  |  |  |  |  |  | } | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | sub decode($) { | 
| 44 | 1 |  |  | 1 | 0 | 2 | local $_ = shift; | 
| 45 | 1 |  |  |  |  | 18 | s/^$promoter//; | 
| 46 | 1 |  |  |  |  | 191 | s/.*([ACGT]).*[ACGT]\n/$1/gm; | 
| 47 | 1 |  |  |  |  | 5 | s/(.)/$inverse{$1}/ge; | 
|  | 232 |  |  |  |  | 429 |  | 
| 48 | 1 |  |  |  |  | 101 | pack "b*", $_; | 
| 49 |  |  |  |  |  |  | } | 
| 50 |  |  |  |  |  |  |  | 
| 51 | 1 |  |  | 1 | 0 | 24 | sub promoted($) { $_[0] =~ /^$promoter/ } | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | open 0 or print "Can't open '$0'\n" and exit; | 
| 54 |  |  |  |  |  |  | (my $sequence = join "", <0>) =~ s/.*^\s*use\s+Acme::DoubleHelix\s*;\n//sm; | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | do { eval decode $sequence; exit } if promoted $sequence; | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | open 0, ">$0" or print "Cannot encode '$0'\n" and exit; | 
| 59 |  |  |  |  |  |  | print {0} "use Acme::DoubleHelix;\n", encode $sequence and exit; | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  | 1; | 
| 63 |  |  |  |  |  |  | __END__ |