I’ve been doing the Perl Weekly
Challenges. The
latest
involved base sequences and a binary multiplication system. (Note that
this is open until 13 December 2020.)
TASK #1 › DNA Sequence
DNA is a long, chainlike molecule which has two strands twisted into
a double helix. The two strands are made up of simpler molecules
called nucleotides. Each nucleotide is composed of one of the four
nitrogen-containing nucleobases cytosine (C), guanine (G), adenine
(A) and thymine (T).
You are given DNA sequence,
GTAAACCCCTTTTCATTTAGACAGATCGACTCCTTATCCATTCTCAGAGATGTGTTGCTGGTCGCCG.
Write a script to print nucleiobase count in the given DNA sequence.
Also print the complementary sequence where Thymine (T) on one
strand is always facing an adenine (A) and vice versa; guanine (G)
is always facing a cytosine (C) and vice versa.
This is a bit odd. Usually we get at least a couple of test cases,
rather than just the single query. And why return the base count when
this is just the length of the string? Hey ho. Let's just do this the
really easy way, with regexp substitution.
sub gs {
my $bs=shift;
(my $cs=$bs) =~ s/G/X/g;
$cs =~ s/C/G/g;
$cs =~ s/X/C/g;
$cs =~ s/A/X/g;
$cs =~ s/T/A/g;
$cs =~ s/X/T/g;
return [length($bs),$cs];
}
Similarly in Raku, only with slighly different syntax:
$cs ~~ s:g/C/G/;
For the other languages I used hashes/dicts and maps. Python:
def gs(bs):
l={'A': 'T','T': 'A','C': 'G','G': 'C'}
os=''.join(l[i] for i in bs)
return [len(os),os]
Ruby:
def gs(bs)
l={'A' => 'T', 'T' => 'A', 'C' => 'G', 'G' => 'C'}
os=bs.chars.map{|i| l[i]}.join('')
return [os.length(),os]
end
Rust (which does have maps, but I have to do so much variable
furkling that they'd just reduce readability):
fn gs(bs: String) -> (i32, String) {
let mut l: HashMap<char, char>=HashMap::new();
l.insert('C','G');
(etc.)
let mut os=String::new();
for i in bs.chars() {
os.push(*l.get(&i).unwrap());
}
return (os.len() as i32,os);
}
TASK #2 › Ethiopian Multiplication
You are given two positive numbers $A and $B.
Write a script to demonstrate Ethiopian Multiplication using the
given numbers.
The supplied link makes it clear that this is the "Russian
Peasant"
variant; halve A, double B, if A on that row is odd then add B to the
total.. So what I'll produce will look like, for 13×238:
13 238 -> 238
6 476
3 952 -> 952
1 1904 -> 1904
-----
3094
I'm arbitrarily restricting numbers to 5 digits, and using the same
algorithm for each language: generate each line, push it into a list,
then print out the whole list at the end. Nothing terribly clever
here. Here's the Raku version:
sub em($aa,$bb) {
my ($a,$b)=($aa,$bb);
my $s=0;
my @demo;
while ($a > 0) {
my $line=sprintf('%5d %5d',$a,$b);
if ($a +& 1 == 1) {
$s+=$b;
$line ~= sprintf(' -> %5d',$b);
}
$a +>= 1;
$b +<= 1;
push @demo,$line;
}
push @demo,' -----';
push @demo,sprintf(' %5d',$s);
for @demo {
say $_;
}
return $s;
}
Python and Rust use their own distinct formatting systems rather than
standard sprintf
. I hope it makes them feel terribly special.
Full code on
github.
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.