Perl Weekly Challenge: Week 11
Challenge 1:
Write a script that computes the equal point in the Fahrenheit and Celsius scales, knowing that the freezing point of water is 32° F and 0 °C, and that the boiling point of water is 212 °F and 100 °C. This challenge was proposed by Laurent Rosenfeld.
We can do this in Raku (or Perl 6 as it was known when this challenge came out) as a one-liner.
We use the "lazy list" feature to count down degrees in celsius from 0. For each number in the list we convert to Fahrenheit using the well-known formula C = 32 + 1.8F
and compare the two stopping only when they are both equal. Why count down? Because if
0° C = 32° F we can reasonably assume that their meeting point will not be a positive number. So now we have a list consisting
of all numbers from 0 to the goal. The subscript [*-1]
indicates the last element of the list i.e. the goal. We print it out
with say()
.
say (0, -1 ... { $_ == 32 + 1.8 * $_ })[*-1];
For Perl, we set up a variable with the initial value of degrees. i.e. 0. In hindsight I should have named this $celsius
instead of $x
.
my $x = 0;
In lieu of lazy lists, we have to use a while
loop and decrement $x
.
while ($x != 32 + 1.8 * $x) {
$x--;
}
say $x;
The answer by the way is -40.
Challenge 2:
Write a script to create an Identity Matrix for the given size. For example, if the size is 4, then create Identity Matrix 4x4. For more information about Identity Matrix, please read the wiki page.
If you read the Wikipedia article linked in the spec, you would see that this identity matrix is just a 2d array where elements in a diagonal from top left to bottom right (or top right to bottom left I suppose) have the value 1 and all the other elements have the value 0.
This is easy to recreate. We just need a double loop, each ranging from 0 to the size of the matrix...
for (0 .. $n - 1) -> $i {
for (0 .. $n - 1) -> $j {
...and where the value of the inner and outer loop indices is equal we print 1, otherwise we print 0. spaces and newlines are also printed to make the output more attractive.
print ($j == $i) ?? '1 ' !! '0 ';
}
print "\n";
}
The Perl version is exactly the same except for syntax differences.
for my $i (0 .. $n - 1) {
for my $j (0 .. $n - 1) {
print (($j == $i) ? '1 ' : '0 ');
}
print "\n";
}