RabbitFarm

2024-03-23

These Elements, They’re Multiplying!

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

File Index

"ch-1.pl" Defined by 1.

"ch-2.pl" Defined by 7.

Part 1: Element Digit Sum

You are given an array of integers, @integers. Write a script to evaluate the absolute difference between every element and the digit sum of the entire given array.

The complete solution is contained in one file that has a simple structure.

"ch-1.pl" 1


preamble 2
element digit sum 5
main 6

For this problem we do not need to include very much. We’re just specifying to use the current version of Perl, for all the latest features in the language. This fragment is also used in Part 2.

preamble 2 ⟩≡


use v5.38;

Fragment referenced in 1, 7.

First, let’s consider how we compute the digit sum for an array of integers. If we we make sure that all multi-digit numbers are expanded into lists of digits then this is the sum of the concatenation of all such lists, along with single digit numbers.

The expansion of multi-digit numbers is handled by map, and the sum is taken with unpack and the resulting final array. A key thing to remember here is that Perl will flatten all lists inside the array so all the results from the map will be in a list of single digits.

compute digit sum 3 ⟩≡


my $digit_sum = unpack(q/%32I*/, pack(
q/I*/, map {split //, $_} @{$integers})
);

Fragment referenced in 5.

Defines: $digit_sum 5.

Uses: $integers 5.

The element sum is the same procedure as the digit sum, but just without the map.

compute element sum 4 ⟩≡


my $element_sum = unpack(q/%32I*/, pack q/I*/, @{$integers});

Fragment referenced in 5.

Defines: $element_sum 5.

Uses: $integers 5.

element digit sum 5 ⟩≡


sub element_digit_sum{
my($integers) = [@_];
compute digit sum 3
compute element sum 4
return abs($element_sum - $digit_sum)
}

Fragment referenced in 1.

Defines: $integers 3, 4.

Uses: $digit_sum 3, $element_sum 4.

Finally, we have a few lines of code for running some tests.

main 6 ⟩≡


MAIN:{
say element_digit_sum 1, 2, 3, 45;
say element_digit_sum 1, 12, 3;
say element_digit_sum 1, 2, 3, 4;
say element_digit_sum 236, 416, 336, 350;
}

Fragment referenced in 1.

Sample Run
$ perl perl/ch-1.pl 
36 
9 
0 
1296
    

Part 2: Multiply by Two

You are given an array of integers, @integers and an integer $start. Write a script to do the following:

a) Look for $start in the array @integers, if found multiply the number by 2.

b) If not found stop the process, otherwise repeat.

In the end return the final value.

We’ll contain the solution in a single recursive function. The completed solution will just have that function plus a few tests.

"ch-2.pl" 7


preamble 2
search and multiply 8
main 9

This is our principal function. As can be seen, it’s very short! The logic here is simple: for each recursive call check for $start in the array and, if found, double $start and keep recursing. Otherwise, return $start.

search and multiply 8 ⟩≡


sub search_multiply{
my($start) = shift;
return $start if 0 == grep {$start == $_} @_;
search_multiply($start + $start, @_);
}

Fragment referenced in 7.

Finally, here’s a few tests to confirm everything is working right.

main 9 ⟩≡


MAIN:{
say search_multiply 3, 5, 3, 6, 1, 12;
say search_multiply 1, 1, 2, 3, 4;
say search_multiply 2, 5, 6, 7;
}

Fragment referenced in 7.

Sample Run
$ perl ch-2.pl 
24 
8 
2
    

References

The Weekly Challenge 261
Generated Code

posted at: 20:34 by: Adam Russell | path: /perl | permanent link to this entry