-
-
Notifications
You must be signed in to change notification settings - Fork 46.8k
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
Changes from 16 commits
c319119
e10bc54
deec6d4
fcb5639
44eb286
ad09b82
3d00dad
4d1a89c
21a703d
1584436
7b9809c
03d0296
2974289
6ebaf25
04f1e2b
6b0243c
385c294
edf0036
8dbfa37
d4d9c7c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,135 @@ | ||||||||||
""" | ||||||||||
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 | ||||||||||
""" | ||||||||||
|
||||||||||
|
||||||||||
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
|
||||||||||
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) | ||||||||||
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'. | ||||||||||
Where 'base' ranges from 2 to 36. | ||||||||||
|
||||||||||
Examples: | ||||||||||
>>> harshad_numbers_in_base(15, 2) | ||||||||||
(7, ['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']) | ||||||||||
>>> harshad_numbers_in_base(12, 4) | ||||||||||
(7, ['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): | ||||||||||
... | ||||||||||
ValueError: 'base' must be between 36 and 2 inclusive | ||||||||||
>>> harshad_numbers_in_base(234, 1) | ||||||||||
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
See previous comment |
||||||||||
|
||||||||||
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 | ||||||||||
|
||||||||||
|
||||||||||
def is_harshad_number_in_base(num: int, base: int) -> bool: | ||||||||||
""" | ||||||||||
Determines whether n in base 'base' is a harshad number. | ||||||||||
Where 'base' ranges from 2 to 36. | ||||||||||
|
||||||||||
Examples: | ||||||||||
>>> is_harshad_number_in_base(18, 10) | ||||||||||
True | ||||||||||
>>> is_harshad_number_in_base(21, 10) | ||||||||||
True | ||||||||||
>>> is_harshad_number_in_base(-21, 5) | ||||||||||
False | ||||||||||
>>> # bases beyond 36 and below 2 will error | ||||||||||
>>> is_harshad_number_in_base(45, 37) | ||||||||||
Traceback (most recent call last): | ||||||||||
... | ||||||||||
ValueError: 'base' must be between 36 and 2 inclusive | ||||||||||
>>> is_harshad_number_in_base(45, 1) | ||||||||||
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
|
||||||||||
|
||||||||||
if num < 0: | ||||||||||
return False | ||||||||||
|
||||||||||
n = int_to_base(num, base) | ||||||||||
d = sum_of_digits(num, base) | ||||||||||
return int(n, base) % int(d, base) == 0 | ||||||||||
|
||||||||||
|
||||||||||
if __name__ == "__main__": | ||||||||||
import doctest | ||||||||||
|
||||||||||
doctest.testmod() |
Uh oh!
There was an error while loading. Please reload this page.