aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubos Kolouch <lubos@kolouch.net>2025-09-16 10:00:40 +0200
committerLubos Kolouch <lubos@kolouch.net>2025-09-16 10:00:40 +0200
commit5848bcf4c55da4ca11a6ff911ea340115fcf6264 (patch)
tree5db836cc2a203c10cdad2fe15da167815abf889d
parent0bcf9c312644e0c7cac46ede084bcd19172aeed8 (diff)
downloadperlweeklychallenge-club-5848bcf4c55da4ca11a6ff911ea340115fcf6264.tar.gz
perlweeklychallenge-club-5848bcf4c55da4ca11a6ff911ea340115fcf6264.tar.bz2
perlweeklychallenge-club-5848bcf4c55da4ca11a6ff911ea340115fcf6264.zip
Add challenge 339 solutions for Lubos
-rw-r--r--challenge-339/lubos-kolouch/README75
-rw-r--r--challenge-339/lubos-kolouch/perl/ch-1.pl80
-rw-r--r--challenge-339/lubos-kolouch/perl/ch-2.pl60
-rw-r--r--challenge-339/lubos-kolouch/python/ch-1.py64
-rw-r--r--challenge-339/lubos-kolouch/python/ch-2.py49
5 files changed, 292 insertions, 36 deletions
diff --git a/challenge-339/lubos-kolouch/README b/challenge-339/lubos-kolouch/README
index b3e885f6ab..7035227f5b 100644
--- a/challenge-339/lubos-kolouch/README
+++ b/challenge-339/lubos-kolouch/README
@@ -1,76 +1,79 @@
Solutions by Lubos Kolouch.
-# The Weekly Challenge - 338
+# The Weekly Challenge - 339
-## Task 1: Highest Row
+## Task 1: Max Diff
### Description
-Given an m x n matrix, the task is to find the highest row sum in the matrix. Each row is summed, and the maximum sum is returned.
+Given an array of at least four integers, find two disjoint pairs whose product
+difference is as large as possible. The difference for pairs (a, b) and (c, d)
+is `(a * b) - (c * d)`, and we are interested in the maximum absolute value of
+this difference across all pair selections.
### Solution
#### Perl (ch-1.pl)
-The Perl solution defines a function `highest_row` that takes a reference to a 2D array (matrix). It iterates through each row, computes the sum of the elements, and tracks the maximum sum. Input validation ensures the matrix is not empty.
-
-- **Input**: A 2D array reference (`@matrix`).
-- **Output**: The maximum sum of any row.
-- **Approach**: Use a loop to sum each row and update the maximum sum if the current row's sum is larger.
+Enumerates every combination of four numbers, evaluates the three possible
+pairings, and keeps the maximum absolute difference between the resulting
+products. Input validation ensures the list has at least four elements, with
+unit tests covering the provided examples.
#### Python (ch-1.py)
-The Python solution defines a function `highest_row` that takes a 2D list (matrix). It uses Python's `sum` function to compute each row's sum and tracks the maximum using the `max` function. Type hints are included for clarity, and input validation checks for empty matrices.
-
-- **Input**: A 2D list (`matrix: List[List[int]]`).
-- **Output**: An integer representing the maximum row sum.
-- **Approach**: Iterate through rows, compute sums, and track the maximum.
+Uses `itertools.combinations` to iterate through all quadruples of integers and
+checks the three pairings of each quadruple. Tracks the maximum absolute
+product difference. Type hints and `unittest` cases cover the supplied
+scenarios.
### Examples
-- Example 1: `[[4, 4, 4, 4], [10, 0, 0, 0], [2, 2, 2, 9]]` → `16`
-- Example 2: `[[1, 5], [7, 3], [3, 5]]` → `10`
-- Example 3: `[[1, 2, 3], [3, 2, 1]]` → `6`
-- Example 4: `[[2, 8, 7], [7, 1, 3], [1, 9, 5]]` → `17`
-- Example 5: `[[10, 20, 30], [5, 5, 5], [0, 100, 0], [25, 25, 25]]` → `100`
+- Example 1: `[5, 9, 3, 4, 6]` → `42`
+- Example 2: `[1, -2, 3, -4]` → `10`
+- Example 3: `[-3, -1, -2, -4]` → `10`
+- Example 4: `[10, 2, 0, 5, 1]` → `50`
+- Example 5: `[7, 8, 9, 10, 10]` → `44`
-## Task 2: Max Distance
+## Task 2: Peak Point
### Description
-Given two integer arrays, the task is to find the maximum absolute difference between any pair of values from the two arrays.
+Given a list of altitude gains, starting from altitude zero compute the running
+sum and report the highest altitude reached at any step.
### Solution
#### Perl (ch-2.pl)
-The Perl solution defines a function `max_distance` that takes references to two arrays. It computes the absolute difference between each pair of elements from the two arrays using nested loops and tracks the maximum difference. Input validation ensures both arrays are non-empty.
-
-- **Input**: Two array references (`@arr1`, `@arr2`).
-- **Output**: The maximum absolute difference between any pair of elements.
-- **Approach**: Use nested loops to compute `abs(x - y)` for each pair and update the maximum.
+Processes the gains sequentially, maintaining the cumulative altitude and the
+highest value encountered. Embedded tests verify the challenge examples.
#### Python (ch-2.py)
-The Python solution defines a function `max_distance` that takes two lists of integers. It uses nested loops to compute the absolute difference between each pair of elements and tracks the maximum using the `max` function. Type hints are included, and input validation checks for empty arrays.
-
-- **Input**: Two lists (`arr1: List[int]`, `arr2: List[int]`).
-- **Output**: An integer representing the maximum absolute difference.
-- **Approach**: Iterate through all pairs, compute absolute differences, and track the maximum.
+Updates the running altitude for each gain and retains the maximum altitude
+seen. Includes type annotations and unit tests mirroring the provided cases.
### Examples
-- Example 1: `arr1 = [4, 5, 7], arr2 = [9, 1, 3, 4]` → `6`
-- Example 2: `arr1 = [2, 3, 5, 4], arr2 = [3, 2, 5, 5, 8, 7]` → `6`
-- Example 3: `arr1 = [2, 1, 11, 3], arr2 = [2, 5, 10, 2]` → `9`
-- Example 4: `arr1 = [1, 2, 3], arr2 = [3, 2, 1]` → `2`
-- Example 5: `arr1 = [1, 0, 2, 3], arr2 = [5, 0]` → `5`
+- Example 1: `[-5, 1, 5, -9, 2]` → `1`
+- Example 2: `[10, 10, 10, -25]` → `30`
+- Example 3: `[3, -4, 2, 5, -6, 1]` → `6`
+- Example 4: `[-1, -2, -3, -4]` → `0`
+- Example 5: `[-10, 15, 5]` → `10`
## Running the Code
### Perl
-Run the Perl scripts with:
```bash
perl ch-1.pl
perl ch-2.pl
+```
+
+### Python
+
+```bash
+python3 ch-1.py
+python3 ch-2.py
+```
diff --git a/challenge-339/lubos-kolouch/perl/ch-1.pl b/challenge-339/lubos-kolouch/perl/ch-1.pl
new file mode 100644
index 0000000000..086c600a9d
--- /dev/null
+++ b/challenge-339/lubos-kolouch/perl/ch-1.pl
@@ -0,0 +1,80 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+=head1 NAME
+
+ch-1.pl - The Weekly Challenge 339 Task 1: Max Diff
+
+=head1 DESCRIPTION
+
+Given an array of at least four integers, find two disjoint pairs whose product
+difference is as large as possible. The difference for pairs (a, b) and (c, d)
+is defined as C<(a * b) - (c * d)>. The script enumerates all quadruples of
+numbers, checks the three ways to split them into two pairs, and keeps the
+maximum absolute difference of the resulting products.
+
+=head1 AUTHOR
+
+Lubos Kolouch
+
+=cut
+
+use constant IntList => 'ARRAY';
+use Test::More tests => 5;
+
+sub max_product_difference {
+ my (@ints) = @_;
+ die 'Need at least four integers' if @ints < 4;
+
+ my $max_diff = 0;
+ for my $i ( 0 .. $#ints - 3 ) {
+ for my $j ( $i + 1 .. $#ints - 2 ) {
+ for my $k ( $j + 1 .. $#ints - 1 ) {
+ for my $l ( $k + 1 .. $#ints ) {
+ my @vals = @ints[ $i, $j, $k, $l ];
+ my @pairings = (
+ [ [ $vals[0], $vals[1] ], [ $vals[2], $vals[3] ] ],
+ [ [ $vals[0], $vals[2] ], [ $vals[1], $vals[3] ] ],
+ [ [ $vals[0], $vals[3] ], [ $vals[1], $vals[2] ] ],
+ );
+
+ for my $pair (@pairings) {
+ my ( $first, $second ) = @$pair;
+ my $prod1 = $first->[0] * $first->[1];
+ my $prod2 = $second->[0] * $second->[1];
+ my $diff = abs( $prod1 - $prod2 );
+ $max_diff = $diff if $diff > $max_diff;
+ }
+ }
+ }
+ }
+ }
+
+ return $max_diff;
+}
+
+subtest 'Example 1' => sub {
+ my @ints = ( 5, 9, 3, 4, 6 );
+ is( max_product_difference(@ints), 42, 'Max difference is 42' );
+};
+
+subtest 'Example 2' => sub {
+ my @ints = ( 1, -2, 3, -4 );
+ is( max_product_difference(@ints), 10, 'Max difference is 10' );
+};
+
+subtest 'Example 3' => sub {
+ my @ints = ( -3, -1, -2, -4 );
+ is( max_product_difference(@ints), 10, 'Max difference is 10' );
+};
+
+subtest 'Example 4' => sub {
+ my @ints = ( 10, 2, 0, 5, 1 );
+ is( max_product_difference(@ints), 50, 'Max difference is 50' );
+};
+
+subtest 'Example 5' => sub {
+ my @ints = ( 7, 8, 9, 10, 10 );
+ is( max_product_difference(@ints), 44, 'Max difference is 44' );
+};
diff --git a/challenge-339/lubos-kolouch/perl/ch-2.pl b/challenge-339/lubos-kolouch/perl/ch-2.pl
new file mode 100644
index 0000000000..277360cff3
--- /dev/null
+++ b/challenge-339/lubos-kolouch/perl/ch-2.pl
@@ -0,0 +1,60 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+=head1 NAME
+
+ch-2.pl - The Weekly Challenge 339 Task 2: Peak Point
+
+=head1 DESCRIPTION
+
+Given a list of altitude gains, compute the cumulative altitude starting at
+zero and return the highest altitude reached. The script processes the gains in
+order, keeps the running total, and tracks the maximum value encountered.
+
+=head1 AUTHOR
+
+Lubos Kolouch
+
+=cut
+
+use constant GainList => 'ARRAY';
+use Test::More tests => 5;
+
+sub peak_point {
+ my (@gains) = @_;
+
+ my $current = 0;
+ my $max_alt = 0;
+ for my $delta (@gains) {
+ $current += $delta;
+ $max_alt = $current if $current > $max_alt;
+ }
+
+ return $max_alt;
+}
+
+subtest 'Example 1' => sub {
+ my @gain = ( -5, 1, 5, -9, 2 );
+ is( peak_point(@gain), 1, 'Peak altitude is 1' );
+};
+
+subtest 'Example 2' => sub {
+ my @gain = ( 10, 10, 10, -25 );
+ is( peak_point(@gain), 30, 'Peak altitude is 30' );
+};
+
+subtest 'Example 3' => sub {
+ my @gain = ( 3, -4, 2, 5, -6, 1 );
+ is( peak_point(@gain), 6, 'Peak altitude is 6' );
+};
+
+subtest 'Example 4' => sub {
+ my @gain = ( -1, -2, -3, -4 );
+ is( peak_point(@gain), 0, 'Peak altitude is 0' );
+};
+
+subtest 'Example 5' => sub {
+ my @gain = ( -10, 15, 5 );
+ is( peak_point(@gain), 10, 'Peak altitude is 10' );
+};
diff --git a/challenge-339/lubos-kolouch/python/ch-1.py b/challenge-339/lubos-kolouch/python/ch-1.py
new file mode 100644
index 0000000000..9c47b73425
--- /dev/null
+++ b/challenge-339/lubos-kolouch/python/ch-1.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+"""
+The Weekly Challenge 339 Task 1: Max Diff
+
+Given a list of at least four integers, find two disjoint pairs whose product
+absolute difference is maximal. For every combination of four numbers the
+script evaluates the three distinct pairings, computes the absolute difference
+of their products, and keeps the largest value encountered.
+"""
+from itertools import combinations
+import unittest
+
+IntList = list[int]
+PAIRINGS = (
+ ((0, 1), (2, 3)),
+ ((0, 2), (1, 3)),
+ ((0, 3), (1, 2)),
+)
+
+
+def max_product_difference(ints: IntList) -> int:
+ """Return the maximum product difference obtainable from two disjoint pairs."""
+ if len(ints) < 4:
+ msg = "Need at least four integers"
+ raise ValueError(msg)
+
+ best = 0
+ for indices in combinations(range(len(ints)), 4):
+ values = [ints[i] for i in indices]
+ for first, second in PAIRINGS:
+ prod1 = values[first[0]] * values[first[1]]
+ prod2 = values[second[0]] * values[second[1]]
+ diff = abs(prod1 - prod2)
+ if diff > best:
+ best = diff
+ return best
+
+
+class TestMaxProductDifference(unittest.TestCase):
+ """Unit tests covering the provided examples."""
+
+ def test_example1(self) -> None:
+ ints = [5, 9, 3, 4, 6]
+ self.assertEqual(max_product_difference(ints), 42)
+
+ def test_example2(self) -> None:
+ ints = [1, -2, 3, -4]
+ self.assertEqual(max_product_difference(ints), 10)
+
+ def test_example3(self) -> None:
+ ints = [-3, -1, -2, -4]
+ self.assertEqual(max_product_difference(ints), 10)
+
+ def test_example4(self) -> None:
+ ints = [10, 2, 0, 5, 1]
+ self.assertEqual(max_product_difference(ints), 50)
+
+ def test_example5(self) -> None:
+ ints = [7, 8, 9, 10, 10]
+ self.assertEqual(max_product_difference(ints), 44)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/challenge-339/lubos-kolouch/python/ch-2.py b/challenge-339/lubos-kolouch/python/ch-2.py
new file mode 100644
index 0000000000..6a7575b351
--- /dev/null
+++ b/challenge-339/lubos-kolouch/python/ch-2.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+"""
+The Weekly Challenge 339 Task 2: Peak Point
+
+Given a list of altitude gain values, compute the running cumulative altitude
+starting from zero and return the highest altitude reached at any step.
+"""
+import unittest
+
+GainList = list[int]
+
+
+def peak_point(gain: GainList) -> int:
+ """Return the maximum altitude reached given incremental gains."""
+ altitude = 0
+ peak = 0
+ for delta in gain:
+ altitude += delta
+ if altitude > peak:
+ peak = altitude
+ return peak
+
+
+class TestPeakPoint(unittest.TestCase):
+ """Unit tests covering the provided examples."""
+
+ def test_example1(self) -> None:
+ gain = [-5, 1, 5, -9, 2]
+ self.assertEqual(peak_point(gain), 1)
+
+ def test_example2(self) -> None:
+ gain = [10, 10, 10, -25]
+ self.assertEqual(peak_point(gain), 30)
+
+ def test_example3(self) -> None:
+ gain = [3, -4, 2, 5, -6, 1]
+ self.assertEqual(peak_point(gain), 6)
+
+ def test_example4(self) -> None:
+ gain = [-1, -2, -3, -4]
+ self.assertEqual(peak_point(gain), 0)
+
+ def test_example5(self) -> None:
+ gain = [-10, 15, 5]
+ self.assertEqual(peak_point(gain), 10)
+
+
+if __name__ == "__main__":
+ unittest.main()