Is there a more effective implementation? - python

Problem statement:
You are given two positive integers
d
and
s
. Find minimal positive integer
n
which is divisible by
d
and has sum of digits equal to
s
.
Input:
The first line contains two positive integers
d
and
s
(
1
≤
d
≤
500
,
1
≤
s
≤
5000
) separated by space.
Output:
Print the required number or -1 if it doesn't exist.
This my code:
d_and_s = [int(x) for x in input().split()]
counter_dracula = 0
while True:
if counter_dracula%d_and_s[0] == 0 and sum(map(int, str(counter_dracula))) == d_and_s[1]:
break
counter_dracula += 1
print(counter_dracula)
That's my implementation but clearly there must be a faster way.
For example if the Input is 13 and 50 the output is 699998.
My code gives me the correct answer but takes a long time but even ultra longer in this sample testcase: Input is 61 and 2 and the output is 1000000000000000000000000000001.
How can I implement them correctly using Python 3?

(yey, the question opened again :-) )
For one quite improvement, realize that the numbers divisible by d is d, 2*d, 3*d, 4*d , ...
So instead of incrementing the loop by 1 every time, you can increment with d
def sum_digits(n):
r = 0
while n:
r, n = r + n % 10, n // 10
return r
d, s = [int(x) for x in input().split()]
counter = 0
while True:
counter += d
if sum_digits(counter) == s:
break
print(counter)

Related

how to find a number with max divisors from a set of input numbers?

I wrote this code to find the number with max divisors, but in the case with equal divisors like 672 and 8388608 which both of them have 24 divisors the code cannot select the biggest number and just return the first number with the more number of divisors. In that example, the code returns 672 while it is vivid that 8388608 is much bigger than 672!
please help me to modify my code.
thank you in advance.
def divisors(x):
c = 0
for i in range (1,x+1):
if x % i == 0:
c += 1
return c
m = 0
count = 0
for i in range (20):
a = int(input())
if divisors(a) > count:
m = a
count = divisors(a)
print(m,'',count)
This code will collect the maximum number of divisors in a list, resetting the list if a greater number is found, and appending to the list otherwise. If there are multiple numbers with the same number of divisors, you'll get a list of them:
def divisors(x):
c = 0
for i in range (1,x+1):
if x % i == 0:
c += 1
return c
m = []
count = 0
inputs = 767,665,999,895,907,796,561,914,719,819,555,529,672,933,882,869,801,660,879,985
for a in sorted(inputs):
d = divisors(a)
if d == count:
m.append(a)
elif d > count:
m = [a]
count = d
print(m,'',count)
Output:
[660, 672] 24
If you just want the biggest number, use max(m) in the final print instead.

Python: Why does while loop exclude the first value?

I am trying to make a decimal to binary converter, however, I noticed that some values are being ignored and the last value is not being entered into the list I created.
#Here we create a new empty list.
binary = []
n = int(input("Enter number: "))
while n > 1:
n = n//2
m = n%2
binary.append(m)
binary.reverse()
print( " ".join( repr(e) for e in binary ))
This is your code after correction :
binary = []
n = int(input("Enter number: "))
while n > 0:
m = n%2
n = n//2
binary.append(m)
if len(binary)==0:
binary.append(0)
binary.reverse()
print( " ".join( repr(e) for e in binary ))
Your question is duplicate to this stackoverflow question check the link too.
good luck :)
As PM 2Ring suggested a tuple assignment may be the way to go. Makes your code shorter too :-) ... also changed n > 1 to n >= 1
binary = []
n = int(input("Enter number: "))
while n >= 1:
n, m = n // 2, n % 2
binary.append(m)
binary.reverse()
print( " ".join( repr(e) for e in binary ))
n = int(input("Enter number: "))
print("{0:0b}".format(n)) # one-line alternate solution
if n == 0: # original code with bugs fixed
binary = [0]
else:
binary = []
while n > 0:
m = n%2
n = n//2
binary.append(m)
binary.reverse()
print("".join( repr(e) for e in binary ))
Your algorithm is close, but you need to save the remainder before you perform the division. And you also need to change the while condition, and to do special handling if the input value of n is zero.
I've fixed your code & put it in a loop to make it easier to test.
for n in range(16):
old_n = n
#Here we create a new empty list.
binary = []
while n:
m = n % 2
n = n // 2
binary.append(m)
# If the binary list is empty, the original n must have been zero
if not binary:
binary.append(0)
binary.reverse()
print(old_n, " ".join(repr(e) for e in binary))
output
0 0
1 1
2 1 0
3 1 1
4 1 0 0
5 1 0 1
6 1 1 0
7 1 1 1
8 1 0 0 0
9 1 0 0 1
10 1 0 1 0
11 1 0 1 1
12 1 1 0 0
13 1 1 0 1
14 1 1 1 0
15 1 1 1 1
As Blckknght mentions in the comments, there's a standard function that can give you the quotient and remainder in one step
n, m = divmod(n, 2)
It can be convenient, but it doesn't really provide much benefit apart from making the code a little more readable. Another option is to use a tuple assignment to perform the operations in parallel:
n, m = n // 2, n % 2
It's a good practice, especially when you're new to coding, to work through your algorithm on paper to get a feel for what it's doing. And if your code doesn't give the expected output it's a good idea to add a few print calls in strategic places to check that the values of your variables are what you expect them to be. Or learn to use a proper debugger. ;)

Memory error for code to find sum of Even Fibonacci numbers in python

I was writing code for finding sum of even-valued terms in Fibonacci sequence whose values do not exceed four million.the code works fine for values upto 40k But I got an memory error for finding upto 4 million can someone help me resolve the problem
my code is:
def fib(x):
l=[0,1]
m=[]
a=0
c=0
b=1
while len(l) <=x:
d=c+b
c=b
b=d
l.append(d)
if d%2==0:
m.append(d)
a=a+d
print
print a
print m
Just to clarify as I understand: You are looking for a function which returns the sum of all the even numbers in the fibonacci sequence, up to 4 million. Try it with two separate functions like this.
The first function for a given number in the fibonacci sequence:
def fib(n):
a = 0
b = 1
for e in range(n):
old_a = a
a = b
b = old_a + b
return a
The second function for the sum which calls the earlier function (and uses a count, not a list, so as to save on memory.):
def even_sum(t):
total = 0
for x in range(t):
fib_x = fib(x)
if fib_x % 2 == 0:
total += fib_x
print fib_x # <-- this line is optional,
# include it if you want to see each
# even number printed.
return total
Then call your function. For example:
print even_sum(100)
which gives us this answer:
286573922006908542050
try this:
def sum_fib(x):
a = 0
c = 0
b = 1
l = 2
while l <=x:
d = c + b
c = b
b = d
l += 1
# yoda conditions check
if 0 == d % 2: # using binary should be faster (0 == d & 1)
a += d
print
print a
As said in the comments replace l with a counter. If you need to print all the even fib numbers keep m otherwise remove it all together.
Initialize count
count = 2
And every time around the while loop increment count by 1.
Here's a version that eliminates the unnecessary lists, as I described in my comments. Note that you are still going to have an exponentially-growing sum, which is unavoidable:
def fib(x):
lc=2
mc=0
a=0
c=0
b=1
while lc <=x:
d=c+b
c=b
b=d
lc += 1
if d%2==0:
mc += 1
a += d
print
print a
print mc

Sum of all the multiples of 3 or 5 below 1000

Beginner here- trying to make a simple python program that will compute/answer this problem:
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
Currently this is what I have:
a = 0
b = 0
while a < 1000:
a = a + 3
print (a)
while b < 1000
b = b + 5
print (b)
This will print all the numbers being considered. I just need to add them together and that's my answer.
I would like one of two things to happen, instead of the code that I have written:
I would like all of this to happen internally, and therefore not have to use the "print" function. The just print the sum of all of those multiples.
I would like all of this stuff to print, but then I want to be able to print the sum of all of them too. Is there a way to make the computer take the value of everything it has printed?
Actually this problem can be solved in O(1) instead of O(N) without using any loops or lists:
The required sum is the sum of all multiples of 3 plus sum of all multiples of 5 minus the sum of multiples of (3*5=15) below the given number 1000 (LIMIT=999). The sums are calculated as a sum of arithmetic series.
It can be calculated in following way:
LIMIT=999
# Get the upper bounds for the arithmetic series
upper_for_three = LIMIT // 3
upper_for_five = LIMIT // 5
upper_for_fifteen = LIMIT // 15
# calculate sums
sum_three = 3*upper_for_three*(1 + upper_for_three) / 2
sum_five = 5*upper_for_five*(1 + upper_for_five) / 2
sum_fifteen = 15*upper_for_fifteen*(1 + upper_for_fifteen) / 2
# calculate total
total = sum_three + sum_five - sum_fifteen
# print result with Python 3
print(int(total))
The result is:
>>>
233168
It is possible to do this in one line in Python using a generator expression:
print(sum(x for x in range(1000) if x % 3 == 0 or x % 5 == 0))
The range(1000) produces all the integers from 0 to 999 inclusive. For each one of those integers, if it is divisible by 3 or divisible by 5, then it is included in the result. The sum(...) function adds up all those numbers, and finally print(...) prints the result.
I would use a for loop to iterate over each number in your selected range. Then you can check if the modulus % is equal to 0, meaning it has no remainder when divided by those values, if so, add it to the total.
total = 0
for num in range(1000):
if num % 3 == 0 or num % 5 == 0:
print(num)
total += num
>>> total
233168
While a for loop would work, you could also use a generator expression and sum:
sum(n for n in range(1000) if n % 3 == 0 or n % 5 == 0)
def sum_multiply (n):
data = []
for num in range (1, n):
if num % 3 == 0 or num % 5 == 0:
data.append(num)
return sum(data)
sum_multiply(1000)
total=0
i=0
while i<1000:
if i%3==0 or i%5==0:
print(num)
total+=i
i+=1
print("Total is: ")
**with python**
print(sum([i for i in range(1,1000) if i%3==0 or i%5==0 ]))

fibonacci sequence going from point a to point b?

m = 2
n =20
a,b = m,0
fib = [m]
while a <= n:
fib.append(a)
a,b = a+b, a
So given two variables from m to n (and m < n), I need to create a list containing all the numbers of the Fibonacci sequence between m and n inclusive (but cannot exceed) ex: if m = 2 and n = 20 then fib should be [2,3,5,8,13].
I do not know how to start the fibonnaci sequence midway, so the best I can think of is to filter the results afterwards.
def f(low, high):
fib = [0]
a, b = 1, 0
while a <= n:
fib.append(a)
a,b = a+b, a
return filter(lambda x: x >= low and x =< high, fib)
The fibonacci code is trivial, the new thing you might be seeing here is filter, which takes a function f and an iterable x, and returns a new iterable with all of the elements from x such that f(x) is true.
def fib(m,n):
a,b = 1,1
while a < m:
a,b = b, a+b
answer = [a]
while b < n:
a,b = b, a+b
answer.append(a)
return answer
In [2040]: fib(2,20)
Out[2040]: [2, 3, 5, 8, 13]
m = int(raw_input("Enter the start number : "))
n = int(raw_input("Enter the end number : "))
def fib(i):
if i == 0: return 0
elif i == 1: return 1
else: return f(i-1)+f(i-2)
print map(fib, range(m, n))
I hope this is what you need.
I thanks it's simple and clear to calculate the Fibonacci number recursively or by put all the number in a list. But if the number is too large, it not a good idea.
Here is code ,BTW
def main():
print fibo(100,600)
def fibo(m,n):
f0=2
f1=3
while f1<m:
tmp=f1
f1=f0+f1
f0=tmp
res=[f0]
while f1<n:
res.append(f1)
f1=res[-2]+res[-1]
return res[1:];
if __name__ == '__main__':
main()
I googled and find the n-th term formula of fibonacci here
so the codes could be:
def fibn(n):
Phi = (1+math.sqrt(5))/2
phi = (1-math.sqrt(5))/2
return round((math.pow(Phi, n) - math.pow(phi, n))/math.sqrt(5))
>>> fibn(0)
0.0
>>> fibn(1)
1.0
>>> fibn(2)
1.0
>>> fibn(3)
2.0
>>> fibn(4)
3.0
>>> fibn(5)
5.0
>>> fibn(6)
8.0
>>> fibn(7)
13.0
>>> fibn(8)
21.0
>>> fibn(9)
34.0
>>> fibn(10)
55.0
You could do something like:
def fibs(low,high):
a, b = 0, 1
while 1:
a, b = b, a+b
if low <= a:
if a <= high:
yield a
else:
break
you can use it like
>>> for num in fibs(2,15):
... print num
...
2
3
5
8
13
But without resorting to the formula for the nth Fibonacci number and relying on proper rounding there isn't a way of getting the nth number without computing the first n-1 numbers.
So, if you don't want to use the formula it would probably be best to just keep a list of the Fibonacci numbers around and use that, if it turns out you need numbers between low and high where high > fib_nums[-1] then you can always use fib_nums[-1] and fib_nums[-2] as b and a to compute the values you're missing.
There are a few subproblems to consider for getting a log order solution, assuming (n-m) is relatively small. If (n-m) can be relatively large its best to precompute all reults and simply do a binary search.
Can we find i th fibonacci number in log time?
Can we find the number j such that fib(j) >= m ?
For first problem we can find i th fibonacci using (http://en.wikipedia.org/wiki/Fibonacci_number#Matrix_form).
And the second problem can be solved using a binary search and uses first method to find the fibonacci number >= m. Once we know j we can find j+1 th fibonacci number in log time, and simply generate all other numbers <=n using these.
Using Generator :
import os,sys
def fib(num):
a=0
b=1
while 1:
a,b =b, b+a
yield a
low=2
high=200
for i in fib(range(1)):
if i <= high and i >= low :
print i
elif i > high:
break
O/P
2
3
5
8
13
21
34
55
89
144

Categories

Resources