How to find a specific number in a sequence of number with a constant sum of digit equal to 9 python?
Question:
Enter the natural number N (1 <= N <= 1,000,000). Print to the screen the Nth number of the sequence: 9 18 27 36 45 54 63 72 81 90 108 117
(they all have their sum of digit equal to 9)
N = 9+(int(input())-1)*9
def sumnum(N):
sum = 0
while N > 0:
d = N%10
N = N//10
sum += d
sumnum(N)
while sum != 9:
N+=1
sumnum(N)
print(N)
Here’s my code and it got this error
TimeLimitError: Stopped on Line 4
Answers:
Your sumnum
function doesn’t return anything, so it never changes sum
(or any other value) outside of the function. Normally you’d get an error trying to compare an undefined variable, but sum
is actually the name of a builtin function, so that’s what you’re comparing 9 to.
Here’s a simple approach: iterate through all numbers in a while
loop, and check the sum of each one’s digits by converting it to a string and summing the int values of its characters. Each time you find one whose sum is 9, decrement N
by one. When it hits zero, print the current number.
>>> N = 12
>>> i = 0
>>> while True:
... i += 1
... if sum(int(d) for d in str(i)) == 9:
... N -= 1
... if N == 0:
... print(i)
... break
...
117
Here’s a more code-golf-y approach using a filtered generator with itertools.count()
(less efficient for big numbers because it builds a list of the sequence up to N instead of just printing the last element):
>>> import itertools
>>> list(zip(range(N), (i for i in itertools.count() if sum(int(d) for d in str(i)) == 9)))[-1][-1]
117
Numbers whose digits add to 9 are multiples of 9 and vice versa. So the Nth number whose digits add to 9 is N*9. So all you need is this:
N = int(input("Enter N: "))
print (N*9)
You can add range checking for N being between 1 and 1,000,000 if you like.
This worked for me!
def getSum(n):
sum = 0
for digit in str(n):
sum += int(digit)
return sum
for i in range(0, 1000000):
n = i
sum = getSum(n)
if sum == 9:
print(f"{n} -- {sum}")
The millionth such number is 1020011001021000. Found in less than a second by either of these two solutions:
Solution 1
Produce all such numbers with up to 16 digits and then print the N-th (Try it online!):
from itertools import combinations_with_replacement
N = 1_000_000
worths = (10**i for i in range(16))
combs = combinations_with_replacement(worths, 9)
nums = sorted(map(sum, combs))
print(nums[N-1])
With up to 16 digits, the digit positions are worth 10^0 to 10^15. By picking 9 of those position worths (allowing repeats) and adding them, you get the numbers with digit sum 9.
For example, 1020011001021000 came from picking 10^15 once, 10^13 twice, 10^10 once, etc.
Solution 2
Imagine you have nine 1s and you move them around in the digit positions (the "ones" position, "tens" position, "hundreds" position, etc). They all start at the "ones" position, so the first number is 9. Then move one to the "tens" position, so you have the number 18. Move another there and you have 27. And so on. (Try it online!)
N = 1_000_000
digits = [9] + [0] * 15
for _ in range(N-1):
for i, d in enumerate(digits):
if d:
digits[i] = 0
digits[i+1] += 1
digits[0] = d - 1
break
print(int(''.join(map(str, reversed(digits)))))
Enter the natural number N (1 <= N <= 1,000,000). Print to the screen the Nth number of the sequence: 9 18 27 36 45 54 63 72 81 90 108 117
(they all have their sum of digit equal to 9)
N = 9+(int(input())-1)*9
def sumnum(N):
sum = 0
while N > 0:
d = N%10
N = N//10
sum += d
sumnum(N)
while sum != 9:
N+=1
sumnum(N)
print(N)
Here’s my code and it got this error
TimeLimitError: Stopped on Line 4
Your sumnum
function doesn’t return anything, so it never changes sum
(or any other value) outside of the function. Normally you’d get an error trying to compare an undefined variable, but sum
is actually the name of a builtin function, so that’s what you’re comparing 9 to.
Here’s a simple approach: iterate through all numbers in a while
loop, and check the sum of each one’s digits by converting it to a string and summing the int values of its characters. Each time you find one whose sum is 9, decrement N
by one. When it hits zero, print the current number.
>>> N = 12
>>> i = 0
>>> while True:
... i += 1
... if sum(int(d) for d in str(i)) == 9:
... N -= 1
... if N == 0:
... print(i)
... break
...
117
Here’s a more code-golf-y approach using a filtered generator with itertools.count()
(less efficient for big numbers because it builds a list of the sequence up to N instead of just printing the last element):
>>> import itertools
>>> list(zip(range(N), (i for i in itertools.count() if sum(int(d) for d in str(i)) == 9)))[-1][-1]
117
Numbers whose digits add to 9 are multiples of 9 and vice versa. So the Nth number whose digits add to 9 is N*9. So all you need is this:
N = int(input("Enter N: "))
print (N*9)
You can add range checking for N being between 1 and 1,000,000 if you like.
This worked for me!
def getSum(n):
sum = 0
for digit in str(n):
sum += int(digit)
return sum
for i in range(0, 1000000):
n = i
sum = getSum(n)
if sum == 9:
print(f"{n} -- {sum}")
The millionth such number is 1020011001021000. Found in less than a second by either of these two solutions:
Solution 1
Produce all such numbers with up to 16 digits and then print the N-th (Try it online!):
from itertools import combinations_with_replacement
N = 1_000_000
worths = (10**i for i in range(16))
combs = combinations_with_replacement(worths, 9)
nums = sorted(map(sum, combs))
print(nums[N-1])
With up to 16 digits, the digit positions are worth 10^0 to 10^15. By picking 9 of those position worths (allowing repeats) and adding them, you get the numbers with digit sum 9.
For example, 1020011001021000 came from picking 10^15 once, 10^13 twice, 10^10 once, etc.
Solution 2
Imagine you have nine 1s and you move them around in the digit positions (the "ones" position, "tens" position, "hundreds" position, etc). They all start at the "ones" position, so the first number is 9. Then move one to the "tens" position, so you have the number 18. Move another there and you have 27. And so on. (Try it online!)
N = 1_000_000
digits = [9] + [0] * 15
for _ in range(N-1):
for i, d in enumerate(digits):
if d:
digits[i] = 0
digits[i+1] += 1
digits[0] = d - 1
break
print(int(''.join(map(str, reversed(digits)))))