diff options
| -rw-r--r-- | challenge-334/sgreen/README.md | 4 | ||||
| -rw-r--r-- | challenge-334/sgreen/blog.txt | 1 | ||||
| -rwxr-xr-x | challenge-334/sgreen/perl/ch-1.pl | 29 | ||||
| -rwxr-xr-x | challenge-334/sgreen/perl/ch-2.pl | 57 | ||||
| -rwxr-xr-x | challenge-334/sgreen/python/ch-1.py | 40 | ||||
| -rwxr-xr-x | challenge-334/sgreen/python/ch-2.py | 66 | ||||
| -rwxr-xr-x | challenge-334/sgreen/python/test.py | 25 |
7 files changed, 220 insertions, 2 deletions
diff --git a/challenge-334/sgreen/README.md b/challenge-334/sgreen/README.md index 8c45461c8c..c346b56b6b 100644 --- a/challenge-334/sgreen/README.md +++ b/challenge-334/sgreen/README.md @@ -1,3 +1,3 @@ -# The Weekly Challenge 333 +# The Weekly Challenge 334 -Blog: [Duplicate Lines](https://dev.to/simongreennet/weekly-challenge-duplicate-lines-6pd) +Blog: [Perl has classes now 👍](https://dev.to/simongreennet/weekly-challenge-perl-has-classes-now-4n8e) diff --git a/challenge-334/sgreen/blog.txt b/challenge-334/sgreen/blog.txt new file mode 100644 index 0000000000..c2bf4eba76 --- /dev/null +++ b/challenge-334/sgreen/blog.txt @@ -0,0 +1 @@ +https://dev.to/simongreennet/weekly-challenge-perl-has-classes-now-4n8e
\ No newline at end of file diff --git a/challenge-334/sgreen/perl/ch-1.pl b/challenge-334/sgreen/perl/ch-1.pl new file mode 100755 index 0000000000..f64ae392db --- /dev/null +++ b/challenge-334/sgreen/perl/ch-1.pl @@ -0,0 +1,29 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use feature 'say'; +use experimental 'signatures'; + +use List::Util 'sum'; + +sub main (@ints) { + my $y = pop @ints; # Last element is y + my $x = pop @ints; # Second last element is x + + # Sanity checks for x and y + if ( $x < 0 or $x > $#ints ) { + die "x must be between 0 and " . $#ints . ", got $x\n"; + } + if ( $y < 0 or $y > $#ints ) { + die "y must be between 0 and " . $#ints . ", got $y\n"; + } + if ( $x > $y ) { + die "x must be less than or equal to y, got x=$x, y=$y\n"; + } + + # Return the sum of the range from x to y (inclusive) + say sum( @ints[ $x .. $y ] ); +} + +main(@ARGV); diff --git a/challenge-334/sgreen/perl/ch-2.pl b/challenge-334/sgreen/perl/ch-2.pl new file mode 100755 index 0000000000..cba99de4dd --- /dev/null +++ b/challenge-334/sgreen/perl/ch-2.pl @@ -0,0 +1,57 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use feature qw(class say); +use experimental 'signatures'; + +no warnings 'experimental::class'; + +class Point { + field $x : param; + field $y : param; + + method x { return $x; } + method y { return $y; } + + method distance_to($other) { + return abs( $x - $other->x ) + abs( $y - $other->y ); + } +} + +sub main (@ints) { + my $x = shift @ints; # First element is x + my $y = shift @ints; # Second element is y + my @points_list = (); + for ( my $i = 0 ; $i < $#ints ; $i += 2 ) { + push @points_list, [ $ints[$i], $ints[ $i + 1 ] ]; + } + + # Convert to Point objects + my $starting_point = Point->new( x => $x, y => $y ); + my @points = map { Point->new( x => $_->[0], y => $_->[1] ) } @points_list; + + # Initialize variables to track the minimum distance and corresponding index + my $min_distance = undef; + my $min_index = -1; + + for my $index ( 0 .. $#points ) { + my $point = $points[$index]; + + # Check if the point shares either x or y coordinate with the starting point + next + if $point->x != $starting_point->x && $point->y != $starting_point->y; + + # Calculate the distance from the starting point to the current point + # and update the minimum distance and index if necessary + my $distance = $starting_point->distance_to($point); + if ( !defined($min_distance) || $distance < $min_distance ) { + $min_distance = $distance; + $min_index = $index; + } + } + + say $min_index; +} + +main(@ARGV); diff --git a/challenge-334/sgreen/python/ch-1.py b/challenge-334/sgreen/python/ch-1.py new file mode 100755 index 0000000000..fa9ce37b44 --- /dev/null +++ b/challenge-334/sgreen/python/ch-1.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +import sys + + +def range_sum(ints: list, x: int, y: int) -> int: + """Calculate the sum of a range in a list of integers. + + Args: + ints (list): A list of integers. + x (int): The starting index of the range (inclusive). + y (int): The ending index of the range (inclusive). + + Returns: + int: The sum of the integers from index x to index y (inclusive). + """ + # Sanity checks for x and y + if x < 0 or x >= len(ints): + raise ValueError(f"x must be between 0 and {len(ints) - 1}, got {x}") + if y < 0 or y >= len(ints): + raise ValueError(f"y must be between 0 and {len(ints) - 1}, got {y}") + if x > y: + raise ValueError( + f"x must be less than or equal to y, got x={x}, y={y}") + + # Return the sum of the range from x to y (inclusive) + return sum(ints[x:y + 1]) + + +def main(): + # Convert input into integers + array = [int(n) for n in sys.argv[1:]] + y = array.pop() # Last element is y + x = array.pop() # Second last element is x + result = range_sum(array, x, y) + print(result) + + +if __name__ == '__main__': + main() diff --git a/challenge-334/sgreen/python/ch-2.py b/challenge-334/sgreen/python/ch-2.py new file mode 100755 index 0000000000..f012c8e3ce --- /dev/null +++ b/challenge-334/sgreen/python/ch-2.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 + +from dataclasses import dataclass +import sys + + +@dataclass(frozen=True) +class Point: + """A point in 2D space with x and y coordinates.""" + x: int + y: int + + def __sub__(self, other: 'Point') -> int: + """Calculate the Manhattan distance between this point and another.""" + return abs(self.x - other.x) + abs(self.y - other.y) + + +def shortest_index(x: int, y: int, points_list: list[list[int]]) -> int: + """Find the index of the point closest to (x, y) that shares either x or y coordinate. + If no such point exists, return -1. + + Args: + x (int): The x coordinate of the starting point. + y (int): The y coordinate of the starting point. + points_list (list[list[int]]): A list of points, each represented as a list of two integers [x, y]. + + Returns: + int: The index of the closest point that shares either x or y coordinate, or -1 if none exists. + """ + + # Turn the input parameters into Point objects + starting_point = Point(x, y) + points = [Point(*point) for point in points_list] + + # Initialize variables to track the minimum distance and corresponding index + min_distance = None + min_index = -1 + + for index, point in enumerate(points): + # Check if the point shares either x or y coordinate with the starting point + if point.x != starting_point.x and point.y != starting_point.y: + continue + + # Calculate the distance from the starting point to the current point + # and update the minimum distance and index if necessary + distance = starting_point - point + if min_distance is None or distance < min_distance: + min_distance = distance + min_index = index + + # Return the index of the closest point, or -1 if no such point was found + return min_index + + +def main(): + # Convert input into integers + array = [int(n) for n in sys.argv[1:]] + x = array.pop(0) # First element is x + y = array.pop(0) # Second element is y + points = [array[i:i + 2] for i in range(0, len(array), 2)] + result = shortest_index(x, y, points) + print(result) + + +if __name__ == '__main__': + main() diff --git a/challenge-334/sgreen/python/test.py b/challenge-334/sgreen/python/test.py new file mode 100755 index 0000000000..98b178d49b --- /dev/null +++ b/challenge-334/sgreen/python/test.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +import unittest +ch_1 = __import__('ch-1') +ch_2 = __import__('ch-2') + + +class TestClass(unittest.TestCase): + def test_ch_1(self): + self.assertEqual(ch_1.range_sum([-2, 0, 3, -5, 2, -1], 0, 2), 1) + self.assertEqual(ch_1.range_sum([1, -2, 3, -4, 5], 1, 3), -3) + self.assertEqual(ch_1.range_sum([1, 0, 2, -1, 3], 3, 4), 2) + self.assertEqual(ch_1.range_sum([-5, 4, -3, 2, -1, 0], 0, 3), -2) + self.assertEqual(ch_1.range_sum([-1, 0, 2, -3, -2, 1], 0, 2), 1) + + def test_ch_2(self): + self.assertEqual(ch_2.shortest_index(3, 4, [[1, 2], [3, 1], [2, 4], [2, 3]]), 2) + self.assertEqual(ch_2.shortest_index(2, 5, [[3, 4], [2, 3], [1, 5], [2, 5]]), 3) + self.assertEqual(ch_2.shortest_index(1, 1, [[2, 2], [3, 3], [4, 4]]), -1) + self.assertEqual(ch_2.shortest_index(0, 0, [[0, 1], [1, 0], [0, 2], [2, 0]]), 0) + self.assertEqual(ch_2.shortest_index(5, 5, [[5, 6], [6, 5], [5, 4], [4, 5]]), 0) + + +if __name__ == '__main__': + unittest.main() |
