-
-
Notifications
You must be signed in to change notification settings - Fork 46.6k
Created harshad_numbers.py #9023
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 12 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
c319119
Created harshad_numbers.py
davidekong e10bc54
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] deec6d4
Update harshad_numbers.py
davidekong fcb5639
Update harshad_numbers.py
davidekong 44eb286
Update harshad_numbers.py
davidekong ad09b82
Update harshad_numbers.py
davidekong 3d00dad
Update harshad_numbers.py
davidekong 4d1a89c
Update maths/harshad_numbers.py
davidekong 21a703d
Update maths/harshad_numbers.py
davidekong 1584436
Raised Value Error for negative inputs
davidekong 7b9809c
Update maths/harshad_numbers.py
davidekong 03d0296
Update maths/harshad_numbers.py
davidekong 2974289
Update maths/harshad_numbers.py
davidekong 6ebaf25
Update harshad_numbers.py
davidekong 04f1e2b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 6b0243c
Update harshad_numbers.py
davidekong 385c294
Update harshad_numbers.py
davidekong edf0036
Update harshad_numbers.py
davidekong 8dbfa37
Update harshad_numbers.py
davidekong d4d9c7c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,135 @@ | ||||||||||
""" | ||||||||||
A Harshad number is divisible by the sum of its digits in any base n. | ||||||||||
Reference: https://en.wikipedia.org/wiki/Harshad_number | ||||||||||
""" | ||||||||||
|
||||||||||
|
||||||||||
def int_to_base(number: int, base: int) -> str: | ||||||||||
davidekong marked this conversation as resolved.
Show resolved
Hide resolved
davidekong marked this conversation as resolved.
Show resolved
Hide resolved
davidekong marked this conversation as resolved.
Show resolved
Hide resolved
davidekong marked this conversation as resolved.
Show resolved
Hide resolved
davidekong marked this conversation as resolved.
Show resolved
Hide resolved
davidekong marked this conversation as resolved.
Show resolved
Hide resolved
davidekong marked this conversation as resolved.
Show resolved
Hide resolved
davidekong marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" | ||||||||||
result = "" | ||||||||||
|
||||||||||
if number < 0: | ||||||||||
raise ValueError("number must be a positive integer") | ||||||||||
|
||||||||||
while number > 0: | ||||||||||
davidekong marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
number, remainder = divmod(number, base_of_interest) | ||||||||||
result = digits[remainder] + result | ||||||||||
|
||||||||||
if result == "": | ||||||||||
result = "0" | ||||||||||
|
||||||||||
return result | ||||||||||
|
||||||||||
|
||||||||||
def sum_of_digits(num: int, base: int) -> str: | ||||||||||
""" | ||||||||||
Calculate the sum of digit values in a positive integer | ||||||||||
converted to the given 'base'. | ||||||||||
Where 'base' 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' must be between 36 and 2 inclusive | ||||||||||
""" | ||||||||||
|
||||||||||
if (base > 36) or (base < 2): | ||||||||||
raise ValueError("'base' must be between 36 and 2 inclusive") | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Parentheses are unnecessary, and it's kinda strange to read the range backward |
||||||||||
|
||||||||||
num_str = int_to_base(num, base) | ||||||||||
res = 0 | ||||||||||
for char in num_str: | ||||||||||
res += int(char, base) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Let's avoid manually looping when possible |
||||||||||
res_str = int_to_base(res, base) | ||||||||||
return res_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. | ||||||||||
|
||||||||||
Examples: | ||||||||||
>>> all_harshad_numbers(15, 2) | ||||||||||
(7, ['1', '10', '100', '110', '1000', '1010', '1100']) | ||||||||||
>>> 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 | ||||||||||
>>> 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_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. | ||||||||||
|
||||||||||
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 | ||||||||||
davidekong marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
|
||||||||||
if __name__ == "__main__": | ||||||||||
import doctest | ||||||||||
|
||||||||||
doctest.testmod() |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpicks: