Reputation: 19
a, b = map(int, input().split())
s = 0
for i in range(a, b + 1):
g = 0
while i != 0:
k = i % 10
g = g + k
i = i // 10
if g % 2 == 0:
s = s + 1
print(s)
The task itself:Count the number of natural numbers on the segment from a to b, the sum of the digits of which is even.
Upvotes: 2
Views: 133
Reputation: 5036
You can use (end-start)//2
for full blocks of n*10+[0...9]
inside the range and compute the small rests with your algorithm.
def q1(a,b):
s = 0
for i in range(a, b + 1):
g = 0
c = i
while i != 0:
k = i % 10
g = g + k
i = i // 10
if g % 2 == 0:
s = s + 1
return s
def q2(a,b):
br = b%10
ar = 10 - a%10
return q1(a, a+ar-1) + ((b - br) - (a + ar)) // 2 + q1(b-br,b)
I tested the implementation with
import random
for _ in range(1000):
a = random.randint(1,1000)
b = random.randint(100,100000)
assert q1(a,a+b) == q2(a,a+b), 'not the same result'
Benchmark
%timeit q1(10,10000) #=4995 in ~O(n^2)
# 100 loops, best of 5: 7.58 ms per loop
%timeit q2(10,1_000_000_000) #499999995 in ~O(1)
# 100000 loops, best of 5: 7.17 µs per loop
Upvotes: 1
Reputation: 1433
The idea here is not to loop through everything.
The sum of digits of every second number is even:
101 -> even
102 -> odd
103 -> even
So to find the amount of numbers that have an even sum of digits all you have to do is (start-end)/2
and then account for the edge cases, basically if the number you start and end on have even or odd sums.
Edit: I missed one of the weirdnesses at the 10s. The example beeing 29 and 30 which are both odd. So to amend that, every block of 10 numbers like 30-39 has 5 even and 5 odds. That increases the edge case you need to consider to a couple numbers befor you hit the first multiple of 10 and after you hit your last multiple of 10 - 1.
Upvotes: 4