Python gives empty list when change loop range - python

hi everyone i have a problem with my codes below. as you can see i am trying to find "near power sum" numbers(35---> 3^2 + 5^2 = 34) when i arrange my range 10 to 100 program gives the exact results 35 and 75. however when i change the range like 100000 to 500000 or 1000000 it gives nothing, just an empty list. could you please help me about this?
import math
mylist=[]
for i in range(100000,1000000):
a =0
b=0
num=i
while num >= 1:
b = num%10
a= a+(b**2)
num = math.trunc(num/10)
if a == i-1 or a== i+1:
mylist.append(i)
print(mylist)

Numbers from your new range have only 5 digits. The biggest "near power sum" you can get in that range will be 9^2 * 5 = 405 which is less than your lower boundary 1e+5. So your code works properly as there is no way your condition can be satisfied for that range.

Let us take a decimal number with n digits n>2. I will assume that it has no leading 0, so its first digit is >=1.
Then the number is >= 10**(n-1)
Its digits are at most 9 so the sum of the square of its digits is <= n*81
For n =4, the number is >=1000 while the sum of the square of its digits is < 4*81 = 324: no deal...
And it will be worse when n increases.

Related

Finding the biggest number for a sequence given by the while loop

I'm currently learning Python, more specifically, how the loop while works. As far as I know, this loop can be used to create sequences of numbers with and specific condition. For example,
n=1
while n < 10:
n = n*2
print(n)
Which gives the powers of two up to 16:
2
4
8
16
But I was wondering if there's a way for the loop to print only the biggest number of the sequence, in this case, it would be 16. Here's my attempt,
n=1
bigNumber = 0
while n <= 10:
bigNumber = n
n = n*2
if n < bigNumber:
print(bigNumber)
However it doesn't work. Could someone point out were the mistake is?
Your code doesn't work as intended because the condition of the if statement is never fulfilled. Just take for example n=4. Then in the loop you first assign bigNumber = 4 and then n is increased to 8. And at this point, always n > bigNumber.
The easiest way here to get the correct answer is to print n after the loop (already mentioned in a comment) as n is always incrementing.
You can do this in 2 ways.
If you just want to print the final value you can just ommit part of the code:
n=1
while n < 10:
n = n*2
print(n)
If you want to keep all values and then show the highest one:
n=1
num_list = []
while n < 10:
num_list.append(n)
n = n*2
print(f'From the numbers {num_list} the highest is {max(num_list)}')
The max() function is built to find the highest value in a list.
The output should be:
From the numbers [1, 2, 4, 8] the highest is 8
print the number after the while loop is finished.
n=1
bigNumber = 0
while n <= 10:
bigNumber = n
n = n*2
print(bigNumber)

How to solve sum of sequence range of digits with less time complexity in python?

Sum of all digits between numbers
Kriti has two numbers, her tution teacher give a task to her. The task is that, she wants to find the sum of all digits appearing between those two numbers.
For Ex:
Num1 = 8 and Num2 = 13
Output: 27
(8 + 9 + 1 + 0 + 1 + 1 + 1 + 2 + 1 +3)
Input Format
Input the Number1 Input the Number2
Constraints
0 <= Number1 <=1000000000
Number1 <= Number2 <=1000000000
(Negative Numbers and Decimals are not allowed)
Output Format
Display the Sum of all digits appearing between Number1 and Number2
Sample Input 0
8
13
Sample Output 0
27
MY CODE
a=int(input())
b=int(input())
ls=0
lst=[]
s=0
for i in range(a,b+1):
lst.append(i)
for i in lst:
if i<10:
s=s+i
else:
for j in str(i):
s=s+int(j)
print(s)
This code almost clear 5/7 test cases but the problem of remaining two cases is the value of number range is 1000000000 if the input of the digits are maximum it will shows runtime error how to solve this problem efficient time with the given constrains constrains. The problem I mentioned here was a hackerrank platform that contest was conducted by my college staff and it's finished by an hour ago
If you approach this from a digit position's perspective, you can achieve O(log10 N).
def sumDigits(n1,n2):
if n2==0 or n1>n2: return 0
p1,d1 = divmod(n1,10) # extract last digits
p2,d2 = divmod(n2,10) # and prefixes
if p1==p2:
# same prefix: sum of last digits, digit count * sum of prefix digits
return sum(range(d1,d2+1)) + (d2-d1+1)*sumDigits(p1,p2)
else:
# different prefixes: recurse lower, upper, middle ranges
return sumDigits(p1*10+d1,p1*10+9) \
+ sumDigits(p2*10, p2*10+d2) \
+ sumDigits(p1+1,p2-1)*10 + (p2-p1-1)*45 # full middle range
For each digit position you can perform the calculation recursively by isolating the lower, middle and upper partial ranges and multiplying the sum of digits for the middle prefixes.
For example: from 1234 to 4567
If the numbers have the same prefix before the last digits, then we only need to compute the sum of the last digits between the two numbers and recurse for the sum of digits in the prefix (which will occur once for every last digit in the range)
Otherwise, break down the problem into lower, middle and upper ranges:
1234-1239 ... 124x-455x ... 4560-4567
The middle part will have all ending digits (0...9) for every number in the range 124x to 455x.
So the last digit part will have a sum of 45 (∑0..9) 332 times (456-124).
Each prefix in the middle range will be present 10 times (once for each ending digit)
So we can compute the sum of digits for numbers in the middle range using sumDigits(124,455) * 10 + (456-124) * 45
The 1234-1239 and 4560-4567 ranges can be computed by recursion (they have a common prefix by definition)
output:
sumDigits(8,13) # 27
sumDigits(1234,4567) # 52723
sumDigits(123456789,987654321) # 35514403389
verification:
sum(sum(map(int,str(n))) for n in range(8,13+1)) # 27
sum(sum(map(int,str(n))) for n in range(1234,4567+1)) # 52723
sum(sum(map(int,str(n))) for n in range(123456789,987654321+1))# takes too long
Your first for loop is definitely useless. You should just iterate over range(a, b + 1) don't put it in a list - this makes interpreter hold all of the values in memory, while you only need one at any point in time, which is why you must use range. This will save whole lot of time and memory.
Other than that, there might be just a slight improvement to calculations. Here is what i'd come up with:
for i in range(a, b + 1):
s += sum(map(int, str(i)))
So I guess I would do it like this:
a = int(input())
b = int(input())
result = 0
for i in range(a, b+1):
# so here we want to get the digits of i and add them up
current_length=len(str(i))
if current_length == 1:
result+=int(i)
else if current_length > 1:
for k in str(i).split(""):
result += int(k)
print(result)
I think this maybe faster than your approach, but I'm not sure, also you may need to tweak this code a bit, as I whipped it up on my phone, and could not really test it.
You don't need a list to keep track of the numbers. You just need a running sum. You can convert each number to a string. The string is iterable and allows you to find the sum of individual digits.
sum = 0
for i in range(a, b + 1):
digits = str(i)
for d in digits:
sum += int(d)

How would I make a try and expect block python to catch an infinite loop in a for loop

I am working on a problem where I have to output the smallest number bigger than N consisting of the same digits as N. If there is no such number, I must print "0" as the output. This is the code I have for now...
n = int(input())
copy = n+1
while True:
if sorted(str(n)) == sorted(str(copy)):
print(copy)
break
else:
copy+=1
I can not find a way to catch if a number has no such numbers, so, therefore, "0." I was thinking a try expect block but it somehow catches infinite loops. Any idea of how to implement this, or any other suggestions? Thank you!
SAMPLE INPUT/OUTPUT
input 1: 156
output 1: 165
input 2: 330
output 2: 0 (No such number fulfills the condition)
input 3: 27711
output 3: 71127
I have a different approach to the problem:
If all digits sorted in descending order, then output is always -1. For example, 321.
For other cases, we need to process the number from rightmost side (why? because we need to find the smallest of all greater numbers)
Algorithm
Traverse the given number from rightmost digit, keep traversing till you find a digit which is smaller than the previously traversed digit. For example, if the input number is “534976”, we stop at 4 because 4 is smaller than next digit 9. If we do not find such a digit, then output is “Not Possible”.
Now search the right side of above found digit ‘d’ for the smallest digit greater than ‘d’. For “534976″, the right side of 4 contains “976”. The smallest digit greater than 4 is 6.
Swap the above found two digits, we get 536974 in above example.
Now sort all digits from position next to ‘d’ to the end of number. The number that we get after sorting is the output. Finally, for above example, We get “536479” which is the next greater number for input 534976.
In last step we should check weather the result is a 32-bit number or not.
Code
def nextGreaterElement(n):
n = list(str(n))
N = len(n)
for x in range(N - 1, 0, -1):
if n[x] > n[x - 1]:
i = x - 1
break
else:
return -1
swap = i + 1
pos = i
for x in range(swap, N):
if n[pos] < n[x] < n[swap]:
swap = x
n[pos], n[swap] = n[swap], n[pos]
ans = int(''.join(n[:pos + 1]) + ''.join(sorted(n[pos + 1:])))
return ans if len(bin(ans)[2:]) < 32 else -1
print(nextGreaterElement(123))
# 132

Find all positive numbers divisible by 10 and less than n

I need to find all positive numbers that are divisible by 10 and less than n, i found a string with the same question but i have a hard time interpreting it as the user was using java so the codes are very different and confusing.
i tried to make a code by piecing together codes i've checked out but it only works if its divisible by other numbers, if its 10 it would keep going on forever with 0.
n = int(input("Enter a number: "))
x = 0
while x < n :
r = n % 10
if r % 10 != 0 :
x = x + r
print("positive numbers divisible by 10 ", x)
Below is simpler code which will help to get the list of numbers divisible by 10 and less than n:
n = int(input("Enter a number n: "))
divisibleBy10 = []
for i in range(0, n):
if i % 10 == 0:
divisibleBy10.append(i)
print(divisibleBy10)
You can do like this:
n = 100
i = 0
while i<n:
if i%10==0:
print(i)
i+=1
You can also try the following:
# grab the user's input
n = int(input('please enter a number: '))
# set x to 0, so the while loop can stop when 'n' is greater than '0'
x = 0
while n > x:
if n % 10 == 0:
print('{} is divisible by 10.'.format(n))
n -= 1
So basically the loop enters with the value that the user inputs, let's say 10.
Is 10 greater than 0? Yes (while loop executes), the if statement evaluates the remainder with the mod. The value is printed because the if statement evaluates True , the remainder is equal to zero. At last, n is subtracted by 1
Is 9 greater than 0? Yes (while loop executes), the if statement evaluates the remainder with the mod. The value is not printed because the if statement evaluates False , the remainder is not equal to zero. At last, n is subtracted by 1
Is 8 greater than 0? Yes (while loop executes), the if statement evaluates the remainder with the mod. The value is not printed because the if statement evaluates False , the remainder is not equal to zero. At last, n is subtracted by 1
...
And so on until n reaches 0, the while loop stops because 0 is not greater than 0.
This code below tries to reduce the number of loops. If 'x' is extremely large, it helps to optimize the solution. The idea is to not do the divisibility check for each number starting from 1 to n-1. Here, we use the fact that the least positive number divisible by 10 is 10. The next number of interest is 10 + 10 = 20, there by skipping numbers 11 to 19. This helps improve the performance.
x = input('Enter any number ')
y = 10
while y < x:
print(y)
y = y + 10
I think use inline for loop:
print([i for i in range(10,n,10) if i % 4 == 0])

python count no of digits in a non negative integer

I am writing a program for counting number of digits in a non negative integer whose upper bound is 10^{1000000} and has a time limit of 12 seconds
I have declared an array with size 1000000 and the indexes 0,1,2...,1000000 correspond to the number of digits of the number represented by 10^{array index}.
However I am getting Time Limit Exceeded for input ranges close to 10^{10000}.
Please find inline the code for the same:
def Number(x):
a=[0]*(1000000)
for j in xrange(len(a)):
#print j
a[j]=j+1
i=0
flag=0
flagc=0
counter=0
while(i<len(a)-1):
#print x
if (10**i)==x:
print a[i]
flag=1
break
elif x>(10**i) and x<(10**(i+1)):
print a[i]
flag=1
break
i=i+1
if (i==len(a)-1 and flag==0 and x==(10**i)):
print a[i]
number=int(input())
Number(number+1)
Please help as to how to handle large input values for the above as time limit got exceeded is coming for inputs close to 10^10000
OP has stated in a comment that his problem is he needs to take a numerical input in the form of a string, add 1 to it, and return the number of digits.
Adding 1 to a number will change the number of digits IF AND ONLY IF the string is composed completely of 9s. A simple test can achieve this. If it is all 9s, output the string length plus 1, otherwise output the unchanged string length.
num = input()
length = len(num)
if num == '9' * length: # checks if string is all 9's
print(length + 1)
else:
print(length)
By eliminating the need to convert to int and back, we save a lot of time. This code executes in fractions of a second.
The simplest way to do this in pure python is to use len(number) where "number" has the required base.
To the commenters saying that this is an integer, the data being discussed in this question would overflow an integer, and these numbers would have to be represented as a strings in memory due to their length.
As shown above in the comments, math.log10 is not accurate enough for large numbers. Try a while loop:
n = 10 ** 10000 - 1
count = 0
while n > 0:
n //= 10
count += 1
print(count)
Output:
10000
Changing n to 10 ** 10000 outputs 10001 as expected.
EDIT: I found something very surprising (to me, at least):
len(str(n))
is actually EXTREMELY fast! I tested for numbers up to 10^1000000, and it finishes executing in a matter of seconds!

Categories