I’ve been doing the Perl Weekly
Challenges. The
latest
involved a basic Markov chain.
Write a script to rotate the followin matrix by given 90/180/270
degrees clockwise.
[ 1, 2, 3 ]
[ 4, 5, 6 ]
[ 7, 8, 9 ]
For example, if you rotate by 90 degrees then expected result should
be like below
[ 7, 4, 1 ]
[ 8, 5, 2 ]
[ 9, 6, 3 ]
This is fairly straightforward: a function to do a single rotation,
iterated, will handle all of them. The main fiddliness is to work out
that each step maps (x,y) to (y,-x).
sub rotate {
my ($rotations,@in)=@_;
my $xs=$#in;
foreach my $ya (@in) {
if ($#{$ya} != $xs) {
die "not a square matrix\n";
}
}
my @out=@in;
foreach (1..$rotations) {
my @im=@out;
my @tmp;
foreach my $x (0..$xs) {
foreach my $y (0..$xs) {
$tmp[$y][$xs-$x]=$im[$x][$y];
}
}
@out=@tmp;
}
return @out;
}
Perl6 is similar except for syntax.
Write a script to accept an integer 1 <= N <= 5 that would print all
possible strings of size N formed by using only vowels (a, e, i, o,
u).
The string should follow the following rules:
‘a’ can only be followed by ‘e’ and ‘i’.
‘e’ can only be followed by ‘i’.
‘i’ can only be followed by ‘a’, ‘e’, ‘o’, and ‘u’.
‘o’ can only be followed by ‘a’ and ‘u’.
‘u’ can only be followed by ‘o’ and ‘e’.
For example, if the given integer N = 2 then script should print the
following strings:
ae
ai
ei
ia
io
iu
ie
oa
ou
uo
ue
I've done things like this before with Markov chains, typically using
the two previous elements to generate the next one randomly. In this
case it was simply a iterative breadth-first search: given a stem,
generate all possible extensions. The obvious data structure for this
is a ring buffer, with loop exit when any member of the buffer has
reached the target length (which will mean they all have).
my %tree=(
'' => [qw(a e i o u)],
a => [qw(e i)],
e => [qw(i)],
i => [qw(a e o u)],
o => [qw(a u)],
u => [qw(o e)],
);
print map {"$_\n"} generate(2,\%tree);
sub generate {
my ($len,$tree)=@_;
my @list=('');
while (1) {
if (length($list[0])==$len) {
last;
}
my $r=shift @list;
my $s=substr($r,-1,1) || '';
foreach my $extension (@{$tree{$s}}) {
push @list,$r.$extension;
}
}
return @list;
}
Perl6 is similar, but it was fiddly to get an array literal into a hash:
my %tree=(
'' => [<a e i o u>],
a => [<e i>],
e => [<i>],
i => [<a e o u>],
o => [<a u>],
u => [<o e>],
);
and substr no longer takes a negative argument for "end of the string"
even though the documentation says it should work as it did in perl5.
my $s = substr($r,*-1,1) || '';
Perl6 tries to hide references, but eventually it has to give up and
admit that they exist.
for @(%tree{$s}) -> $extension {
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.