Python Algorithm - python

I am solving this question on HackerRank.
Problem Statement
You are given a number N, you need to print the
number of positions where digits exactly divides N.
Input format
The first line contains T (number of test cases followed by T lines
each containing N).
Constraints
1 <=T <= 15
0 < N < 1010
Output Format
Number of positions in N where digits in that number
exactly divides the number N.
When I give the input
T = 1
N = 114108089
I get ZeroDivisionError
Even after using the try and exception, error handling technique in Python the answer I get is 0 instead of the correct answer 3.
Code so far:
def find_digits():
try:
ctr = 0
c = int(input())
string_c = str(c)
list1 = []
for ch in string_c:
list1.append(ch)
for i in list1:
print i
b = int(i)
if c % b == 0:
ctr += 1
print ctr
except ZeroDivisionError:
print 0
test_case = int(input()) for s in range(test_case):
find_digits()

Some of the digits in N are zeroes, so b == 0 and when you try:
if c % b == 0:
you get a ZeroDivisionError. Rather than wrap the whole function in try, (which means you will only ever get non-zero output for inputs that contain no zeroes at all), wrap that one section:
try:
if c % b == 0:
ctr += 1
except ZeroDivisionError:
pass
Alternatively, check for non-zero values of b first:
if b and c % b == 0:
If you really want to get clever, the function can be done in one line:
sum(N % i == 0 for i in map(int, str(N)) if i)

You are getting a division by zero error because the digits can be zero.
if c % b == 0:
Here b can be zero.

Related

Print all perfect numbers less than N

I am trying to print all perfect numbers lesser than an integer, but I am not sure how to do it. Could you help me, please? When I execute the code, it writes ValueError: invalid literal for int() with base 10.
My code:
n = input()
w = int(n) - 1
i = 0
a = 0
z = 0
list = []
for w in range(w, 1):
for i in range(w, 2):
if w % i == 0:
a = int(w / i)
z = z + a
if z == w:
list.append(w)
print(list)
What is a perfect number?
In number theory, a perfect number is a positive integer that is equal to the sum of its positive divisors, excluding the number itself.
Here's how you can do it:
n = input('Enter the integer:')
w = int(n) - 1
l = [] # creating an empty list 'l'
for i in range(w, 0, -1): # Runs the loop for all integers below n and greater than 0.
s = 0 # Set the sum to 0.
for j in range(i,0, -1): # Runs the loop till 0 to check for all divisors
if i % j == 0 and j!= i: # If the number is a divisor of 'i' and not equal to the 'i' itself.
s = s + j # Then add the divisor to the sum
if s == i: # If sum is equal to the number 'i'
l.append(i) # Then add the number 'i' to the list 'l'
print(l)
Output:
Enter the integer:10000
[8128, 496, 28, 6]
What you were doing wrong?
Naming a list by a Python keyword is a bad practice and should be avoided! You named the list by the name list which is a keyword in Python.
You were using the same variable names for different tasks such as w for denoting integer less than n and also range in for loop. This should be avoided too!
Idk, why you were using the variable a but there's no need to initialize variables with 0 if you are using as range in for loop.
You were running the for loop till 1 instead should run it 0.
You were not setting the sum to zero at every integer.
Here is a very simple implementation of the perfect numbers algorithm:
def isperfect(n: int) -> bool:
"""Test if a number is perfect."""
sum_ = sum(i for i in range(1, n//2+1) if not n % i)
return sum_ == n
n = int(input('Enter a positive integer: '))
p = [i for i in range(1, n) if isperfect(i)]
Output:
Enter a positive integer: 10000
print('Perfect numbers:', *p)
Perfect numbers: 6 28 496 8128
Explanation:
The isperfect function is used to test whether n is perfect. Efficiency is gained by only testing numbers <= n/2.
Capture the user's requested integer.
Using list comprehension, iterate the range of values (N-1) and test if each is perfect.
The perfect numbers are captured and stored into the p variable as a list.

Printing digits of an integer in order in Python

I want to print the digits of an integer in order, and I don't want to convert to string. I was trying to find the number of digits in given integer input and then divide the number to 10 ** (count-1), so for example 1234 becomes 1.234 and I can print out the "1". now when I want to move to second digit it gets confusing. Here is my code so far:
Note: Please consider that I can only work with integers and I am not allowed to use string and string operations.
def get_number():
while True:
try:
a = int(input("Enter a number: "))
return a
except:
print("\nInvalid input. Try again. ")
def digit_counter(a):
count=0
while a > 0:
count = count+1
a = a // 10
return count
def digit_printer(a, count):
while a != 0:
print (a // (10 ** (count-1)))
a = a // 10
a = get_number()
count = digit_counter(a)
digit_printer(a, count)
I want the output for an integer like 1234 as below:
1
2
3
4
Using modulo to collect the digits in reversed order and then print them out:
n = 1234
digits = []
while n > 0:
digits.append(n%10)
n //=10
for i in reversed(digits):
print(i)
Recursive tricks:
def rec(n):
if n > 0:
rec(n//10)
print(n%10)
rec(1234)
Finding the largest power of 10 needed, then going back down:
n = 1234
d = 1
while d * 10 <= n:
d *= 10
while d:
print(n // d % 10)
d //= 10

how to find how many factorial numbers are within a file

i have a problem when i try to find if a number is factorial
this is what I've done so far:
i = 1
count = 0
while n>1:
if n % i == 0:
n /= i
else:
break
i+=1
if n<=1:
count += 1
return count
but it returns 1 and I don't know how to fix
As written, the value of count in your example code indicates whether or not the number n is a factorial number, for a single n.
If it is, then at some point n <= 1, so count will be incremented, and the value of count returned by the function will be 1. If it is not, then at some point before n <= 1, n % i == 0 will be False, the loop will break, and the returned value of count will be 0.
Note, though, that there is an edge case not covered by your example code as is. Namely, 1 is a factorial number (1! = 1). But if n is 1, the condition on the while loop is never True, so the function immediately returns 0. So, you need to change the condition in the while loop.
E.g.
def isfactorialnumber(n):
i = 1
count = 0
while n >= 1:
if n % i == 0:
n /= i
else:
break
i += 1
if n <= 1:
count += 1
return count
I have 2 further comments about this code.
First, in the context of this new function, the variable name count is misleading. What is it counting? Nothing, really. It can only take 2 values, 1 or 0. It would be better then, to use a boolean variable, and call it result or similar. Even better, get rid of the variable and refactor your code as:
def isfactorialnumber(n):
i = 1
while n >= 1:
if n % i == 0:
n /= i
else:
break
i += 1
if n <= 1:
return True
return False
Which is equivalent but a little better.
Second, a more readable, natural way to solve the problem would be to work from bottom-up. That is, solve the problem by generating the factorial numbers, m that are less than or equal to n, then checking if the last m is equal to n. This leads to more concise and understandable code IMO.
E.g.
def isfactorialnumber(n):
m = 1
i = 1
while m < n:
m *= i
i += 1
return m == n
Finally, assuming each number in your file, is on its own line:
with open('factorials.txt') as infile:
print(len([1 for line in infile if isfactorialnumber(int(line))]))
Will print the number of factorial numbers in the file factorials.txt
count = 0
for n in listOfNumbers:
i = 1
while n>=1:
if n % i == 0:
n /= i
else:
break
i+=1
if n<=1:
count += 1
return count

Zero division error in python function even after using if-statement to avoid division by 0

I am writing a function that returns the total count of digits(of an integer) that can divide the integer that it is a part of.
For ex- Integer -111
count - 3 as all 1,1,1 divide 111
Integer - 103456
count - 2 only divisible by 1,4.
To handle the special case of division by 0 , I have used if-else statements .However, I am still getting a zero divison error. Why am I still getting this error?
My error message:-ZeroDivisionError:integer division or modulo by zero
My code-
count=0
divisors_list=[]
number_in_string = str(n)
divisors_list=list(number_in_string)
for divisor in divisors_list:
if divisor != 0:
if n%int(divisor) == 0:
count+=1
return count
x=findDigits(103456)
The issue is bad usage of strings as integers.
One way to fix your code is:
def findDigits(n):
count = 0
number_in_string = str(n)
divisors_list = list(number_in_string)
for divisor in divisors_list:
# *** at this point, divisor is a string ***
divisor = int(divisor) # <== cast it to int
if divisor != 0:
if n % divisor == 0:
count += 1
return count
int(divisor) can be 0 even if divisor != 0.
>>> divisor = 0.5
>>> int(divisor)
0
I would suggest to ask for forgiveness instead of permission and just catch the ZeroDivisionError.
try:
if n%int(divisor) == 0:
count += 1
except ZeroDivisionError:
pass

Looking for Clarification on how this "For-Loop" works

I'm a complete beginner to programming so forgive me for my naivete.
I wanted to make a program in Python that lets me print a given N number of prime numbers, where N is inputted by the user. I searched a little on "for/while" loops and did some tinkering. I ran a program I saw online and modified it to suit the problem. Here is the code:
i = 1
print("Hi! Let's print the first N prime numbers.")
nPrimes = int(input("Enter your N: "))
counter = 0
while True:
c = 0 #another initialization
for x in range (1, (i + 1)):
a = i % x # "a" is a new variable that got introduced.
if a == 0:
c = c + 1
if c == 2:
print(i, end = " ")
counter = counter + 1
if counter > = nPrimes: #if it reaches the number input, the loop will end.
break
i = i+1
print(": Are your", nPrimes, "prime number/s!")
print()
print("Thanks for trying!")
This should be able to print the amount of prime numbers the user so likes. It is a working code, though I am having difficulty trying to understand it. It seems that the variable c is important in deciding whether or not to print the variable i (which in our case is the supposed prime number during that interval).
We do c + 1 to c every time our variable a has a remainder of 0 in a = i % x. Then, if c reaches 2, the current variable i is printed, and variable c re-initializes itself to 0 once a prime number has been found and printed.
This I can comprehend, but I get confused once the numbers of i get to values 4 and onwards. *How is 4 skipped by the program and not printed when it has 2+ factors in the range that makes its remainder equal to zero? Wouldn't c == 2 for 4 and thus print 4? *And how would the program continue to the next number, 5? (Given that variable N is a large enough input).
Any clarifications would be greatly appreciated. Thank you so much!
From Wikipedia we know:
A prime number (or a prime) is a natural number greater than 1 that cannot be formed by multiplying two smaller natural numbers.
So to find a prime, is to find a natural number, aka an integer, which can only be exactly divided by 1 or itself. This is called Approach of Definition to find primes.
Hence, the following loop traverses through all integers from 1 to i,
and it counts how many times the integer i can be exactly divided by them.
for x in range (1, (i + 1)):
a = i % x # "a" is a new variable that got introduced.
if a == 0:
c = c + 1
And later you judge if the integer i can only be exactly divided by 1 and itself.
If true, you got a prime;
otherwise you just keep on.
if c == 2:
print(i, end = " ")
counter = counter + 1
if counter > = nPrimes: #if it reaches the number input, the loop will end.
break
Meanwhile, you can improve this prime searching algorithm a little bit by changing i = 1 to i = 2 in the beginning and adding an if statement:
# Start from 2 instead of 1
# and end at `i - 1` instead of `i`
for x in range (2, i):
a = i % x # "a" is a new variable that got introduced.
if a == 0:
c = c + 1
# Abandon the loop
# because an integer with factors other than 1 and itself
# is unevitably a composite number, not a prime
if c > 0:
break
if c == 0:
print(i, end = " ")
counter = counter + 1
if counter >= nPrimes: #if it reaches the number input, the loop will end.
break
This twist improves the efficiency of your program because you avoid unnecessary and meaningless amount of work.
To prevent potential infinite loop resulting from while expression,
you should replace while True: with while counter < nPrimes:. And the code turns out to be like this:
#if it reaches the number input, the loop will end.
while counter < nPrimes:
c = 0 #another initialization
# Start from 2 instead of 1
# and end at `i - 1` instead of `i`
for x in range (2, i):
a = i % x # "a" is a new variable that got introduced.
if a == 0:
c = c + 1
# Abandon the loop
# because an integer with factors other than 1 and itself
# is unevitably a composite number, not a prime
if c > 0:
break
if c == 0:
print(i, end = " ")
counter = counter + 1
i = i + 1
If you want to read more about how to improve your program's efficiency in finding primes, read this code in C language. :P
c in this case is used to count the number of numbers that divide evenly into i.
for example, if i = 8: 8 is divisible by 1, 2, 4, and 8. so c = 4 since there are 4 things that divide evenly into it
if i = 5: 5 is divisible by 1 and 5. so c = 2 since there are 2 numbers that divide evenly into it
if i = 4 (where you seem to be confused): 4 is divisible by 1, 2, and 4. so c = 3, not 2.

Categories