From c31911963df6ded34c57931477fb2ad8ac73dc6a Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Thu, 31 Aug 2023 12:06:16 +0100 Subject: [PATCH 01/20] Created harshad_numbers.py --- maths/harshad_numbers.py | 132 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 maths/harshad_numbers.py diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py new file mode 100644 index 000000000000..45175fbb4eac --- /dev/null +++ b/maths/harshad_numbers.py @@ -0,0 +1,132 @@ +""" +A harshad number in a base n is an integer divisible by the sum of its digits in that base. +Reference: https://en.wikipedia.org/wiki/Harshad_number +""" + + +def int_to_base(number, base_of_interest): + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + result = "" + + while number > 0: + number, remainder = divmod(number, base_of_interest) + result = digits[remainder] + result + + if result == "": + result = "0" + + return result + + +def sum_of_digits(num: int, base_of_interest: int): + """ + Calculate the sum of digit values in a positive integer + converted to the given 'base_of_interest'. + Where 'base_of_interest' ranges from 2 to 36. + + Examples: + >>> sum_of_digits(103, 12) + '13' + >>> sum_of_digits(1275, 4) + '30' + >>> sum_of_digits(6645, 2) + '1001' + >>> # bases beyond 36 and below 2 will error + >>> sum_of_digits(543, 1) + Traceback (most recent call last): + ... + ValueError: 'base_of_interest' must be between 36 and 2 inclusive + >>> sum_of_digits(543, 37) + Traceback (most recent call last): + ... + ValueError: 'base_of_interest' must be between 36 and 2 inclusive + """ + + if ((base_of_interest > 36) or (base_of_interest < 2)): + raise ValueError("'base_of_interest' must be between 36 and 2 inclusive") + + num = int_to_base(num, base_of_interest) + sum = 0 + for char in num: + sum += int(char, base_of_interest) + sum = int_to_base(sum, base_of_interest) + return sum + + +def all_harshad_numbers(num: int, base_of_interest: int): + """ + Finds all Harshad numbers smaller than num in base 'base_of_interest'. + Where 'base_of_interest' ranges from 2 to 36. + + Examples: + >>> all_harshad_numbers(15, 2) + (7, ['1', '10', '100', '110', '1000', '1010', '1100']) + >>> all_harshad_numbers(25, 34) + (24, ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O']) + >>> all_harshad_numbers(12, 4) + (7, ['1', '2', '3', '10', '12', '20', '21']) + >>> # bases beyond 36 and below 2 will error + >>> all_harshad_numbers(234, 37) + Traceback (most recent call last): + ... + ValueError: 'base_of_interest' must be between 36 and 2 inclusive + >>> all_harshad_numbers(234, 1) + Traceback (most recent call last): + ... + ValueError: 'base_of_interest' must be between 36 and 2 inclusive + """ + + if ((base_of_interest > 36) or (base_of_interest < 2)): + raise ValueError("'base_of_interest' must be between 36 and 2 inclusive") + + result = 0 + numbers = [] + if (num >= 0): + for i in range(1, num): + y = sum_of_digits(i, base_of_interest) + if (i % int(y, base_of_interest) == 0): + result += 1 + numbers.append(int_to_base(i, base_of_interest)) + + return result, numbers + + +def is_harshad_number(num: int, base_of_interest: int): + """ + Determines whether n in base 'base_of_interest' is a harshad number. + Where 'base_of_interest' ranges from 2 to 36. + + Examples: + >>> is_harshad_number(18, 10) + True + >>> is_harshad_number(21, 10) + True + >>> is_harshad_number(-21, 5) + False + >>> # bases beyond 36 and below 2 will error + >>> is_harshad_number(45, 37) + Traceback (most recent call last): + ... + ValueError: 'base_of_interest' must be between 36 and 2 inclusive + >>> is_harshad_number(45, 1) + Traceback (most recent call last): + ... + ValueError: 'base_of_interest' must be between 36 and 2 inclusive + """ + + if ((base_of_interest > 36) or (base_of_interest < 2)): + raise ValueError("'base_of_interest' must be between 36 and 2 inclusive") + + if (num >= 0): + n = int_to_base(num, base_of_interest) + d = sum_of_digits(num, base_of_interest) + if (int(n, base_of_interest) % int(d, base_of_interest) == 0): + return True + + return False + + +if __name__ == "__main__": + import doctest + + doctest.testmod() \ No newline at end of file From e10bc546ff6ae1fd7cee681a27af3be5a31961a5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 31 Aug 2023 11:07:56 +0000 Subject: [PATCH 02/20] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/harshad_numbers.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 45175fbb4eac..4189aa48a80f 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -11,10 +11,10 @@ def int_to_base(number, base_of_interest): while number > 0: number, remainder = divmod(number, base_of_interest) result = digits[remainder] + result - + if result == "": result = "0" - + return result @@ -42,7 +42,7 @@ def sum_of_digits(num: int, base_of_interest: int): ValueError: 'base_of_interest' must be between 36 and 2 inclusive """ - if ((base_of_interest > 36) or (base_of_interest < 2)): + if (base_of_interest > 36) or (base_of_interest < 2): raise ValueError("'base_of_interest' must be between 36 and 2 inclusive") num = int_to_base(num, base_of_interest) @@ -76,15 +76,15 @@ def all_harshad_numbers(num: int, base_of_interest: int): ValueError: 'base_of_interest' must be between 36 and 2 inclusive """ - if ((base_of_interest > 36) or (base_of_interest < 2)): + if (base_of_interest > 36) or (base_of_interest < 2): raise ValueError("'base_of_interest' must be between 36 and 2 inclusive") result = 0 numbers = [] - if (num >= 0): + if num >= 0: for i in range(1, num): y = sum_of_digits(i, base_of_interest) - if (i % int(y, base_of_interest) == 0): + if i % int(y, base_of_interest) == 0: result += 1 numbers.append(int_to_base(i, base_of_interest)) @@ -114,13 +114,13 @@ def is_harshad_number(num: int, base_of_interest: int): ValueError: 'base_of_interest' must be between 36 and 2 inclusive """ - if ((base_of_interest > 36) or (base_of_interest < 2)): + if (base_of_interest > 36) or (base_of_interest < 2): raise ValueError("'base_of_interest' must be between 36 and 2 inclusive") - if (num >= 0): + if num >= 0: n = int_to_base(num, base_of_interest) d = sum_of_digits(num, base_of_interest) - if (int(n, base_of_interest) % int(d, base_of_interest) == 0): + if int(n, base_of_interest) % int(d, base_of_interest) == 0: return True return False @@ -129,4 +129,4 @@ def is_harshad_number(num: int, base_of_interest: int): if __name__ == "__main__": import doctest - doctest.testmod() \ No newline at end of file + doctest.testmod() From deec6d43eb2b16d0332a6b89adad097f5b4fa376 Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Thu, 31 Aug 2023 12:19:57 +0100 Subject: [PATCH 03/20] Update harshad_numbers.py Fixed a few errors --- maths/harshad_numbers.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 4189aa48a80f..2f5b696c03a9 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -1,5 +1,5 @@ """ -A harshad number in a base n is an integer divisible by the sum of its digits in that base. +A Harshad number is divisible by the sum of its digits in any base n. Reference: https://en.wikipedia.org/wiki/Harshad_number """ @@ -46,11 +46,11 @@ def sum_of_digits(num: int, base_of_interest: int): raise ValueError("'base_of_interest' must be between 36 and 2 inclusive") num = int_to_base(num, base_of_interest) - sum = 0 + res = 0 for char in num: - sum += int(char, base_of_interest) - sum = int_to_base(sum, base_of_interest) - return sum + res += int(char, base_of_interest) + res = int_to_base(res, base_of_interest) + return res def all_harshad_numbers(num: int, base_of_interest: int): @@ -61,8 +61,8 @@ def all_harshad_numbers(num: int, base_of_interest: int): Examples: >>> all_harshad_numbers(15, 2) (7, ['1', '10', '100', '110', '1000', '1010', '1100']) - >>> all_harshad_numbers(25, 34) - (24, ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O']) + >>> all_harshad_numbers(12, 34) + (11, ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B']) >>> all_harshad_numbers(12, 4) (7, ['1', '2', '3', '10', '12', '20', '21']) >>> # bases beyond 36 and below 2 will error From fcb5639f11938c3af25a2abb9396004ff6329619 Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Thu, 31 Aug 2023 12:29:38 +0100 Subject: [PATCH 04/20] Update harshad_numbers.py Added function type hints --- maths/harshad_numbers.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 2f5b696c03a9..0c830ba5372b 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -3,8 +3,10 @@ Reference: https://en.wikipedia.org/wiki/Harshad_number """ +from typing import Tuple, List -def int_to_base(number, base_of_interest): + +def int_to_base(number: int, base_of_interest: int) -> str: digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" result = "" @@ -18,7 +20,7 @@ def int_to_base(number, base_of_interest): return result -def sum_of_digits(num: int, base_of_interest: int): +def sum_of_digits(num: int, base_of_interest: int) -> str: """ Calculate the sum of digit values in a positive integer converted to the given 'base_of_interest'. @@ -53,7 +55,7 @@ def sum_of_digits(num: int, base_of_interest: int): return res -def all_harshad_numbers(num: int, base_of_interest: int): +def all_harshad_numbers(num: int, base_of_interest: int) -> Tuple[int, List[str]]: """ Finds all Harshad numbers smaller than num in base 'base_of_interest'. Where 'base_of_interest' ranges from 2 to 36. @@ -91,7 +93,7 @@ def all_harshad_numbers(num: int, base_of_interest: int): return result, numbers -def is_harshad_number(num: int, base_of_interest: int): +def is_harshad_number(num: int, base_of_interest: int) -> bool: """ Determines whether n in base 'base_of_interest' is a harshad number. Where 'base_of_interest' ranges from 2 to 36. From 44eb28623bff4700d879f2fc623cf1bf58854acb Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Thu, 31 Aug 2023 12:33:15 +0100 Subject: [PATCH 05/20] Update harshad_numbers.py Fixed depreciated Tuple and List usage --- maths/harshad_numbers.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 0c830ba5372b..7edf639794b2 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -3,8 +3,6 @@ Reference: https://en.wikipedia.org/wiki/Harshad_number """ -from typing import Tuple, List - def int_to_base(number: int, base_of_interest: int) -> str: digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -55,7 +53,7 @@ def sum_of_digits(num: int, base_of_interest: int) -> str: return res -def all_harshad_numbers(num: int, base_of_interest: int) -> Tuple[int, List[str]]: +def all_harshad_numbers(num: int, base_of_interest: int) -> tuple[int, list[str]]: """ Finds all Harshad numbers smaller than num in base 'base_of_interest'. Where 'base_of_interest' ranges from 2 to 36. From ad09b82e537d8e8c1c23cdd0cbabc0506296607a Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Thu, 31 Aug 2023 12:41:47 +0100 Subject: [PATCH 06/20] Update harshad_numbers.py Fixed incompatible types in assignments --- maths/harshad_numbers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 7edf639794b2..eac554a95bf0 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -45,9 +45,9 @@ def sum_of_digits(num: int, base_of_interest: int) -> str: if (base_of_interest > 36) or (base_of_interest < 2): raise ValueError("'base_of_interest' must be between 36 and 2 inclusive") - num = int_to_base(num, base_of_interest) + num_str = int_to_base(num, base_of_interest) res = 0 - for char in num: + for char in num_str: res += int(char, base_of_interest) res = int_to_base(res, base_of_interest) return res From 3d00dad53518e3570aa4771667a8a51e567106d4 Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Thu, 31 Aug 2023 12:44:53 +0100 Subject: [PATCH 07/20] Update harshad_numbers.py Fixed incompatible type assignments --- maths/harshad_numbers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index eac554a95bf0..489be3c29cfc 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -49,8 +49,8 @@ def sum_of_digits(num: int, base_of_interest: int) -> str: res = 0 for char in num_str: res += int(char, base_of_interest) - res = int_to_base(res, base_of_interest) - return res + res_str = int_to_base(res, base_of_interest) + return res_str def all_harshad_numbers(num: int, base_of_interest: int) -> tuple[int, list[str]]: From 4d1a89cd294783db1b01d253eee817a7f4774ffc Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Tue, 5 Sep 2023 11:06:53 +0100 Subject: [PATCH 08/20] Update maths/harshad_numbers.py Co-authored-by: Tianyi Zheng --- maths/harshad_numbers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 489be3c29cfc..aba49674b508 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -4,7 +4,7 @@ """ -def int_to_base(number: int, base_of_interest: int) -> str: +def int_to_base(number: int, base: int) -> str: digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" result = "" From 21a703d4952e7093ab54a989f00119aba81816a7 Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Tue, 5 Sep 2023 11:07:07 +0100 Subject: [PATCH 09/20] Update maths/harshad_numbers.py Co-authored-by: Tianyi Zheng --- maths/harshad_numbers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index aba49674b508..8a5beb6f5ff2 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -18,7 +18,7 @@ def int_to_base(number: int, base: int) -> str: return result -def sum_of_digits(num: int, base_of_interest: int) -> str: +def sum_of_digits(num: int, base: int) -> str: """ Calculate the sum of digit values in a positive integer converted to the given 'base_of_interest'. From 1584436dfa7150c357973d45bac5e046c0e47bb6 Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:24:02 +0100 Subject: [PATCH 10/20] Raised Value Error for negative inputs --- maths/harshad_numbers.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 8a5beb6f5ff2..b000bc0759ff 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -8,6 +8,9 @@ def int_to_base(number: int, base: int) -> str: digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" result = "" + if number < 0: + raise ValueError("number must be a positive integer") + while number > 0: number, remainder = divmod(number, base_of_interest) result = digits[remainder] + result @@ -21,8 +24,8 @@ def int_to_base(number: int, base: int) -> str: def sum_of_digits(num: int, base: int) -> str: """ Calculate the sum of digit values in a positive integer - converted to the given 'base_of_interest'. - Where 'base_of_interest' ranges from 2 to 36. + converted to the given 'base'. + Where 'base' ranges from 2 to 36. Examples: >>> sum_of_digits(103, 12) @@ -39,17 +42,17 @@ def sum_of_digits(num: int, base: int) -> str: >>> sum_of_digits(543, 37) Traceback (most recent call last): ... - ValueError: 'base_of_interest' must be between 36 and 2 inclusive + ValueError: 'base' must be between 36 and 2 inclusive """ - if (base_of_interest > 36) or (base_of_interest < 2): - raise ValueError("'base_of_interest' must be between 36 and 2 inclusive") + if (base > 36) or (base < 2): + raise ValueError("'base' must be between 36 and 2 inclusive") - num_str = int_to_base(num, base_of_interest) + num_str = int_to_base(num, base) res = 0 for char in num_str: - res += int(char, base_of_interest) - res_str = int_to_base(res, base_of_interest) + res += int(char, base) + res_str = int_to_base(res, base) return res_str From 7b9809cb971c0406bad16abe60939a8bff3eecdc Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:27:51 +0100 Subject: [PATCH 11/20] Update maths/harshad_numbers.py Co-authored-by: Tianyi Zheng --- maths/harshad_numbers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index b000bc0759ff..3c21d93ff27d 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -56,7 +56,7 @@ def sum_of_digits(num: int, base: int) -> str: return res_str -def all_harshad_numbers(num: int, base_of_interest: int) -> tuple[int, list[str]]: +def harshad_numbers_in_base(limit: int, base: int) -> list[str]: """ Finds all Harshad numbers smaller than num in base 'base_of_interest'. Where 'base_of_interest' ranges from 2 to 36. From 03d0296aaf7a946f98a3ba3c11ade2b3d812b1b3 Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:31:09 +0100 Subject: [PATCH 12/20] Update maths/harshad_numbers.py Co-authored-by: Tianyi Zheng --- maths/harshad_numbers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 3c21d93ff27d..286d9f305384 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -94,7 +94,7 @@ def harshad_numbers_in_base(limit: int, base: int) -> list[str]: return result, numbers -def is_harshad_number(num: int, base_of_interest: int) -> bool: +def is_harshad_number_in_base(num: int, base: int) -> bool: """ Determines whether n in base 'base_of_interest' is a harshad number. Where 'base_of_interest' ranges from 2 to 36. From 2974289dc52e2c34e2f4dc9c18111e6363038bef Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:31:28 +0100 Subject: [PATCH 13/20] Update maths/harshad_numbers.py Co-authored-by: Tianyi Zheng --- maths/harshad_numbers.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 286d9f305384..2d0340fa2f01 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -120,13 +120,12 @@ def is_harshad_number_in_base(num: int, base: int) -> bool: if (base_of_interest > 36) or (base_of_interest < 2): raise ValueError("'base_of_interest' must be between 36 and 2 inclusive") - if num >= 0: - n = int_to_base(num, base_of_interest) - d = sum_of_digits(num, base_of_interest) - if int(n, base_of_interest) % int(d, base_of_interest) == 0: - return True + if num < 0: + return False - return False + n = int_to_base(num, base_of_interest) + d = sum_of_digits(num, base_of_interest) + return int(n, base_of_interest) % int(d, base_of_interest) == 0 if __name__ == "__main__": From 6ebaf2589e42e6c9f7abb64139c5fba9a994d14d Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:38:14 +0100 Subject: [PATCH 14/20] Update harshad_numbers.py --- maths/harshad_numbers.py | 61 ++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 2d0340fa2f01..91f302f69526 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -1,5 +1,6 @@ """ -A Harshad number is divisible by the sum of its digits in any base n. +A harshad number (or more specifically an n-harshad number) is a number that's +divisible by the sum of its digits in some given base n. Reference: https://en.wikipedia.org/wiki/Harshad_number """ @@ -12,7 +13,7 @@ def int_to_base(number: int, base: int) -> str: raise ValueError("number must be a positive integer") while number > 0: - number, remainder = divmod(number, base_of_interest) + number, remainder = divmod(number, base) result = digits[remainder] + result if result == "": @@ -58,74 +59,74 @@ def sum_of_digits(num: int, base: int) -> str: def harshad_numbers_in_base(limit: int, base: int) -> list[str]: """ - Finds all Harshad numbers smaller than num in base 'base_of_interest'. - Where 'base_of_interest' ranges from 2 to 36. + Finds all Harshad numbers smaller than num in base 'base'. + Where 'base' ranges from 2 to 36. Examples: - >>> all_harshad_numbers(15, 2) + >>> harshad_numbers_in_base(15, 2) (7, ['1', '10', '100', '110', '1000', '1010', '1100']) - >>> all_harshad_numbers(12, 34) + >>> harshad_numbers_in_base(12, 34) (11, ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B']) - >>> all_harshad_numbers(12, 4) + >>> harshad_numbers_in_base(12, 4) (7, ['1', '2', '3', '10', '12', '20', '21']) >>> # bases beyond 36 and below 2 will error - >>> all_harshad_numbers(234, 37) + >>> harshad_numbers_in_base(234, 37) Traceback (most recent call last): ... - ValueError: 'base_of_interest' must be between 36 and 2 inclusive - >>> all_harshad_numbers(234, 1) + ValueError: 'base' must be between 36 and 2 inclusive + >>> harshad_numbers_in_base(234, 1) Traceback (most recent call last): ... - ValueError: 'base_of_interest' must be between 36 and 2 inclusive + ValueError: 'base' must be between 36 and 2 inclusive """ - if (base_of_interest > 36) or (base_of_interest < 2): - raise ValueError("'base_of_interest' must be between 36 and 2 inclusive") + if (base > 36) or (base < 2): + raise ValueError("'base' must be between 36 and 2 inclusive") result = 0 numbers = [] if num >= 0: for i in range(1, num): - y = sum_of_digits(i, base_of_interest) - if i % int(y, base_of_interest) == 0: + y = sum_of_digits(i, base) + if i % int(y, base) == 0: result += 1 - numbers.append(int_to_base(i, base_of_interest)) + numbers.append(int_to_base(i, base)) return result, numbers def is_harshad_number_in_base(num: int, base: int) -> bool: """ - Determines whether n in base 'base_of_interest' is a harshad number. - Where 'base_of_interest' ranges from 2 to 36. + Determines whether n in base 'base' is a harshad number. + Where 'base' ranges from 2 to 36. Examples: - >>> is_harshad_number(18, 10) + >>> is_harshad_number_in_base(18, 10) True - >>> is_harshad_number(21, 10) + >>> is_harshad_number_in_base(21, 10) True - >>> is_harshad_number(-21, 5) + >>> is_harshad_number_in_base(-21, 5) False >>> # bases beyond 36 and below 2 will error - >>> is_harshad_number(45, 37) + >>> is_harshad_number_in_base(45, 37) Traceback (most recent call last): ... - ValueError: 'base_of_interest' must be between 36 and 2 inclusive - >>> is_harshad_number(45, 1) + ValueError: 'base' must be between 36 and 2 inclusive + >>> is_harshad_number_in_base(45, 1) Traceback (most recent call last): ... - ValueError: 'base_of_interest' must be between 36 and 2 inclusive + ValueError: 'base' must be between 36 and 2 inclusive """ - if (base_of_interest > 36) or (base_of_interest < 2): - raise ValueError("'base_of_interest' must be between 36 and 2 inclusive") + if (base > 36) or (base < 2): + raise ValueError("'base' must be between 36 and 2 inclusive") if num < 0: return False - n = int_to_base(num, base_of_interest) - d = sum_of_digits(num, base_of_interest) - return int(n, base_of_interest) % int(d, base_of_interest) == 0 + n = int_to_base(num, base) + d = sum_of_digits(num, base) + return int(n, base) % int(d, base) == 0 if __name__ == "__main__": From 04f1e2b19e29b17e8f8c89ccc14d41582665e84e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 18:39:33 +0000 Subject: [PATCH 15/20] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/harshad_numbers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 91f302f69526..eabd31f165d4 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -1,5 +1,5 @@ """ -A harshad number (or more specifically an n-harshad number) is a number that's +A harshad number (or more specifically an n-harshad number) is a number that's divisible by the sum of its digits in some given base n. Reference: https://en.wikipedia.org/wiki/Harshad_number """ From 6b0243c5f2f01b6eda450e884ef0bc5bfa8b4296 Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:52:20 +0100 Subject: [PATCH 16/20] Update harshad_numbers.py --- maths/harshad_numbers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index eabd31f165d4..f23fea57ff0a 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -85,8 +85,8 @@ def harshad_numbers_in_base(limit: int, base: int) -> list[str]: result = 0 numbers = [] - if num >= 0: - for i in range(1, num): + if limit >= 0: + for i in range(1, limit): y = sum_of_digits(i, base) if i % int(y, base) == 0: result += 1 From 385c29495423ffbf87f49d953928613d372a7cb4 Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Wed, 6 Sep 2023 01:29:01 +0100 Subject: [PATCH 17/20] Update harshad_numbers.py --- maths/harshad_numbers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index f23fea57ff0a..7ee058875e24 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -39,7 +39,7 @@ def sum_of_digits(num: int, base: int) -> str: >>> sum_of_digits(543, 1) Traceback (most recent call last): ... - ValueError: 'base_of_interest' must be between 36 and 2 inclusive + ValueError: 'base' must be between 36 and 2 inclusive >>> sum_of_digits(543, 37) Traceback (most recent call last): ... From edf0036cda4ec9abc750cabcccd517a684e33f0b Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Wed, 6 Sep 2023 01:34:45 +0100 Subject: [PATCH 18/20] Update harshad_numbers.py --- maths/harshad_numbers.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 7ee058875e24..6f084289af4b 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -64,11 +64,11 @@ def harshad_numbers_in_base(limit: int, base: int) -> list[str]: Examples: >>> harshad_numbers_in_base(15, 2) - (7, ['1', '10', '100', '110', '1000', '1010', '1100']) + ['1', '10', '100', '110', '1000', '1010', '1100'] >>> harshad_numbers_in_base(12, 34) - (11, ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B']) + ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B'] >>> harshad_numbers_in_base(12, 4) - (7, ['1', '2', '3', '10', '12', '20', '21']) + ['1', '2', '3', '10', '12', '20', '21'] >>> # bases beyond 36 and below 2 will error >>> harshad_numbers_in_base(234, 37) Traceback (most recent call last): @@ -83,16 +83,14 @@ def harshad_numbers_in_base(limit: int, base: int) -> list[str]: if (base > 36) or (base < 2): raise ValueError("'base' must be between 36 and 2 inclusive") - result = 0 numbers = [] if limit >= 0: for i in range(1, limit): y = sum_of_digits(i, base) if i % int(y, base) == 0: - result += 1 numbers.append(int_to_base(i, base)) - return result, numbers + return numbers def is_harshad_number_in_base(num: int, base: int) -> bool: From 8dbfa37288ac8c8217f6762e0121ffd11a9af8ab Mon Sep 17 00:00:00 2001 From: David Ekong <66387173+davidekong@users.noreply.github.com> Date: Wed, 6 Sep 2023 13:03:28 +0100 Subject: [PATCH 19/20] Update harshad_numbers.py Added doc test to int_to_base, fixed nested loop, other minor changes --- maths/harshad_numbers.py | 73 +++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 6f084289af4b..7e1347d50661 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -6,6 +6,31 @@ def int_to_base(number: int, base: int) -> str: + """ + Convert a given positive decimal integer to base 'base'. + Where 'base' ranges from 2 to 36. + + Examples: + >>> int_to_base(23, 2) + '10111' + >>> int_to_base(58, 5) + '213' + >>> int_to_base(167, 16) + 'A7' + >>> # bases below 2 and beyond 36 will error + >>> int_to_base(98, 1) + Traceback (most recent call last): + ... + ValueError: 'base' must be between 2 and 36 inclusive + >>> int_to_base(98, 37) + Traceback (most recent call last): + ... + ValueError: 'base' must be between 2 and 36 inclusive + """ + + if base < 2 or base > 36: + raise ValueError("'base' must be between 2 and 36 inclusive") + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" result = "" @@ -35,24 +60,22 @@ def sum_of_digits(num: int, base: int) -> str: '30' >>> sum_of_digits(6645, 2) '1001' - >>> # bases beyond 36 and below 2 will error + >>> # bases below 2 and beyond 36 will error >>> sum_of_digits(543, 1) Traceback (most recent call last): ... - ValueError: 'base' must be between 36 and 2 inclusive + ValueError: 'base' must be between 2 and 36 inclusive >>> sum_of_digits(543, 37) Traceback (most recent call last): ... - ValueError: 'base' must be between 36 and 2 inclusive + ValueError: 'base' must be between 2 and 36 inclusive """ - if (base > 36) or (base < 2): - raise ValueError("'base' must be between 36 and 2 inclusive") + if base < 2 or base > 36: + raise ValueError("'base' must be between 2 and 36 inclusive") num_str = int_to_base(num, base) - res = 0 - for char in num_str: - res += int(char, base) + res = sum(int(char, base) for char in num_str) res_str = int_to_base(res, base) return res_str @@ -69,26 +92,28 @@ def harshad_numbers_in_base(limit: int, base: int) -> list[str]: ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B'] >>> harshad_numbers_in_base(12, 4) ['1', '2', '3', '10', '12', '20', '21'] - >>> # bases beyond 36 and below 2 will error + >>> # bases below 2 and beyond 36 will error >>> harshad_numbers_in_base(234, 37) Traceback (most recent call last): ... - ValueError: 'base' must be between 36 and 2 inclusive + ValueError: 'base' must be between 2 and 36 inclusive >>> harshad_numbers_in_base(234, 1) Traceback (most recent call last): ... - ValueError: 'base' must be between 36 and 2 inclusive + ValueError: 'base' must be between 2 and 36 inclusive """ - if (base > 36) or (base < 2): - raise ValueError("'base' must be between 36 and 2 inclusive") + if base < 2 or base > 36: + raise ValueError("'base' must be between 2 and 36 inclusive") - numbers = [] - if limit >= 0: - for i in range(1, limit): - y = sum_of_digits(i, base) - if i % int(y, base) == 0: - numbers.append(int_to_base(i, base)) + if limit < 0: + return [] + + numbers = [ + int_to_base(i, base) + for i in range(1, limit) + if i % int(sum_of_digits(i, base), base) == 0 + ] return numbers @@ -105,19 +130,19 @@ def is_harshad_number_in_base(num: int, base: int) -> bool: True >>> is_harshad_number_in_base(-21, 5) False - >>> # bases beyond 36 and below 2 will error + >>> # bases below 2 and beyond 36 will error >>> is_harshad_number_in_base(45, 37) Traceback (most recent call last): ... - ValueError: 'base' must be between 36 and 2 inclusive + ValueError: 'base' must be between 2 and 36 inclusive >>> is_harshad_number_in_base(45, 1) Traceback (most recent call last): ... - ValueError: 'base' must be between 36 and 2 inclusive + ValueError: 'base' must be between 2 and 36 inclusive """ - if (base > 36) or (base < 2): - raise ValueError("'base' must be between 36 and 2 inclusive") + if base < 2 or base > 36: + raise ValueError("'base' must be between 2 and 36 inclusive") if num < 0: return False From d4d9c7c2fd465e139ed37ed80ae9961a7df6c97e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 12:04:03 +0000 Subject: [PATCH 20/20] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/harshad_numbers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths/harshad_numbers.py b/maths/harshad_numbers.py index 7e1347d50661..050c69e0bd15 100644 --- a/maths/harshad_numbers.py +++ b/maths/harshad_numbers.py @@ -108,7 +108,7 @@ def harshad_numbers_in_base(limit: int, base: int) -> list[str]: if limit < 0: return [] - + numbers = [ int_to_base(i, base) for i in range(1, limit)