number1 = int(input('Number #1: '))
number2 = int(input('Number #2: '))
l = len(str(number1))
l1 = len(str(number2))
print()
def addition():
print(' ',max(number1,number2))
print('+')
print(' ',min(number1,number2))
print('-'*(max(l,l1)+2))
print(' ')
print(' ',number1+number2)
def carries():
while (int(str(number1)[::-1])+int(str(number2)[::-1]))>=10:
carries = 0
carries = carries + 1
return carries
addition()
print()
print('Carries : ',carries())
I am trying to make a program that does the addition of two user input numbers and calculates the answer while also stating how many carries there are. Carries being if 9+8=17, then there would be 1 carry and so forth. I am having issues with having my program go beyond 1 carry. So this program so far is only applicable for user input numbers that when added are below 99. If you could explain to me how I would go about altering this program to make it applicable to any numbers, that would be great. I was thinking about using the len(number1) and len(number2) and then inputting the string of the user input backwards so it would look like str(number1[::-1])) but I do not think it works like that.
Fun one-liner solution
def numberOfCarryOperations(a, b):
f=lambda n:sum(map(int,str(n)));return(f(a)+f(b)-f(a+b))/9
# f is the digitSum function :)
Explanation
Asserting a,b >=0, you can proof mathematically: every time you have a carry, the digitSum decreases by 9.
9, because we are in number system 10, so we "lose 10" on one digit if we have carry, and we gain +1 as the carry.
Readable solution
def digitSum(n):
return sum(map(int,str(n)))
def numberOfCarryOperations(a, b)
# assert(a >= 0); assert(b >= 0);
return (digitSum(a) + digitSum(b) - digitSum(a+b)) / 9
I rewrote your carry function so it works, but the implementation is totally different. You first make the numbers strings so you can iterate through them. Then you make them equal length by appending 0's, and loop through each digit to check whether their sum (plus the carry) is over 9. If it is, increment the counter. Hope this helps:
number1 = int(input('Number #1: '))
number2 = int(input('Number #2: '))
l = len(str(number1))
l1 = len(str(number2))
print()
def addition():
print(' ',max(number1,number2))
print('+')
print(' ',min(number1,number2))
print('-'*(max(l,l1)+2))
print(' ')
print(' ',number1+number2)
def carries():
num1 = str(number1)
num2 = str(number2)
carry = 0
carries = 0
c1 = l
c2 = l
if (l < l1):
while (c1 < l1):
num1 = '0' + num1
c1+=1
if (l1 < l):
while (c2 < l):
num2 = '0' + num2
c2+=1
i = c1
while (i > 0):
if (int(num1[i-1])+int(num2[i-1])+carry > 9):
carry = 1;
carries+=1
else:
carry = 0
i-=1
return carries
addition()
print()
print('Carries : ',carries())
Edited with quick fix
Your while loop is fatally flawed.
You set carries to 0 every time, and then add 1, so there's no way to return anything but 0.
The return is inside the loop, so you will always return after the first iteration.
If the ones digits don't provide a carry, then you never get into the loop, and return None.
You don't provide for multiple carries, such as the three carries in 999 + 1.
If you remove the return from the while loop, you have an infinite loop: the terms of the condition never change. You don't iterate through anything.
You gave a function and a variable the same name. This is not good practice.
Here's a start for you, based loosely on your original routine.
Set the count of carries to 0.
Convert the two numbers to strings and find the common (shorter) length.
So long as you have digits in both numbers, grab the digits (moving from the right end) and see whether their numeric sum requires a carry. If so, increment the count.
def carries():
carry_count = 0
str1 = str(number1)
str2 = str(number2)
for digit_pos in range(1, min(len(str1), len(str2)) + 1):
if int(str1[-digit_pos]) + int(str2[-digit_pos]) >= 10:
carry_count += 1
return carry_count
Sample output:
Number #1: 77077
Number #2: 4444
77077
+
4444
-------
81521
Carries : 3
This still has deficiencies for you to fix. Most notably, it doesn't handle multiple carries. However, it should get you moving toward a solution.
Related
Have been trying to write some code that is supposed to read a string on a list and see if the string in question is present in a certain range, but the IF is just ignoring the WHILE loop entirely...
This is the full thing, i have no idea what is making this not work...
Thanks in advance
ls = list()
qt = int(input('How many numbers you want to analize: '))
for c in range(1,qt+1):
ls.append(input(f'Write the number you want to analize: '))
start = int(input('First digit: '))
end = int(input('Last digit: '))
i = 0
for c in range(start, end, 1):
n = str(c)
while i < len(ls):
if ls[i] in n:
print(n, end=' → ')
i += 1
print('Done')
The while loop is not beeing ignored. You have two main issues:
you do not reset i everytime the outside for loop enters a new iteration and because of that the part of the list which had already been checked for the first number is not beeing checked again for the next number. Move the i = 0 into the for loop and it will work as expected.
You are not including the last number when counting the range. If you want all numbers between two numbers to be checked you need to count up to end + 1.
my_list = []
quantity = int(input('How many numbers you want to analize: '))
for _ in range(1,quantity + 1):
my_list.append(input(f'Write the number you want to analize: '))
start = int(input('Start: '))
end = int(input('End: '))
for number in range(start, end + 1, 1):
i = 0
converted_number = str(number)
while i < len(my_list):
if my_list[i] in converted_number:
print(converted_number, end=' → ')
i += 1
print('Done')
Another issue you have in your code is that it is unreadable. You should always try to make your code is as easy to understand as possible. Never use single character variable names (apart from counting variables like i or maybe mathematical expressions like m*x + b but not! a*b*c if you are dealing with cuboids as the three sides are different, always use length, width and height in that case).
I changed the single character variable names in your code to descriptive names to make it easier to understand.
I'm writing a program that takes a number from input and generates it's palindrome number. My program only prints the first half not the second. I tried reverse, didnt work.I have incluede those lines as comment.
My Code:
def show_palindrome(maximum):
maximum = int(input("Enter Number : "))
for number in range(1, maximum + 1):
temporary = number
reverse = 0
while (temporary > 0):
reminder = temporary % 10
reverse = (reverse * 10) + reminder
temporary = temporary //10
if(number == reverse):
#number2 = number[::-1]
#print(number,number2, end = '')
print(number, end = '')
show_palindrome(3)
My output:
123
The output I need:
12321
I believe you're looking for something like this:
def show_palindrome(maximum = None):
if not maximum:
maximum = input("Enter Number : ")
output = str(maximum)
for number in range(1, int(maximum)):
output = str(int(maximum) - number) + str(output) + str(int(maximum) - number)
return output
print(show_palindrome(3))
this returns 12321 for instance
A couple of things I would do differently in your function:
If you're going to require the input in the def (The way you make it optional is to set it equal to something when you declare it like I have it set to None (maximum=None), then you don't need the input() statement.
Since you already know how long you want it to be ( you require it declared when you initialize the function, it's just 2*maximum - 1) there's really no need to use a while loop.
Other than that good job! Keep it up!
You can try something simpler like this:
def show_palindrome():
num = input("Enter Number : ")
print(num + num[:-1][::-1])
show_palindrome()
Input:
123
12
1
Output:
12321
121
1
Apart from the string slice method (as used by #PApostol), you could also use the reversed method :
def show_palindrome():
value = input("Enter Number : ")
print(value[:-1] + "".join(reversed(value)))
Input:
123
Output:
12321
def palindrome(maximum):
number = ''.join([str(num) for num in range(1, maximum + 1)])
return int(number + number[-2::-1])
print(palindrome(3))
Output:
12321
Your code seems over complicated, and I don't even know what to fix in it. What I can tell is that passing a parameter maximum to overwrite it just after with maximum = int(input("Enter Number : ")) is useless, don't pass the parameter.
So let's back to easy things
Build palindrome using strings method : slicing backwards from index -2, and reverse it with -1 increment
def show_palindrome():
value = input("Enter Number : ")
print(value + value[-2::-1])
Build palindrome using math operations : save the remainder, except the first one
def show_palindrome():
value = input("Enter Number : ")
result = value
value = int(value) // 10 # remove last char which would be redundant
while value > 0:
result += str(value % 10)
value = value // 10
print(result)
show_palindrome()
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
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
I've made a program which takes number of test cases as input and for each test case, it needs a number as input. Finally it checks whether the numbers you have entered are fibonacci numbers or not and prints accordingly. I've had no problems running it on my PC.But when i upload it to CodeChef.com(where i saw this quesion), it shows runtime error.
Any help is appreciated and as i'm a noob my code might look lengthy ., any modifications are welcome.Thanks!
Here's my code:
def isperfect(n):
import math
if n < 0:
print("No Solution")
return False
else:
test = int(math.sqrt(n))
return test*test == n
test_cases = int(input())
count = 0
store = []
while count < test_cases:
x = int(input())
store.append(x)
count += 1
for each_item in store:
assert isinstance(each_item, int)
s1 = 5*each_item*each_item-4
s2 = 5*each_item*each_item+4
if(isperfect(s1) == True or isperfect(s2) == True):
print("YES")
else:
print("NO")
This is the most elegant solution i've encountered:
def is_fibonacci(n):
phi = 0.5 + 0.5 * math.sqrt(5.0)
a = phi * n
return n == 0 or abs(round(a) - a) < 1.0 / n
The code is not mine, was posted by #sven-marnach.
The original post:
check-input-that-belong-to-fibonacci-numbers-in-python
The runtime error is apparently due to an exception, but Codechef does not provide any more information. It could be various things including divide by zero, memory exhaustion, assertion failure, ...
Although your program works for many common numbers, it doesn't handle all the inputs that the Codechef constraints allow. In particular, the number to be tested can have up to 1000 digits in it. If you try a large input like a 1000-digit number, you'll find it fails. First it fails because of your assert isinstance(each_item, int); a number of 12 digits or more is not of type int. You can just remove the assertion. The next failure occurs because you are using the floating point sqrt routine, and that requires the integer to be converted into floating point. Python can handle very long integers, but the floating point representation is more limited in its precision, and cannot handle 1000 digit integer conversions. That's harder to fix, but can be done. See this ActiveState recipe for an all-integer solution for square root.
I've figured that this can be done by using Newton- Raphson method, i have replaced the code in the function isperfect() with Newton-Raphson formula code, removed assertion and it worked. Thanks for all your help.
Here's the final code:
def isperfect(n):
x = n
y = (x + n // x) // 2
while y < x:
x = y
y = (x + n // x) // 2
return x*x == n
test_cases = int(input())
count = 0
store = []
while count < test_cases:
x = int(input())
store.append(x)
count += 1
for each_item in store:
s1 = 5*each_item*each_item-4
s2 = 5*each_item*each_item+4
if(isperfect(s1) == True or isperfect(s2) == True):
print("YES")
else:
print("NO")
This is going to be a very efficient way of doing it.
In [65]:
import scipy.optimize as so
from numpy import *
In [66]:
def fib(n):
s5=sqrt(5.)
return sqrt(0.2)*(((1+s5)/2.)**n-((1-s5)/2.)**n)
def apx_fib(n):
s5=sqrt(5.)
return sqrt(0.2)*(0.5*(1+s5))**n
def solve_fib(f):
_f=lambda x, y: (apx_fib(x)-y)**2
return so.fmin_slsqp(_f,0., args=(f,),iprint=0)
def test_fib(fibn):
if fibn<1:
print 'No, it is not'
else:
n=int(round(solve_fib(fibn)))
if int(round(fib(n)))==int(fibn):
print 'Yes, it is. (%d)'%n
else:
print 'No, it is not'
In [67]:
asarray(fib(arange(1,20)), dtype='int64')
Out[67]:
array([ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89,
144, 233, 377, 610, 987, 1597, 2584, 4181])
In [68]:
test_fib(34)
Yes, it is. (9)
In [69]:
test_fib(4181)
Yes, it is. (19)
In [70]:
test_fib(4444)
No, it is not
Fairly simple and efficient way of doing it
def isInFib(n):
if n == 0: return False
elif n == 1: return True
else:
A = 1
B = 1
FLIP = True
while(True):
new = A + B
if new > n: return False
elif new == n: return True
else:
if(FLIP):
A = new
FLIP = not FLIP
else:
B = new
FLIP = not FLIP
Explanation of Algorithm
I first check if my input is equal to 0 or 1, and return appropriate.
If my input is greater than 1, we go into the else, infinite loop.
A and B represent the last two previous numbers in the sequence. We add A and B to get new, the current Fibonacci number.
We check if new is equal to our input number, if that's true we return true, we are done and complete the function.
If it's greater, that means our number is not in the Fibonacci sequence, since we have surpassed it.
if it's less, we need to keep going! and this is where I think it get's confusing to explain. I want to set up A or B as my current fibonacci sequence number (new), but I have make sure that I keep switching between them, since I don't want one to get left behind. Fibonacci sequence takes the previous 2 numbers and adds them together. I want A and B to be my last two previous sums.
I'll use an example
1,1,2,3,5,8,13
A and B are initially 1. So new is equal to 2 first. I then check if I'm over my input number or equal to it. But if my input number is less. I want to keep going.
I want A to equal new (value = 2) then, before we get to our next iteration of the while loop. So that new will equal 2 + 1 as A + B on the next iteration.
But, then THE next iteration of the loop, I want to set B as 3, and I want to leave A being equal to 2. So I have to keep switching between putting the current fibonacci number I'm at, in A or B. And that's why I have the flip logic! It just keeps switching between True and False.
Try this function:
def isfib(number):
num1 = 1
num2 = 1
while True:
if num2 <= number:
if num2 == number:
return True
else:
tempnum = num2
num2 += num1
num1 = tempnum
else:
return False
Here's how it works:
Set num1 and num2 to 0.
If num2 isn't less than or equal to the number return False.
If num2 is equal to the number return True.
Set add num1 to num2, set num1 to num2's original value and go back to step 2.
num=int(input("Enter a number : "))
n1=0
n2=1
i=1
lst=[]
lst.append(n1)
lst.append(n2)
while i<num-1:
n3=n1+n2
n1=n2
n2=n3
lst.append(n3)
i=i+1
for i in lst:
if (num == i):
print("Fibonacci number")
break
else:
print("Not fibonacci")
def isfib(number):
num1 = 0
num2 = 1
while True:
if num2 <= number:
if num2 == number:
return True
else:
tempnum = num2
num2 += num1
num1 = tempnum
else:
return False
n=int(input())
number=n
fibonacci=isfib(number)
if (fibonacci):
print("true")
elif n==0:
print("true")
else:
print("false")