# Reduce to the max **Challenge 225 solutions in Perl by Matthias Muth** The tasks of this challenge are good ones, in the sense that the solutions can be short, nice, well-arranged, clear -- perly! However the second task took me some time to understand what really is happening in the task description and in the examples. But let's start with the first one: ## Task 1: Max Words > You are given a list of sentences, @list.
> A sentence is a list of words that are separated by a single space with no leading or trailing spaces.
> Write a script to find out the maximum number of words that appear in a single sentence.
>
> Example 1
> Input: @list = (qw/Perl and Raku belong to the same family./,
> qw/I love Perl./,
> qw/The Perl and Raku Conference./)
> Output: 8
>
> Example 2
> Input: @list = (qw/The Weekly Challenge./,
> qw/Python is the most popular guest language./,
> qw/Team PWC has over 300 members./)
> Output: 7
Perl in its own realm.
So short that it probably needs some explanations... We get a list of strings, each one containing one sentence. So let's split up each sentence into 'words' using `split " ", $_`, getting our `$_` from using `map` walking us through the list of sentences. The number of words in each sentence is `scalar` of the list of words that we just got. And `max(...)` (from `List::Util`) gets us the largest one. VoilĂ ! ```perl use List::Util qw( max ); sub max_words { my ( @list ) = @_; return max( map { scalar split " ", $_ } @list ); } ``` ## Task 2: Left Right Sum Diff > You are given an array of integers, @ints.
> Write a script to return left right sum diff array as shown below:
> @ints = (a, b, c, d, e)
> @left = (0, a, (a+b), (a+b+c))
> @right = ((c+d+e), (d+e), e, 0)
> @left_right_sum_diff = ( | 0 - (c+d+e) |,
> | a - (d+e) |,
> | (a+b) - e |,
> | (a+b+c) - 0 | )
>
> Example 1:
> Input: @ints = (10, 4, 8, 3)
> Output: (15, 1, 11, 22)
> @left = (0, 10, 14, 22)
> @right = (15, 11, 3, 0)
> @left_right_sum_diff = ( |0-15|, |10-11|, |14-3|, |22-0|)
> = (15, 1, 11, 22)
>
> Example 2:
> Input: @ints = (1)
> Output: (0)
> @left = (0)
> @right = (0)
> @left_right_sum_diff = ( |0-0| ) = (0)
>
> Example 3:
> Input: @ints = (1, 2, 3, 4, 5)
> Output: (14, 11, 6, 1, 19)
> @left = (0, 1, 3, 6, 10)
> @right = (14, 12, 9, 5, 0)
> @left_right_sum_diff = ( |0-14|, |1-12|, |3-9|, |6-5|, |10-0|)
> = (14, 11, 6, 1, 10)
Maybe I don't fully understand the definition, but for me, there seems to be a little inconsistency between the definition and the examples. In the definiton we have 5 elements as input, but only 4 elements in the left and right sums, whereas all the examples are explained using arrays of left and right sums that have the same number of elements as the input array.
I decided in favor of the examples. :-) For this task, I completely avoided writing any for loops, and based my solution on list-processing functions: * `reductions` from `List::Util` does the summing up of the 'left' sum, starting with a 0 and going through all input elements except the last one (to get the correct number of elements), * `reductions` from `List::Util` also does the summing up of the 'right' sum, starting with a 0 and going through the input elements *in reverse order*, leaving out the first element, and then doing another `reverse` to have the 0 at the end of the list, * `pairwise` from the `List::MoreUtils` module from CPAN then builds the list of differences between corresponding elements of the 'left' and 'right' arrays. So actually the task can be solved using three lines of actual code: ```perl use feature 'signatures'; no warnings 'experimental::signatures'; use List::Util qw( reductions ); use List::MoreUtils qw( pairwise ); sub left_right_sum_diff( @ints ) { my @left = reductions { $a + $b } 0, @ints[ 0 .. $#ints - 1 ]; my @right = reverse reductions { $a + $b } 0, reverse @ints[ 1 .. $#ints ]; return pairwise { abs( $a - $b ) } @left, @right } ``` #### **Thank you for the challenge!**