From f19002c7996242fdd39b30066e00083c5d1021f6 Mon Sep 17 00:00:00 2001 From: Simon Green Date: Sun, 17 Aug 2025 21:09:26 +1000 Subject: sgreen solutions to challenge 334 --- challenge-334/sgreen/python/ch-1.py | 40 ++++++++++++++++++++++ challenge-334/sgreen/python/ch-2.py | 66 +++++++++++++++++++++++++++++++++++++ challenge-334/sgreen/python/test.py | 25 ++++++++++++++ 3 files changed, 131 insertions(+) create mode 100755 challenge-334/sgreen/python/ch-1.py create mode 100755 challenge-334/sgreen/python/ch-2.py create mode 100755 challenge-334/sgreen/python/test.py (limited to 'challenge-334/sgreen/python') 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() -- cgit