I’ve been doing the Perl Weekly
Challenges. The
latest
was about recovering a corrupted message and solving an iterative problem.
To discuss the solution of the first part is to spoil the
problem, because working out what is going on is the fun bit. After
that, it's just looking for a particular pattern in the input data.
For each character position, count how many times (across multiple
copies of the message) each character appears there.
my @place;
while (<>) {
chomp;
my @k=split / /,$_;
map {$place[$_]{$k[$_]}++} (0..$#k);
}
For each character position, print the character that appears there
most often.
foreach my $h (@place) {
my @v=values %{$h};
my @k=keys %{$h};
my @i=sort {$v[$b] <=> $v[$a]} (0..$#v);
print $k[$i[0]];
}
print "\n";
And similarly in perl6, though I finally got round to using comb
rather than split
.
for lines() {
.chomp;
my @k=comb(/\S/,$_);
map {@place[$_]{@k[$_]}++}, (0..@k.end);
}
for @place -> %h {
my @v=values %h;
my @k=keys %h;
my @i=sort {@v[$^b] <=> @v[$^a]}, (0..@v.end);
print @k[@i[0]];
}
print "\n";
For the other part, which has the air of one of those standard
computing problems, it's just a matter of iteration… with a small
optimisation at the start to avoid setting the entire array twice, but
with a mere 500 entries there's no point in optimising further.
(Contrast 2019's Advent of Code, which would give this as the first
part of a problem and then in the second part give you eleventy
billion rooms and ask about the final state of number 983244521.)
my @rooms=(1) x 500;
foreach my $n (2..500) {
for (my $k=$n-1;$k<500;$k+=$n) {
$rooms[$k]=1-$rooms[$k];
}
}
print map {$_+1,"\n"} grep {$rooms[$_]==1} (0..$#rooms);
Perl6 differs only in syntax (and the need for whitespace before <
).
my @rooms=1 xx 500;
for 2..500 -> $n {
loop (my $k=$n-1 ; $k <500 ; $k+=$n) {
@rooms[$k]=1-@rooms[$k];
}
}
map {say $_+1}, grep {@rooms[$_]==1}, (0..@rooms.end);
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.