Beautiful Numbers - python

A sequence of numbers is called cute if all the numbers in the sequence are made of only two digits, 8 and 9.
Example of a cute sequence is: 8, 9, 88, 89, 98, 99…. and so on.
A number is called beautiful if it is divisible by any number which is part of the cute sequence.
For example: 8 (divisible by 8), 9(divisible by 9), 889 (divisible by 889), 10668 (divisible by 889) are beautiful numbers. Given a number, n, write a code to print “beautiful” (without quotes) if it is divisible by any number that contains only 8 or 9 or both and print -1 otherwise.
This is the python code which i tried:
I used a for loop from 8 to n/2 and i used regex to check if the number contains only 8 and 9. This code is working fine for smaller numbers, for larger numbers it is giving Time limit exceeded! Is there any efficient solution for this question ?
import re
n=int(input())
l="^[8-9]+$"
x=0
if re.match(l,str(n)):
print("beautiful")
else:
for i in range(8,int(n/2+1),1):
if re.match(l,str(i)) and n%i==0:
print("beautiful")
x=1
break
if x==0:
print(-1)

There is a function that generates all cute number with specified maximum length:
from collections import deque
elements = ["8", "9"]
def all_cute_numbers(max_len):
prefixes = deque(elements)
while prefixes:
p = prefixes.popleft()
yield p
if len(p) < max_len:
for el in elements:
prefixes.append(p + el)
numbers = all_cute_numbers(3)
print(list(numbers))
You can loop over it and check that some of number divide your input n

n = int(input("enter the number "))
s = str(n)
print(len(s))
k = [] a = [8,9]
flag = 0
#generate cute sequence numbers by appending 8 and 9 to the already generated numbers
while True:
x = (a[0]*10) + 8
a.append(x)
y = (a[0]*10) + 9
a.append(y)
#check whether the generated number divides the given number
if ((n%x==0) or (n%y==0)):
flag = 1
print("beatiful")
break
if (len(str(y))>len(s)):
break
k.append(a[0])
a.pop(0)
print(k)
if (flag==0):
print("-1")

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.

Creating the multiplication table

I'm trying to create a multiplication table. The user enters their list of numbers and the program spits out the multiplication for each number. for example,
3 x 1 = 3
3 x 2= 6
3 x 3 = 9
......
.....
3 x 12=42
this is what I have tried so far:
enter code here
N = int(input("How many numbers would you like to multiply?:"))
num = []
q=1
p = 1
count=0
for i in range(0,N):
add = int(input(f"number {i}:"))
num.append(add)
print(num)
for j in num:
while q <= 12:
print (j * q, end=" ")
q+=1
#The result is
How many numbers would you like to multiply?:3
number 0:2
number 1:6
number 2:5
[2, 6, 5]
2 4 6 8 10 12 14 16 18 20 22 24
enter code here
How do I get the program to spit out all the multiplication for every number in the list?
Store your tables in a dictionary and call in any way you want. See below code:
def inputmethod():
N = int(input("How many numbers would you like to multiply?:"))
num = []
for i in range(0,N):
add = int(input(f"number {i}:"))
num.append(add)
return num
def multiplication(m,num):
L = list(range(1,m+1))
dict_tables = {}
for n in num:
dict_tables[n] = [e*n for e in L]
return dict_tables
def print_tables(dict_tables):
for key,value in dict_tables.items():
print(f"Table of {key} is : {value}")
num = inputmethod()
generate_tables = multiplication(12,num)
print_tables(generate_tables)
Here's how (and why) I would have written that:
# More verbose variable names are nice documentation!
num_count = int(input("How many numbers would you like to multiply?:"))
numbers = []
# Start at 1 instead of 0, because humans are used to counting from 1.
for i in range(1, num_count + 1):
number = int(input(f"number {i}:"))
numbers.append(number)
print(numbers)
# Loop across the list of numbers you built in the previous step.
for number in numbers:
# `for i in range(...)` is the canonical Python way to loop over numbers.
for i in range(1, 13):
print(number * i, end=" ")
print()
Alternatively:
...
for i in range(12):
print(number * (i + 1), end=" ")
...
gets the same result, but I find it a lot simpler to iterate over the actual list of numbers I want to use, especially in more complex formulas where you're referring to that variable more than once. For instance, if you were calculating squares and writing number * (i + 1) * (i + 1), and you were my coworker, I would wag my finger at you.

All function only checking one element

counter = 0
numList = []
beginning = 1
primeOrNot = False
number = int(input("Type a number to check if it's prime."))
while True:
if number == 2:
primeOrNot = True
elif "2" in str(number) or "4" in str(number) or "6" in str(number) or "8" in str(number) or "0" in str(number) or number == 1:
primeOrNot = False
numList = [''.join(p) for p in permutations(str(number))]
for p in range(0, len(numList)):
numList[p] = int(numList[p])
for u in range(2, number):
if all(o % u == 0 for o in numList):
counter = counter + 1
if counter == 0:
print(numList)
break
I'm trying to make it so it prints a prime if all permutations of the number are also primes.
I've tried to do that with all but what it's doing is checking if atleast 1 of the elements in the list fits the o % u = 0. I want it to check if all of the elements work, not if one. Anything I can do using all or using something else?
Example of output now:
Input: 12
Output: Nothing, Neither 12 nor 21 are prime
Input: 35
Output: 35, 53
Even though 35 isn't prime it prints because 53 is.
Your logic is faulty:
for u in range(2, number):
if all(o % u == 0 for o in numList):
counter = counter + 1
For each potential divisor in the range, you check to see whether that divisor goes into every permutation of the input. What value of u do you envision is going to divide both 35 and 53?
For starters, you need this to be any, not all.
Second, I strongly recommend that you look up how to find primes and/or factor numbers. You can learn better ways to handle this, especially when your input string is longer.
Also, note that a 0 or 5 in the input will also ensure that some of the permutations will be composite; assuming that the input is at least two digits, it must be entirely composed of 1379 digits.
if number in [2, 3, 5, 7]:
print("number is prime")
exit(0)
if any (d not in "1379" for d in str(number)):
print("This input has composite permutations")

How can I display all numbers in range 0-N that are "super numbers"

The program asks the user for a number N.
The program is supposed to displays all numbers in range 0-N that are "super numbers".
Super number: is a number such that the sum of the factorials of its
digits equals the number.
Examples:
12 != 1! + 2! = 1 + 2 = 3 (it's not super)
145 = 1! + 4! + 5! = 1 + 24 + 120 (is super)
The part I seem to be stuck at is when the program displays all numbers in range 0-N that are "super numbers". I have concluded I need a loop in order to solve this, but I do not know how to go about it. So, for example, the program is supposed to read all the numbers from 0-50 and whenever the number is super it displays it. So it only displays 1 and 2 since they are considered super
enter integer: 50
2 is super
1 is super
I have written two functions; the first is a regular factorial program, and the second is a program that sums the factorials of the digits:
number = int(input ("enter integer: "))
def factorial (n):
result = 1
i = n * (n-1)
while n >= 1:
result = result * n
n = n-1
return result
#print(factorial(number))
def breakdown (n):
breakdown_num = 0
remainder = 0
if n < 10:
breakdown_num += factorial(n)
return breakdown_num
else:
while n > 10:
digit = n % 10
remainder = n // 10
breakdown_num += factorial(digit)
#print (str(digit))
#print(str(breakdown_num))
n = remainder
if n < 10 :
#print (str(remainder))
breakdown_num += factorial(remainder)
#print (str(breakdown_num))
return breakdown_num
#print(breakdown(number))
if (breakdown(number)) == number:
print(str(number)+ " is super")
Existing answers already show how to do the final loop to tie your functions together. Alternatively, you can also make use of more builtin functions and libraries, like sum, or math.factorial, and for getting the digits, you can just iterate the characters in the number's string representation.
This way, the problem can be solved in a single line of code (though it might be better to move the is-super check to a separate function).
def issuper(n):
return sum(math.factorial(int(d)) for d in str(n)) == n
N = 1000
res = [n for n in range(1, N+1) if issuper(n)]
# [1, 2, 145]
First I would slightly change how main code is executed, by moving main parts to if __name__ == '__main__', which will execute after running this .py as main file:
if __name__ == '__main__':
number = int(input ("enter integer: "))
if (breakdown(number)) == number:
print(str(number)+ " is super")
After that it seems much clearer what you should do to loop over numbers, so instead of above it would be:
if __name__ == '__main__':
number = int(input ("enter integer: "))
for i in range(number+1):
if (breakdown(i)) == i:
print(str(i)+ " is super")
Example input and output:
enter integer: 500
1 is super
2 is super
145 is super
Small advice - you don't need to call str() in print() - int will be shown the same way anyway.
I haven't done much Python in a long time but I tried my own attempt at solving this problem which I think is more readable. For what it's worth, I'm assuming when you say "displays all numbers in range 0-N" it's an exclusive upper-bound, but it's easy to make it an inclusive upper-bound if I'm wrong.
import math
def digits(n):
return (int(d) for d in str(n))
def is_super(n):
return sum(math.factorial(d) for d in digits(n)) == n
def supers_in_range(n):
return (x for x in range(n) if is_super(x))
print(list(supers_in_range(150))) # [1, 2, 145]
I would create a lookup function that tells you the factorial of a single digit number. Reason being - for 888888 you would recompute the factorial of 8 6 times - looking them up in a dict is much faster.
Add a second function that checks if a number isSuper() and then print all that are super:
# Lookup table for single digit "strings" as well as digit - no need to use a recursing
# computation for every single digit all the time - just precompute them:
faks = {0:1}
for i in range(10):
faks.setdefault(i,faks.get(i-1,1)*i) # add the "integer" digit as key
faks.setdefault(str(i), faks [i]) # add the "string" key as well
def fakN(n):
"""Returns the faktorial of a single digit number"""
if n in faks:
return faks[n]
raise ValueError("Not a single digit number")
def isSuper(number):
"Checks if the sum of each digits faktorial is the same as the whole number"
return sum(fakN(n) for n in str(number)) == number
for k in range(1000):
if isSuper(k):
print(k)
Output:
1
2
145
Use range.
for i in range(number): # This iterates over [0, N)
if (breakdown(number)) == number:
print(str(number)+ " is super")
If you want to include number N as well, write as range(number + 1).
Not quite sure about what you are asking for. From the two functions you write, it seems you have solid knowledge about Python programming. But from your question, you don't even know how to write a simple loop.
By only answering your question, what you need in your main function is:
for i in range(0,number+1):
if (breakdown(i)) == i:
print(str(i)+ " is super")
import math
def get(n):
for i in range(n):
l1 = list(str(i))
v = 0
for j in l1:
v += math.factorial(int(j))
if v == i:
print(i)
This will print all the super numbers under n.
>>> get(400000)
1
2
145
40585
I dont know how efficient the code is but it does produce the desired result :
def facto():
minr=int(input('enter the minimum range :')) #asking minimum range
maxr=int(input('enter the range maximum range :')) #asking maximum range
i=minr
while i <= maxr :
l2=[]
k=str(i)
k=list(k) #if i=[1,4,5]
for n in k: #taking each element
fact=1
while int(n) > 0: #finding factorial of each element
n=int(n)
fact=fact*n
n=n-1
l2.append(fact) #keeping factorial of each element eg : [1,24,120]
total=sum(l2) # taking the sum of l2 list eg 1+24+120 = 145
if total==i: #checking if sum is equal to the present value of i.145=145
print(total) # if sum = present value of i than print the number
i=int(i)
i=i+1
facto()
input : minr =0 , maxr=99999
output :
1
2
145
40585

Python: Summing Odd/Even Random Numbers Generates TypeError: 'int' object is not iterable

Yes, this question has been asked, but I cannot seem to apply the answers to my problem. There are several parts to this problem, and this is the biggest obstacle I've hit.
I need to generate a random list of 10 numbers between 10 & 90. From those random numbers, I need to sum the totals of both the even and odd numbers.
def playlist():
nums = []
for nums in range(10):
# Get random list of 10 numbers
my_nums = random.randint(10, 90)
print (my_nums,end=' ')
even = []
odd = []
for x in my_nums:
if x % 2 == 0:
even.append[x]
print(even)
else:
odd.append[x]
print(odd)
When I run this, sometimes I get one or two numbers (usually the first two odd numbers), but mostly I get TypeError: 'int' object is not iterable.
Not gonna lie - my first language is PHP, not Python and that's becoming a huge problem for me :(
Any help is appreciated.
Creating list with randoms
n = [random.randint(10,90) for x in range(10)]
Getting even and odds:
even = [x for x in n if x % 2 == 0]
odd = [x for x in n if x % 2 == 1]
You should be doing this.
def playlist():
nums1 = []
for nums in range(10):
# Get random list of 10 numbers
my_nums = random.randint(10, 90)
nums1.append(my_nums)
print my_nums
even = []
odd = []
for x in nums1:
if x % 2 == 0:
even.append(x)
print(even)
else:
odd.append(x)
print(odd)
playlist()
There are a few things you seem to have misunderstood:
range(10) will give you (something that looks like) this list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].
You can use it with a for-loop to do something 10 times
random.randint(10, 90) will give you a single random number between 10 and 90 (not a list)
With this information we can change your script to:
import random
even_sum = 0
odd_sum = 0
for number_of_turns in range(10):
# Get a random number
number_this_turn = random.randint(10, 90)
print(number_this_turn,end=' ')
if number_this_turn % 2 == 0:
even_sum += number_this_turn
print("Sum of even numbers so far:", even_sum)
else:
odd_sum += number_this_turn
print("Sum of odd numbers so far:", odd_sum)
print("Final sum of even numbers:", even_sum)
print("Final sum of odd numbers:", odd_sum)
But we can do better. You will learn that in Python, you will want very often to define a list (or an iterable) with the terms you need then do something with every term. So we can change your script to:
import random
even_sum = 0
odd_sum = 0
random_numbers = [random.randint(10, 90) for x in range(10)]
for number in random_numbers:
print(number,end=' ')
if number % 2 == 0:
even_sum += number
print("Sum of even numbers so far:", even_sum)
else:
odd_sum += number
print("Sum of odd numbers so far:", odd_sum)
print("Final sum of even numbers:", even_sum)
print("Final sum of odd numbers:", odd_sum)
random_numbers = [random.randint(10, 90) for x in range(10)] is using a list comprehension to generate a list of 10 random numbers. You can then do a for-loop on each of these numbers where you can add to the evens' sum or to the odds' sum.
You can even simplify it even further like in #Take_Care_ 's answer but I guess you have a lot more to learn before you reach this level.
As mentioned the comments, you can't write for x in followed by a number. I guess what you want is for x in range(my_nums) rather than for x in my_nums.
This is ultimately what I needed:
def playlist():
nums = []
for nums1 in range(10):
# Get random list of 10 numbers
my_nums = random.randint(10, 90)
nums.append(my_nums)
print (my_nums,end=' ')
even = []
odd = []
for x in nums:
if x % 2 == 0:
even.append(x)
else:
odd.append(x)
print ("\n")
print("Total of Even Numbers: ",sum(even))
print ("\n")
print("Total of Odd Numbers: ",sum(odd))
Thanks to everyone for their help...yes I know the call to run the function is missing - like I said this is just one part of the program :)
Following code works:
"""
I need to generate a random list of 10 numbers between 10 & 90. From those random numbers, I need to sum the totals of both the even and odd numbers.
"""
from random import randint
MIN = 10
MAX = 90
sum_odds = sum_evens = 0
for i in range(10):
r = randint(MIN,MAX)
if r % 2:
sum_odds += r
else:
sum_evens += r
return sum_evens, sum_odds

Categories