Question:
Take two integers
a
andb
, output all the integers inside the range fromb
tob
. Replace numbers ended by 3 and 7 with the Asterisk*
symbol; And for each integer inside the range, if the sum of all digits is greater than or equal to 8, replace the integer with the%
symbol (except for the ones ended with 3 and 7).
Sample Input:
a = 12
b = 30
Sample Output:
12 * 14 15 16 * % % 20 21 22 * 24 25 % * % % 30
My codes:
a = int(input())
b = int(input())
summation = 0
for i in range(a, b 1):
if (i == 3 or i == 7) or (i % 10 == 3 or i % 10 ==7):
print('*', end = ' ')
while i <= b:
n = i % 10
i = i // 10
summation = i n
break
if summation >= 8:
print('%', end = ' ')
else:
print(i, end = ' ')
My Output:
12 * 14 15 16 * 18 19 20 21 22 * 24 25 26 * 28 29 30
Apparently, I've noticed there's something wrong with my code's logic. But I just can't come up with any solutions yet, please help provide some tips to help me fix my logic, appreciate it!
Additionally, I would like tips relating to my current method, converting to strings will be easier but I prefer to understand more about iteration, thank you!
CodePudding user response:
Use this:
def solution(a, b):
r = list(map(str, range(a, b 1))) # Get list of numbers and convert to str
for i, s in enumerate(r): # Loop through r
if s[-1] in '37': # Check if s ends in 3 or 7
r[i] = '*' # If it does, replace with '*'
elif sum(map(int, s)) >= 8: # If it doesn't, check if digits add up to more than 8
r[i] = '%' # If they do, replace with '*'
return ' '.join(r) # Return r, joined by ' '
print(solution(12, 30))
Output: 12 * 14 15 16 * % % 20 21 22 * 24 25 % * % % 30
Without converting to strings:
def solution2(a, b):
r = list(range(a, b 1)) # Get list of numbers
for i, n in enumerate(r): # Loop through r
if n % 10 in (3, 7): # Check if n ends in 3 or 7
r[i] = '*' # If it does, replace with '*'
elif sum(int(d) for d in str(n)) >= 8: # Otherwise, check sum of digits
r[i] = '%' # If greater than or equal to 8, replace with '%'
return r
print(*solution2(12, 30), sep=' ')
Output: 12 * 14 15 16 * % % 20 21 22 * 24 25 % * % % 30
CodePudding user response:
No need to convert the values to strings. You could do it like this:
a = 10
b = 30
result = []
def sd(n):
r = 0
while n > 0:
r = n % 10
n //= 10
return r
for n in range(a, b 1):
if n % 10 in {3, 7}:
result.append('*')
elif sd(n) >= 8:
result.append('%')
else:
result.append(n)
print(' '.join(map(str, result)))
Output:
10 11 12 * 14 15 16 * % % 20 21 22 * 24 25 % * % % 30
CodePudding user response:
This answer will aim to debug your existing program, but see also @Stuart's answer for a simpler method.
The while
loop in which you calculate the sum is inside the if
statement for ending with a 3 or 7. But a %
should only be possible when the number doesn't end in 3 or 7, so the loop should be in the else
statement.
Then the default case, printing out the number directly, can be done in an else
block attached to the while
loop as follows:
if (i == 3 or i == 7) or (i % 10 == 3 or i % 10 ==7):
...
else:
while i <= b:
...
else:
print(i, end=' ')
The else
block will be executed if the while
loop finishes without break
ing, i.e. if %
isn't printed.
The condition on the while
loop is incorrect. i <= b
is always going to be true, because i
starts less than or equal to b and only decreases. In order to loop for as long as i
has digits remaining, this should be i > 0
.
The summation
is being calculated incorrectly. You want to cumulatively sum each n
in each pass through the while
loop, so rather than doing i n
, you want summation n
to add the new n
to the previous total. summation
must also be reset to 0
just before the while
loop.
The break
statement should be at the bottom of the if
statement to only break if the condition is met.
Finally, in order to print the original i
in the case that the digit sum is less than 8, we need to keep it rather than modifying in the while
loop. We can copy the value of i
to m
and use m
instead:
m = i
summation = 0
while m > 0:
n = m % 10
m = m // 10
summation = summation n
...
Final code:
a = int(input())
b = int(input())
for i in range(a, b 1):
if (i == 3 or i == 7) or (i % 10 == 3 or i % 10 == 7):
print('*', end=' ')
else:
m = i
summation = 0
while m > 0:
n = m % 10
m = m // 10
summation = summation n
if summation >= 8:
print('%', end=' ')
break
else:
print(i, end=' ')
CodePudding user response:
This is aa possible one line solution :)
print(*('*' if n % 10 in (3, 7) else ('%' if sum(int(x) for x in str(n)) >= 8 else n) for n in range(a, b 1)))
Output with a=12
and b=30
:
12 * 14 15 16 * % % 20 21 22 * 24 25 % * % % 30