Printing the largest number from the outputs (collatz conjecture-python) - python

I need help for printing the largest number from the multiple outputs. How can I modify this code to do so?
x = int(input("Enter a number : "))
while(x!=1):
if(x%2==0):
x = x/2
print("\n",x)
else:
x = 3*x+1
print("\n",x)
When I typed "20" as the input, I get a list of numbers and I can easily say that 16 is the largest out of the outputs. But it is really hard when the input is big. I need a code to print out the largest number from the outputs

You could create a generator that generates the Collatz sequence and then use the max() function to find the largest number:
def collatz_sequence(x):
yield x
while x > 1:
x = x // 2 if x % 2 == 0 else 3 * x + 1
yield x
print(max(collatz_sequence(5))) # Output: 16

Related

I want to compute the sum of first N even numbers based on the user input N using recursive function

I want to compute the sum of first N even numbers based on the user input N using recursive function.
For example:
Sample Input N: 5
Sample Output: 2 + 4 + 6 + 8 + 10 = 30
I did my code in 2 ways but both of them gave wrong outputs. I'm doing something wrong in the function part sorting number in the loop. So I need some help!
n = int(input("Enter a nmuber: "))
for i in range(1,n+1):
for d in range(0,i+1,2):
print(d)
n = int(input("Enter a number: "))
def get_even(n):
for i in range(1,n+1,2):
d += i
print(d)
You can use the following.
Code
def sum_even(n):
# Base case
if n <= 1:
return 0
if n % 2:
# odd n
return sum_even(n - 1) # sum from next smaller even
else:
# even n
return n + sum_even(n - 2) # current plus sum from next smaller even
# Usage
n = int(input('Enter a nmuber: '))
print(sum_even(n))

Finding the largest odd number among 3 variable, program doesn't work properly [duplicate]

This question already has answers here:
Choose largest odd number python
(28 answers)
Closed 4 months ago.
Hi I am new to programming and I made a program for a finger exercise in the book "Introduction to computation and programming using python"
here's the finger exercise : Write a program that examines three variables—x, y, and z—
and prints the largest odd number among them. If none of them are odd, it
should print a message to that effect.
I made this,
l = []
x = int(input("Enter a number for x: "))
y = int(input("Enter a number for y: "))
z = int(input("Enter a number for z: "))
l.append(x)
l.append(y)
l.append(z)
def testodd(n):
return n%2 != 0
def maxodd (l):
oddlist = []
for i in l:
if testodd(i):
oddlist.append(i)
else:
continue
return max(oddlist)
print(maxodd(l))
Program sometimes work properly and sometimes not for example I gave x=231 y=23 and z=678 it says "none of them are odd" what's the problem about this program ?
First we create a list that will contain all the numbers, then we sort that list in descending order (reverse=True) and then we look if there is any odd number. If we don't find any odd number in the list we print the message:
numbers = []
for _ in range(3): # Iterate 3 times
numbers.append(int(input("Enter a number:"))) # Append 1 number each time
numbers.sort(reverse=True) # Sort the numbers in descending order
for n in numbers: # Iterate over the numbers
if n % 2 != 0: # If the number is odd we have found the maximum odd value
print(n) # Print the value
break # Finish the loop
else: # An else block in a for loop will execute if no break was found
print("none of them are odd") # Print the message
A more advanced way to retrieve the numbers would be:
numbers = sorted((int(input("Enter a number:")) for _ in range(3)), reverse=True)
that would replace the first 4 lines.
This is simpler if you put only the odd numbers into a list.
x = int(input("Enter a number for x: "))
y = int(input("Enter a number for y: "))
z = int(input("Enter a number for z: "))
odd_numbers = [value for value in (x,y,z) if value%2]
if odd_numbers:
print("The greatest odd number is", max(odd_numbers))
else:
print("None of the numbers is odd.")
The program finds the maximal number and checks if it's odd.
To find the maximal odd number, you can use list comprehension:
Put the numbers to check at a list numbers = [x, y, z]
Loop over the numbers t for t in numbers, and filter in those who are odd if t % 2 != 0.
Find the maximal among them (#2): max([t for t in numbers if t % 2 != 0])
x = int(input("Enter a number for x: "))
y = int(input("Enter a number for y: "))
z = int(input("Enter a number for z: "))
# Put numbers in a list
numbers = [x, y, z]
# Filter the odd numbers, and find the max
print(max([t for t in numbers if t % 2 != 0]))
You may just append all numbers entered into a list, sort all odds into another list and get the maximum value:
numbs = []
x = int(input("Enter a number for x: "))
numbs.append(x)
y = int(input("Enter a number for y: "))
numbs.append(y)
z = int(input("Enter a number for z: "))
numbs.append(z)
odds = [x for x in numbs if x%2==1]
if odds == []:
print('No odd number was entered')
else:
print(max(odds))

Assistance required finishing this question

I managed to sort of complete the first part of this question. But I have no idea on how to finish the second part. I managed to complete the input for x and y.
Exercise 1
The function takes in input a number x and a list of numbers y, and returns a value as
follows:
• If x is odd, fun_exercise_1 subtract 1 from all the elements of y and then returns
its sum.
• If x is even, fun_exercise_1 multiplies each element of y by 2 and then returns its
sum.
• If x is zero, fun_exercise_1 returns the sum of all the elements in y
def fun_exercise_1(x,y):
print ("enter value for x")
x = float (input ("x:"))
y = []
print ("Enter 4 numbers for a list. Use a negative number to finish")
yy = float(input ("Enter Number:"))
while yy >=0.0 :
y.append(yy)
yy = float(input("Next number:"))
This is one way to do it. Although it doesn't validate if the first argument is an integer or if the second argument is a list. It just expects those in order to run correctly.
def test(x, y):
if x == 0:
sum = 0
for i in y:
sum += i + sum
return sum
elif x % 2 == 0:
sum = 0
for i in y:
sum += i * 2
return sum
else:
sum = 0
for i in y:
sum += i - 1
return sum
This would be tested by passing an integer and a list as arguments when calling test().
Here is what you wanna do:
def fun_exercise_1(x, y):
if x ==0:
return sum(y)
elif x % 2 == 0:
y = [(val*2) for val in y]
return sum(y)
else:
y = [(val -1) for val in y]
return sum(y)
print(fun_exercise_1(3,[4,5,6,7]))
Output:
18

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

How can I Keep the following program running until it becomes a single digit number?

I want to write a program that can calculate the sum of an integer as well as count its digits . It will keep doing this until it becomes a one digit number.
For example, if I input 453 then its sum will be 12 and digit 3.
Then it will calculate the sum of 12=1+2=3 it will keep doing this until it becomes one digit. I did the first part but i could not able to run it continuously using While . any help will be appreciated.
def main():
Sum = 0
m = 0
n = input("Please enter an interger: ")
numList = list(n)
count = len(numList)
for i in numList:
m = int(i)
Sum = m+Sum
print(Sum)
print(count)
main()
It is not the most efficient way, but it doesn't matter much here; to me, this is a problem to elegantly solve by recursion :)
def sum_digits(n):
n = str(n)
if int(n) < 10:
return n
else:
count = 0
for c in n:
count += int(c)
return sum_digits(count)
print sum_digits(123456789) # --> 9 # a string
A little harder to read:
def sum_digits2(n):
if n < 10:
return n
else:
return sum_digits2(sum(int(c) for c in str(n))) # this one returns an int
There are a couple of tricky things to watch out for. Hopefully this code gets you going in the right direction. You need to have a conditional for while on the number of digits remaining in your sum. The other thing is that you need to covert back and forth between strings and ints. I have fixed the while loop here, but the string <-> int problem remains. Good luck!
def main():
count = 9999
Sum = 0
m = 0
n = input("Please enter an integer: ")
numList = list(n)
while count > 1:
count = len(numList)
for i in numList:
m = int(i)
Sum = m+Sum
print(Sum)
print(count)
# The following needs to be filled in.
numlist = ???
main()
You can do this without repeated string parsing:
import math
x = 105 # or get from int(input(...))
count = 1 + int(math.log10(x))
while x >= 10:
sum = 0
for i in xrange(count):
sum += x % 10
x /= 10
x = sum
At the end, x will be a single-digit number as described, and count is the number of original digits.
I would like to give credit to this stackoverflow question for a succinct way to sum up digits of a number, and the answers above for giving you some insight to the solution.
Here is the code I wrote, with functions and all. Ideally you should be able to reuse functions, and here the function digit_sum(input_number) is being used over and over until the size of the return value (ie: length, if sum_of_digits is read as a string) is 1. Now you can use the while loop to keep checking till the size is what you want, and then abort.
def digit_sum(input_number):
return sum(int(digit) for digit in str(input_number))
input_number = input("Please enter a number: ")
sum_of_digits = digit_sum(input_number)
while(len(str(sum_of_digits)) > 1):
sum_of_digits = digit_sum(input_number)
output = 'Sum of digits of ' + str(input_number) + ' is ' + str(sum_of_digits)
print output
input_number = sum_of_digits
this is using recursive functions
def sumo(n):
sumof = 0
while n > 0:
r = n%10 #last digit
n = n/10 # quotient
sumof += r #add to sum
if sumof/10 == 0: # if no of digits in sum is only 1, then return
return sumof
elif sumof/10 > 0: #else call the function on the sumof
sumo(sumof)
Probably the first temptation would be to write
while x > 9:
x = sum(map(int, str(x)))
that literally means "until there is only one digit replace x by the sum of its digits".
From a performance point of view however one should note that computing the digits of a number is a complex operation because Python (and computers in general) store numbers in binary form and each digit in theory requires a modulo 10 operation to be extracted.
Thus if the input is not a string to begin with you can reduce the number of computations noting that if we're interested in the final sum (and not in the result of intermediate passes) it doesn't really matter the order in which the digits are summed, therefore one could compute the result directly, without converting the number to string first and at each "pass"
while x > 9:
x = x // 10 + x % 10
this costs, from a mathematical point of view, about the same of just converting a number to string.
Moreover instead of working out just one digit however one could also works in bigger chunks, still using maths and not doing the conversion to string, for example with
while x > 99999999:
x = x // 100000000 + x % 100000000
while x > 9999:
x = x // 10000 + x % 10000
while x > 99:
x = x // 100 + x % 100
while x > 9:
x = x // 10 + x % 10
The first loop works 8 digits at a time, the second 4 at a time, the third two and the last works one digit at a time. Also it could make sense to convert the intermediate levels to if instead of while because most often after processing n digits at a time the result will have n or less digits, leaving while loops only for first and last phases.
Note that however the computation at this point is so fast that Python general overhead becomes the most important part and thus not much more can be gained.
You could define a function to find the sum and keep updating the argument to be the most recent sum until you hit one digit.
def splitSum(num):
Sum = 0
for i in str(num):
m = int(i)
Sum = Sum + m
return str(Sum)
n = input("Please enter an integer: ")
count = 0
while count != 1:
Sum = splitSum(n)
count = len(Sum)
print(Sum)
print(count)
n = Sum

Categories