Perl Weekly Challenge: Week 108
Challenge 1:
Locate Memory
Write a script to declare a variable or constant and print it's location in the memory.
Given a variable $a
, in Raku you can print it's location in memory like this:
say $a.WHERE.base(16);
(I converted the result to hexadecimal because memory locations look better in hexadecimal.)
In Perl, it's not quite that simple. If you take a reference to $a
and print it...
say \$a;
...you get the memory location and data type like this:
SCALAR(0x7ffff6bf7688)
Of course in languages like Perl and Raku that manage memory for you, there is not a lot you can do with this information. Maybe it's useful in debugging?
Challenge 2:
Bell Numbers
Write a script to display top 10
Bell Numbers
. Please refer to wikipedia page for more information.
Example
B0: 1 as you can only have one partition of zero element set
B1: 1 as you can only have one partition of one element set {a}.
B2: 2
{a}{b}
{a,b}
B3: 5
{a}{b}{c}
{a,b}{c}
{a}{b,c}
{a,c}{b}
{a,b,c}
B4: 15
{a}{b}{c}{d}
{a,b,c,d}
{a,b}{c,d}
{a,c}{b,d}
{a,d}{b,c}
{a,b}{c}{d}
{a,c}{b}{d}
{a,d}{b}{c}
{b,c}{a}{d}
{b,d}{a}{c}
{c,d}{a}{b}
{a}{b,c,d}
{b}{a,c,d}
{c}{a,b,d}
{d}{a,b,c}
Ugh maths again. Not being able to make head nor tail of the referenced wikipedia page, I googled around and found this page. The code below is a Raku translation of the C++ example provided there.
sub bellNumber(Int $n) {
my @bell;
@bell[0][0] = 1;
for 1 .. $n -> $i {
@bell[$i][0] = @bell[$i - 1][$i - 1];
for 1 .. $i -> $j {
@bell[$i][$j] = @bell[$i - 1][$j - 1] + @bell[$i][$j - 1];
}
}
return @bell[$n][0];
}
Basically we are creating what's known as a Bell Triangle by starting with a known value (1 for a set with 0 elements) and using
dynamic programming to calculate succeeding values. The leftmost value in the $n
th row of the triangle is the Bell number for $n
.
This is the same thing in Perl:
sub bellNumber {
my ($n) = @_;
my @bell;
$bell[0][0] = 1;
for my $i (1 .. $n) {
$bell[$i][0] = $bell[$i - 1][$i - 1];
for my $j (1 .. $i) {
$bell[$i][$j] = $bell[$i - 1][$j - 1] + $bell[$i][$j - 1];
}
}
return $bell[$n][0];
}
The spec asks for the "top ten" Bell numbers by which I assume the first ten is meant. In case you are curious, they are:
1 1 2 5 15 52 203 877 4140 21147