From dc6098965d5b57fca238f71bb3d8c8d2cfa408f4 Mon Sep 17 00:00:00 2001 From: Andrew Grangaard Date: Wed, 11 Oct 2023 22:23:25 -0700 Subject: feature: Add TWC 238 python solution by @spazm with pretty modulino unittests --- challenge-238/spazm/python/task_1_running_sum.py | 66 ++++++++++++++++ .../spazm/python/task_2_persistence_sort.py | 91 ++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100755 challenge-238/spazm/python/task_1_running_sum.py create mode 100755 challenge-238/spazm/python/task_2_persistence_sort.py diff --git a/challenge-238/spazm/python/task_1_running_sum.py b/challenge-238/spazm/python/task_1_running_sum.py new file mode 100755 index 0000000000..391fb82cfa --- /dev/null +++ b/challenge-238/spazm/python/task_1_running_sum.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 + +from typing import Iterable + + +def running_sum(nums: list[int]) -> list[int]: + """ + You are given an array of integers. + + Write a script to return the running sum of the given array. + The running sum can be calculated as sum[i] = num[0] + num[1] + …. + num[i] + + Example 1 + Input: @int = (1, 2, 3, 4, 5) + Output: (1, 3, 6, 10, 15) + >>> assert (1, 3, 6, 10, 15) == running_sum([1, 2, 3, 4, 5]) + Example 2 + Input: @int = (1, 1, 1, 1, 1) + Output: (1, 2, 3, 4, 5) + >>> assert (1, 2, 3, 4, 5) == running_sum([1, 1, 1, 1, 1]) + Example 3 + Input: @int = (0, -1, 1, 2) + Output: (0, -1, 0, 2) + >>> assert ( 0, -1, 0, 2) == running_sum([0, -1, 1, 2]) + """ + return list(running_sum_it(nums)) + + +def running_sum_it(nums: list[int]) -> Iterable[int]: + """ + You are given an array of integers. + + return an iterator of the running sum of the given array. + The running sum can be calculated as sum[i] = num[0] + num[1] + …. + num[i] + + Example 1 + Input: @int = (1, 2, 3, 4, 5) + Output: (1, 3, 6, 10, 15) + >>> assert (1, 3, 6, 10, 15) == list(running_sum([1, 2, 3, 4, 5])) + Example 2 + Input: @int = (1, 1, 1, 1, 1) + Output: (1, 2, 3, 4, 5) + >>> assert (1, 2, 3, 4, 5) == list(running_sum([1, 1, 1, 1, 1])) + Example 3 + Input: @int = (0, -1, 1, 2) + Output: (0, -1, 0, 2) + >>> assert ( 0, -1, 0, 2) == list(running_sum([0, -1, 1, 2])) + """ + + current_sum = 0 + for i in nums: + current_sum += i + yield current_sum + + +if __name__ == "__main__": + import unittest + + tests = [ + ([1, 2, 3, 4, 5], [1, 3, 6, 10, 15]), + ([1, 1, 1, 1, 1], [1, 2, 3, 4, 5]), + ([0, -1, 1, 2], [0, -1, 0, 2]), + ] + tester = unittest.TestCase() + for input, expected in tests: + tester.assertEqual(expected, running_sum(input)) diff --git a/challenge-238/spazm/python/task_2_persistence_sort.py b/challenge-238/spazm/python/task_2_persistence_sort.py new file mode 100755 index 0000000000..1278bac699 --- /dev/null +++ b/challenge-238/spazm/python/task_2_persistence_sort.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 + + +def persistence_sort(ints: list[int]) -> list[int]: + """ + You are given an array of positive integers. + + Write a script to sort the given array in increasing order with respect to + the count of steps required to obtain a single-digit number by multiplying + its digits recursively for each array element. If any two numbers have the + same count of steps, then print the smaller number first. + + Example 1 + Input: @int = (15, 99, 1, 34) + Output: (1, 15, 34, 99) + + >>> persistence_sort([15, 99, 1, 34]) == [1, 15, 34, 99] + + 15 => 1 x 5 => 5 (1 step) + 99 => 9 x 9 => 81 => 8 x 1 => 8 (2 steps) + 1 => 0 step + 34 => 3 x 4 => 12 => 1 x 2 => 2 (2 steps) + Example 2 + Input: @int = (50, 25, 33, 22) + Output: (22, 33, 50, 25) + + 50 => 5 x 0 => 0 (1 step) + 25 => 2 x 5 => 10 => 1 x 0 => 0 (2 steps) + 33 => 3 x 3 => 9 (1 step) + 22 => 2 x 2 => 4 (1 step) + """ + + return sorted(ints, key=persistence_sort_key) + + +def persistence_sort_key(x): + steps_x = single_digit_multiplication_steps(x) + return (steps_x, x) + + +def single_digit_multiplication_steps(num: int) -> int: + """ + Given a multiple-digit number, multiply its digits recursively and return + the number of steps required to obtain a single-digit number. + + >>> single_digit_multiplication_steps(50) == 1 + >>> single_digit_multiplication_steps(25) == 2 + >>> single_digit_multiplication_steps(33) == 1 + >>> single_digit_multiplication_steps(22) == 1 + >>> single_digit_multiplication_steps(99) == 2 + >>> single_digit_multiplication_steps(81) == 1 + >>> single_digit_multiplication_steps(14) == 1 + >>> single_digit_multiplication_steps(98) == 3 + >>> single_digit_multiplication_steps(72) == 2 + >>> single_digit_multiplication_steps(14) == 1 + """ + + product = 1 + for digit in str(num): + product *= int(digit) + + if product < 10: + return 1 + else: + return 1 + single_digit_multiplication_steps(product) + + +if __name__ == "__main__": + import unittest + + tester = unittest.TestCase() + + multiplication_steps_tests = [ + (50, 1), + (25, 2), + (33, 1), + (22, 1), + (99, 2), + (81, 1), + (98, 3), + (72, 2), + (14, 1), + ] + for input, expected in multiplication_steps_tests: + tester.assertEqual( + expected, single_digit_multiplication_steps(input), f"input: {input}" + ) + + persistence_sort_tests = [([15, 99, 1, 34], [1, 15, 34, 99])] + for input, expected in persistence_sort_tests: + tester.assertEqual(expected, persistence_sort(input), f"input: {input}") -- cgit