aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubos Kolouch <lubos@kolouch.net>2025-09-16 09:46:13 +0200
committerLubos Kolouch <lubos@kolouch.net>2025-09-16 09:48:14 +0200
commit0bcf9c312644e0c7cac46ede084bcd19172aeed8 (patch)
tree3a388c9850114b963709dbd30d727e94ffbbfccb
parent05dd424e54c84c2e859717388d326340427fbc33 (diff)
downloadperlweeklychallenge-club-0bcf9c312644e0c7cac46ede084bcd19172aeed8.tar.gz
perlweeklychallenge-club-0bcf9c312644e0c7cac46ede084bcd19172aeed8.tar.bz2
perlweeklychallenge-club-0bcf9c312644e0c7cac46ede084bcd19172aeed8.zip
Add challenge 333 solutions for Lubos
-rw-r--r--challenge-333/lubos-kolouch/README36
-rw-r--r--challenge-333/lubos-kolouch/perl/ch-1.pl77
-rw-r--r--challenge-333/lubos-kolouch/perl/ch-2.pl84
-rw-r--r--challenge-333/lubos-kolouch/python/ch-1.py82
-rw-r--r--challenge-333/lubos-kolouch/python/ch-2.py76
5 files changed, 355 insertions, 0 deletions
diff --git a/challenge-333/lubos-kolouch/README b/challenge-333/lubos-kolouch/README
index 921b2d9f4a..a1e54639cb 100644
--- a/challenge-333/lubos-kolouch/README
+++ b/challenge-333/lubos-kolouch/README
@@ -1 +1,37 @@
Solutions by Lubos Kolouch.
+
+# Perl Weekly Challenge 333
+
+This repository contains solutions for the Perl Weekly Challenge 333, implemented in both Perl and Python. The solutions are written to be clean, efficient, and compliant with coding standards, passing linters such as `Perl::Critic`, `flake8`, `pyupgrade`, and `bandit`. Each solution includes proper documentation, type annotations (where applicable), and unit tests for the provided test cases.
+
+## Task 1: Straight Line
+
+### Problem Statement
+Given a list of coordinates, determine if they form a straight line. Points are collinear if the slope between any pair of points is the same, or if they are vertically aligned (same x-coordinate) or all identical.
+
+### Solution Approach
+- **Perl (ch-1.pl)**: Uses `List::Util::all` to check if points are collinear by comparing cross products of vectors formed by the points to avoid division. Handles special cases like identical points or vertical lines.
+- **Python (ch-1.py)**: Similar approach using list comprehension and type annotations. Checks for collinearity using cross product comparison and handles edge cases.
+
+### Test Cases
+1. Input: `[(2,1), (2,3), (2,5)]` → Output: `True` (vertical line)
+2. Input: `[(1,4), (3,4), (10,4)]` → Output: `True` (horizontal line)
+3. Input: `[(0,0), (1,1), (2,3)]` → Output: `False` (not collinear)
+4. Input: `[(1,1), (1,1), (1,1)]` → Output: `True` (same point)
+5. Input: `[(1000000,1000000), (2000000,2000000), (3000000,3000000)]` → Output: `True` (diagonal line)
+
+## Task 2: Duplicate Zeros
+
+### Problem Statement
+Given an array of integers, duplicate each occurrence of zero, shifting the remaining elements to the right. Elements beyond the original array length are discarded.
+
+### Solution Approach
+- **Perl (ch-2.pl)**: Iterates through the input array, appending each number to the result. For zeros, appends two zeros if space remains within the original length.
+- **Python (ch-2.py)**: Similar logic with type annotations, building a new list while respecting the original length constraint.
+
+### Test Cases
+1. Input: `[1, 0, 2, 3, 0, 4, 5, 0]` → Output: `[1, 0, 0, 2, 3, 0, 0, 4]`
+2. Input: `[1, 2, 3]` → Output: `[1, 2, 3]`
+3. Input: `[1, 2, 3, 0]` → Output: `[1, 2, 3, 0]`
+4. Input: `[0, 0, 1, 2]` → Output: `[0, 0, 0, 0]`
+5. Input: `[1, 2, 0, 3, 4]` → Output: `[1, 2, 0, 0, 3]`
diff --git a/challenge-333/lubos-kolouch/perl/ch-1.pl b/challenge-333/lubos-kolouch/perl/ch-1.pl
new file mode 100644
index 0000000000..629dc362ee
--- /dev/null
+++ b/challenge-333/lubos-kolouch/perl/ch-1.pl
@@ -0,0 +1,77 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+=head1 NAME
+
+ch-1.pl - Perl Weekly Challenge 333, Task 1: Straight Line
+
+=head1 DESCRIPTION
+
+Given a list of coordinates, determine if they form a straight line.
+
+A set of points forms a straight line if they are collinear. This can be checked
+by verifying that the slope between any pair of points is the same (or they are
+all vertically aligned). For points (x1, y1), (x2, y2), (x3, y3), they are
+collinear if (y2 - y1)(x3 - x1) == (y3 - y1)(x2 - x1).
+
+=head1 AUTHOR
+
+[Your Name]
+
+=cut
+
+use List::Util qw(all);
+
+# Type alias for a point (arrayref of two numbers)
+use constant Point => 'ARRAY';
+
+sub is_straight_line {
+ my (@points) = @_;
+
+ # Less than 2 points or all same point are considered straight
+ return 1 if @points < 2 || all { $_->[0] == $points[0][0] && $_->[1] == $points[0][1] } @points;
+
+ # Check if all points are vertically aligned (same x-coordinate)
+ return 1 if all { $_->[0] == $points[0][0] } @points;
+
+ # Compute slope using cross product to avoid division
+ my $dx1 = $points[1][0] - $points[0][0];
+ my $dy1 = $points[1][1] - $points[0][1];
+
+ # Check collinearity for all points against first two
+ return all {
+ my $dx2 = $_->[0] - $points[0][0];
+ my $dy2 = $_->[1] - $points[0][1];
+ $dy1 * $dx2 == $dy2 * $dx1;
+ } @points[ 2 .. $#points ];
+}
+
+# Unit Tests
+use Test::More tests => 5;
+
+subtest 'Example 1' => sub {
+ my @points = ( [ 2, 1 ], [ 2, 3 ], [ 2, 5 ] );
+ ok( is_straight_line(@points), 'Points ([2,1], [2,3], [2,5]) form a straight line' );
+};
+
+subtest 'Example 2' => sub {
+ my @points = ( [ 1, 4 ], [ 3, 4 ], [ 10, 4 ] );
+ ok( is_straight_line(@points), 'Points ([1,4], [3,4], [10,4]) form a straight line' );
+};
+
+subtest 'Example 3' => sub {
+ my @points = ( [ 0, 0 ], [ 1, 1 ], [ 2, 3 ] );
+ ok( !is_straight_line(@points), 'Points ([0,0], [1,1], [2,3]) do not form a straight line' );
+};
+
+subtest 'Example 4' => sub {
+ my @points = ( [ 1, 1 ], [ 1, 1 ], [ 1, 1 ] );
+ ok( is_straight_line(@points), 'Points ([1,1], [1,1], [1,1]) form a straight line' );
+};
+
+subtest 'Example 5' => sub {
+ my @points = ( [ 1000000, 1000000 ], [ 2000000, 2000000 ], [ 3000000, 3000000 ] );
+ ok( is_straight_line(@points),
+ 'Points ([1000000,1000000], [2000000,2000000], [3000000,3000000]) form a straight line' );
+};
diff --git a/challenge-333/lubos-kolouch/perl/ch-2.pl b/challenge-333/lubos-kolouch/perl/ch-2.pl
new file mode 100644
index 0000000000..8d07c9c1db
--- /dev/null
+++ b/challenge-333/lubos-kolouch/perl/ch-2.pl
@@ -0,0 +1,84 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+=head1 NAME
+
+ch-2.pl - Perl Weekly Challenge 333, Task 2: Duplicate Zeros
+
+=head1 DESCRIPTION
+
+Given an array of integers, duplicate each occurrence of zero, shifting the
+remaining elements to the right. Elements beyond the original array length are
+discarded.
+
+=head1 AUTHOR
+
+[Your Name]
+
+=cut
+
+# Type alias for an array of integers
+use constant IntArray => 'ARRAY';
+
+sub duplicate_zeros {
+ my (@ints) = @_;
+
+ my @result;
+ foreach my $num (@ints) {
+ if ( $num == 0 ) {
+
+ # Only add two zeros if there's space within original length
+ push @result, 0 if @result < @ints;
+ push @result, 0 if @result < @ints;
+ }
+ else {
+ # Add non-zero number if there's space
+ push @result, $num if @result < @ints;
+ }
+ }
+ return @result;
+}
+
+# Unit Tests
+use Test::More tests => 5;
+
+subtest 'Example 1' => sub {
+ my @ints = ( 1, 0, 2, 3, 0, 4, 5, 0 );
+ my @expected = ( 1, 0, 0, 2, 3, 0, 0, 4 );
+ my @result = duplicate_zeros(@ints);
+ diag("Input: (@ints), Output: (@result)");
+ is_deeply( [@result], [@expected], 'Array (1,0,2,3,0,4,5,0) becomes (1,0,0,2,3,0,0,4)' );
+};
+
+subtest 'Example 2' => sub {
+ my @ints = ( 1, 2, 3 );
+ my @expected = ( 1, 2, 3 );
+ my @result = duplicate_zeros(@ints);
+ diag("Input: (@ints), Output: (@result)");
+ is_deeply( [@result], [@expected], 'Array (1,2,3) remains (1,2,3)' );
+};
+
+subtest 'Example 3' => sub {
+ my @ints = ( 1, 2, 3, 0 );
+ my @expected = ( 1, 2, 3, 0 );
+ my @result = duplicate_zeros(@ints);
+ diag("Input: (@ints), Output: (@result)");
+ is_deeply( [@result], [@expected], 'Array (1,2,3,0) remains (1,2,3,0)' );
+};
+
+subtest 'Example 4' => sub {
+ my @ints = ( 0, 0, 1, 2 );
+ my @expected = ( 0, 0, 0, 0 );
+ my @result = duplicate_zeros(@ints);
+ diag("Input: (@ints), Output: (@result)");
+ is_deeply( [@result], [@expected], 'Array (0,0,1,2) becomes (0,0,0,0)' );
+};
+
+subtest 'Example 5' => sub {
+ my @ints = ( 1, 2, 0, 3, 4 );
+ my @expected = ( 1, 2, 0, 0, 3 );
+ my @result = duplicate_zeros(@ints);
+ diag("Input: (@ints), Output: (@result)");
+ is_deeply( [@result], [@expected], 'Array (1,2,0,3,4) becomes (1,2,0,0,3)' );
+};
diff --git a/challenge-333/lubos-kolouch/python/ch-1.py b/challenge-333/lubos-kolouch/python/ch-1.py
new file mode 100644
index 0000000000..3776932df1
--- /dev/null
+++ b/challenge-333/lubos-kolouch/python/ch-1.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python3
+"""
+Perl Weekly Challenge 333, Task 1: Straight Line
+
+Given a list of coordinates, determine if they form a straight line.
+
+A set of points forms a straight line if they are collinear. This can be checked
+by verifying that the slope between any pair of points is the same (or they are
+all vertically aligned). For points (x1, y1), (x2, y2), (x3, y3), they are
+collinear if (y2 - y1)(x3 - x1) == (y3 - y1)(x2 - x1).
+
+Author: [Your Name]
+"""
+import unittest
+
+Point = tuple[int, int]
+
+
+def is_straight_line(points: list[Point]) -> bool:
+ """
+ Determine if the given points form a straight line.
+
+ Args:
+ points: List of tuples, each containing x and y coordinates.
+
+ Returns:
+ bool: True if points are collinear, False otherwise.
+ """
+ if len(points) < 2 or all(p[0] == points[0][0] and p[1] == points[0][1]
+ for p in points):
+ return True
+
+ # Check if all points are vertically aligned (same x-coordinate)
+ if all(p[0] == points[0][0] for p in points):
+ return True
+
+ # Compute slope using cross product to avoid division
+ dx1 = points[1][0] - points[0][0]
+ dy1 = points[1][1] - points[0][1]
+
+ # Check collinearity for all points against first two
+ def collinear(index: int) -> bool:
+ dx2 = points[index][0] - points[0][0]
+ dy2 = points[index][1] - points[0][1]
+ return dy2 * dx1 == dx2 * dy1
+
+ return all(collinear(i) for i in range(2, len(points)))
+
+
+# Unit Tests
+
+
+class TestStraightLine(unittest.TestCase):
+
+ def test_example1(self):
+ """Test case: Points ([2,1], [2,3], [2,5]) form a straight line."""
+ points = [(2, 1), (2, 3), (2, 5)]
+ self.assertTrue(is_straight_line(points))
+
+ def test_example2(self):
+ """Test case: Points ([1,4], [3,4], [10,4]) form a straight line."""
+ points = [(1, 4), (3, 4), (10, 4)]
+ self.assertTrue(is_straight_line(points))
+
+ def test_example3(self):
+ """Test case: Points ([0,0], [1,1], [2,3]) do not form a straight line."""
+ points = [(0, 0), (1, 1), (2, 3)]
+ self.assertFalse(is_straight_line(points))
+
+ def test_example4(self):
+ """Test case: Points ([1,1], [1,1], [1,1]) form a straight line."""
+ points = [(1, 1), (1, 1), (1, 1)]
+ self.assertTrue(is_straight_line(points))
+
+ def test_example5(self):
+ """Test case: Points ([1000000,1000000], [2000000,2000000], [3000000,3000000]) form a straight line."""
+ points = [(1000000, 1000000), (2000000, 2000000), (3000000, 3000000)]
+ self.assertTrue(is_straight_line(points))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/challenge-333/lubos-kolouch/python/ch-2.py b/challenge-333/lubos-kolouch/python/ch-2.py
new file mode 100644
index 0000000000..ec8cd6c264
--- /dev/null
+++ b/challenge-333/lubos-kolouch/python/ch-2.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+"""
+Perl Weekly Challenge 333, Task 2: Duplicate Zeros
+
+Given an array of integers, duplicate each occurrence of zero, shifting the
+remaining elements to the right. Elements beyond the original array length are
+discarded.
+
+Author: [Your Name]
+"""
+import unittest
+
+IntArray = list[int]
+
+
+def duplicate_zeros(ints: IntArray) -> IntArray:
+ """
+ Duplicate each zero in the array, shifting elements right within original length.
+
+ Args:
+ ints: List of integers.
+
+ Returns:
+ List[int]: Array with zeros duplicated, truncated to original length.
+ """
+ result = []
+ for num in ints:
+ if num == 0:
+ if len(result) < len(ints):
+ result.append(0)
+ if len(result) < len(ints):
+ result.append(0)
+ else:
+ if len(result) < len(ints):
+ result.append(num)
+ return result
+
+
+# Unit Tests
+
+
+class TestDuplicateZeros(unittest.TestCase):
+
+ def test_example1(self):
+ """Test case: Array (1,0,2,3,0,4,5,0) becomes (1,0,0,2,3,0,0,4)."""
+ ints = [1, 0, 2, 3, 0, 4, 5, 0]
+ expected = [1, 0, 0, 2, 3, 0, 0, 4]
+ self.assertEqual(duplicate_zeros(ints), expected)
+
+ def test_example2(self):
+ """Test case: Array (1,2,3) remains (1,2,3)."""
+ ints = [1, 2, 3]
+ expected = [1, 2, 3]
+ self.assertEqual(duplicate_zeros(ints), expected)
+
+ def test_example3(self):
+ """Test case: Array (1,2,3,0) remains (1,2,3,0)."""
+ ints = [1, 2, 3, 0]
+ expected = [1, 2, 3, 0]
+ self.assertEqual(duplicate_zeros(ints), expected)
+
+ def test_example4(self):
+ """Test case: Array (0,0,1,2) becomes (0,0,0,0)."""
+ ints = [0, 0, 1, 2]
+ expected = [0, 0, 0, 0]
+ self.assertEqual(duplicate_zeros(ints), expected)
+
+ def test_example5(self):
+ """Test case: Array (1,2,0,3,4) becomes (1,2,0,0,3)."""
+ ints = [1, 2, 0, 3, 4]
+ expected = [1, 2, 0, 0, 3]
+ self.assertEqual(duplicate_zeros(ints), expected)
+
+
+if __name__ == '__main__':
+ unittest.main()