CY's Take on The Weekly Challenge #113
If you want to challenge yourself on programming, especially on Perl and/or Raku, go to https://perlweeklychallenge.org, code the latest challenges, submit codes on-time (by GitHub or email).
Do tell me, if I am wrong or you strongly oppose my statements!
It's time for challenges in Week #113 !
Task 1: Represent Integer
An important assertion is: for a non-zero digit $D, any positive integers larger than or equal to $D*10 can be represented in the way specific in the task statement. This comes from modulo arithmetic or mathematical induction, whatever.
For a positive integer smaller than $D*10, there are two very similar ways to determine whether it is "representable":
sub step_down {
# Example I: if N = 82, D = 9, it hints 82 = 9*7+19
# Example II: if N = 64, D = 7, it hints 64 = 7*1+57
# Example III: if N = 30, D = 8, the set {8, 18, 28} ...
# Example IV: if N = 44, D = 6, it hints 44 = 6*3+26
my $digit = $_[0];
my $short = $_[1];
my $temp_short = $short;
do {
return 1 if $temp_short =~ /$digit/;
$temp_short -= $digit;
} while ($temp_short > 0);
return 0;
}
sub last_digit {
# Example I: if N = 82, D = 9, it hints 82 = 72+10 = 9*8+10 = 9*7+19
# Example II: if N = 64, D = 7, it hints 64 = 14+50 = 7*2+50 = 7*1+57
# Example III: if N = 30, D = 8, the set {8, 18, 28} ...
# Example IV: if N = 44, D = 6, it hints 44 = 24+20 = 6*4+20 = 6*3+26
my $digit = $_[0];
my $short = $_[1];
my $last_digit_of_short = $short % 10;
my $i = 1;
while ($digit*$i < $short) {
if ($digit*$i % 10 == $last_digit_of_short ) {
return 1;
}
$i++;
}
return 0;
}
Let us do some optimization according to the fact that the base is 10:
sub representable {
#...
return 1 if $N >= 10*$D;
return 1 if $N % $D == 0; # $N = $D + $D + ... + $D, esp $D == 1
return 0 if $D == 2 || $D == 5;
if ($D == 4 && $N > 10) {
return $N % 2 == 0 ? 1 : 0;
}
if ($D == 8 && $N >= 40) {
return $N % 2 == 0 ? 1 : 0;
}
if ($D == 6) {
return 0 if $N % 2 != 0;
}
# call &step_down or &last_digit...
}
The math of "representable number" in an arbitary base has certain interesting mathematical properties and I am stil exploring them. What kinds of interesting properties? For example, in base-10, for digits $D coprime to 10 (i.e. 3, 7 and 9), the number of "representable" positive integers smaller than $D*10 is (10-1)*($D+1)/2:
- 3: 3, 6, 9, 12, 13, 15, 16, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29 (18 terms);
- 7: 7, 14, 17, 21, 24, 27, 28, 31, 34, 35, 37, 38, 41, 42, 44, 45, 47, 48, 49, 51, 52, 54, 55, 56, 57, 58, 59, 61, 62, 63, 64, 65, 66, 67, 68, 69 (36 terms);
- 9: 9, 18, 19, 27, 28, 29, 36, 37, 38, 39, 45, 46, 47, 48, 49, 54, 55, 56, 57, 58, 59, 63, 64, 65, 66, 67, 68, 69, 72, 73, 74, 75, 76, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89 (45 terms).
For completeness, note that the handle of the case of $D = 0, is return 1 if $N >= $base*$base; return $N % $base == 0 ? 1 : 0; .
Task 2: Recreate Binary Tree
Firstly, take an assumption that the input are integers. But the task statement does not specific whether zero and/or negative numbers are allowed, hence for the null nodes, we can't set them as 0 or -1. Luckily, we have undef in Perl.
Among the possible data structures for getting the sum of the values in nodes of a binary tree, "an implicitly breadth-first orderred one-dimensional array"(paraphrased from Wikipedia) should be the easiest to implement.
Another advantage of this data structure is that it is easy to input:
# Usage: ch-2.pl [binary tree in array format, 'x' for null nodes]
my @tree = map { $_ eq 'x' ? undef : $_ } @ARGV;
my $sum = 0;
for (@tree) {
$sum += $_ if defined($_);
}
for (@tree) {
$_ = $sum - $_ if defined($_);
}
print_tree(@tree);
Using the example in the task statement, we have:
$ perl ch-2.pl 1 2 3 4 x 5 6 x 7 27 26 25 24 x 23 22 x 21
After the first round of coding, I felt a bit bored. Why not provide a hash of hashes implementation for the binary trees? I hadn't done that before. Look at the history of submission; the closest thing I had done is the nested array implementation(Week #057) for the binary trees. I have typed Java and OO stuff so hard recently that it took some time for me to code out the hash of hashes:
sub tree_build { # use for print_pretty_tree
my @t = @{$_[0]};
my $ind = $_[1];
my %leaf = ( "v" => $t[$ind] );
$leaf{"l"} = tree_build(\@t, $ind*2+1)
if defined($t[$ind*2+1]);
$leaf{"r"} = tree_build(\@t, $ind*2+2)
if defined($t[$ind*2+2]);
return \%leaf;
}
And just like what I did in Week #057, I ask Data::Dumper for output:
sub print_pretty_tree {
my @tr = @_;
my $hash_tree = tree_build( \@tr, 0);
$Data::Dumper::Terse = 1;
$Data::Dumper::Indent = 2;
$Data::Dumper::Sortkeys = 1;
print "\n";
print "Output in Hash Format:\n";
print Dumper $hash_tree;
}
The updated result is:
$ perl ch-2.pl 1 2 3 4 x 5 6 x 7 Output in Array Format: 27 26 25 24 x 23 22 x 21 Output in Hash Format: { 'l' => { 'l' => { 'r' => { 'v' => 21 }, 'v' => 24 }, 'v' => 26 }, 'r' => { 'l' => { 'v' => 23 }, 'r' => { 'v' => 22 }, 'v' => 25 }, 'v' => 27 }
Stay alert and healthy! □
link for full codes: ch-1.pl, ch-2.pl
Contact on twitter: @e7_87.
Created Date: 19th May, 2021; last updated: 20th May, 2021 05:09 HKT