Can anybody explain me print statement in this code? - python-3.x

I found this code on internet but I am not able to understand how the print statement is working.
I have already tried to see many answers but none answers it perfectly.
def main():
n=int(raw_input())
for i in range(0, 1<<n):
gray=i^(i>>1)
print "{0:0{1}b}".format(gray,n),
main()

for i in range(0, 1<<n):
Here, 1 << n shifts 1 by n bits to left. It means:
if n = 1, 1 << 1 would be 10,
n = 2, 1 << 10 would be 100 [2 = binary 10]
and so on.
For decimal number the answer is equivalent 2 to the power n.
For binary 'n' number of zeros are added.
So the range is for i in range(0, 2 ** n).
gray=i^(i>>1)
Here i>>1 shifts i by 1 bit to right. It means:
if i = 1, 1 >> 1 would be 0,
i = 2, 10 >> 1 would be 1 [2 = binary 10]
i = 3, 100 >> 1 would be 10 (in binary) 2 in decimal
and so on.
For decimal numbers it is equivalent to dividing by 2 (and ignoring digits after . decimal point).
For binary last digit is erased.
^ is exclusive OR operator. It is defined as:
0 ^ 0 = 0,
0 ^ 1 = 1 ^ 0 = 1,
1 ^ 1 = 0
print "{0:0{1}b}".format(gray,n)
Here {1} refers to n, b refers to binary. So gray is converted to binary and expressed in n digits.

What you are looking at is known by the concept of Advanced string formatting. Specifically, PEP 3101 Advanced string Formatting
You may refer the official documentation for understanding purposes.

Related

Why can't I store all Fibonacci numbers up to the 1000000th in a Python list?

This code gives out a fibonacci number.
With larger number it produces memory error. Can i allocate more ram or resources to the compiler or is there a more efficient code that i can use?
list1 = [0, 1]
x = 0
while x < 1000000:
list1.append(list1[-1] + list1[-2])
x+=1
print(list1[-1])
If you are interested in the last number, don't store the intermediate results.
I just tried it (using sys.getsizeof()) and the sum of all integer values in the list would be 46308778320 bytes. Which is 46 GByte.
Even though the 1000000th Fibobacci number only has 92592 bytes
There is no limit to how big an integer can be in Python.
This is how the size of the integers grows:
A small integer in Python has already has 28 bytes, which is quite large compared to a C int.
More info on this can be found at "sys.getsizeof(int)" returns an unreasonably large value?
How to calculate the total size?
import sys
fib = None
size_fib = 0
for _ in range(1000000):
fib = ... # calculation here
size_fib += sys.getsizeof(fib)
print(size_fib)
I found the 1000000th Fibobacci number using the following code,
it took a minute or so to calculate the result.
cache = {}
for x in range(1, 1000001):
if x > 4:
cache.pop(x-3, x-4)
if x <= 2:
value = 1
cache[x] = value
else:
value = cache[x - 1] + cache[x - 2]
cache[x] = value
print(value)

Project Euler #23 Optimization [Python 3.6]

I'm having trouble getting my code to run quickly for Project Euler Problem 23. The problem is pasted below:
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
And my code:
import math
import bisect
numbers = list(range(1, 20162))
tot = set()
numberabundance = []
abundant = []
for n in numbers:
m = 2
divisorsum = 1
while m <= math.sqrt(n):
if n % m == 0:
divisorsum += m + (n / m)
m += 1
if math.sqrt(n) % 1 == 0:
divisorsum -= math.sqrt(n)
if divisorsum > n:
numberabundance.append(1)
else:
numberabundance.append(0)
temp = 1
# print(numberabundance)
for each in numberabundance:
if each == 1:
abundant.append(temp)
temp += 1
abundant_set = set(abundant)
print(abundant_set)
for i in range(12, 20162):
for k in abundant:
if i - k in abundant_set:
tot.add(i)
break
elif i - k < i / 2:
break
print(sum(numbers.difference(tot)))
I know the issue lies in the for loop at the bottom but I'm not quire sure how to fix it. I've tried modeling it after some of the other answers I've seen here but none of them seem to work. Any suggestions? Thanks.
Your upper bound is incorrect - the question states all integers greater than 28123 can be written ..., not 20162
After changing the bound, generation of abundant is correct, although you could do this generation in a single pass by directly adding to a set abundant, instead of creating the bitmask array numberabundance.
The final loop is also incorrect - as per the question, you must
Find the sum of all the positive integers
whereas your code
for i in range(12, 20162):
will skip numbers below 12 and also doesn't include the correct upper bound.
I'm a bit puzzled about your choice of
elif i - k < i / 2:
Since the abundants are already sorted, I would just check if the inner loop had passed the midpoint of the outer loop:
if k > i / 2:
Also, since we just need the sum of these numbers, I would just keep a running total, instead of having to do a final sum on a collection.
So here's the result after making the above changes:
import math
import bisect
numbers = list(range(1, 28123))
abundant = set()
for n in numbers:
m = 2
divisorsum = 1
while m <= math.sqrt(n):
if n % m == 0:
divisorsum += m + (n / m)
m += 1
if math.sqrt(n) % 1 == 0:
divisorsum -= math.sqrt(n)
if divisorsum > n:
abundant.add(n)
#print(sorted(abundant))
nonabundantsum = 0
for i in numbers:
issumoftwoabundants = False
for k in abundant:
if k > i / 2:
break
if i - k in abundant:
issumoftwoabundants = True
break
if not issumoftwoabundants:
nonabundantsum += i
print(nonabundantsum)
Example here

Change-making: Dynamic Programming

In a lecture earlier, we were told that using a greedy approach to solve a change making problem would not always work.
An example of this was given as follows:
We want to reach n = 14, and we have three coins of different values: d1 = 1,d2 = 7,d3 = 10.
Using the greedy approach this would lead us to do 10 + 1 + 1 + 1 + 1 (5 coins).
It was said the a dynamic problem approach would solve this accurately. I tried working it out but it came back to 5.
Assume F holds the number of coins needed to make an amount
F[14] = min {F[14 – 1] , F[14 – 7], F[14 – 10]} + 1
= F[14 – 10] + 1 = 4 + 1 = 5
This shows again that we need 5 coins, when this can clearly be done by using 2 coins (7 + 7).
What gives? Thanks.
You assumed that min {F[14 – 1] , F[14 – 7], F[14 – 10]}=F[14-10] when it is not the case. The minimum is actually F[14-7]=1 and hence the optimum is 2

split a value into values in max, min range

I want to find an efficient algorithm to divide an integer number to some value in a max, min range. There should be as less values as possible.
For example:
max = 7, min = 3
then
8 = 4 + 4
9 = 4 + 5
16 = 5 + 5 + 6 (not 4 + 4 + 4 + 4)
EDIT
To make it more clear, let take an example. Assume that you have a bunch of apples and you want to pack them into baskets. Each basket can contain 3 to 7 apples, and you want the number of baskets to be used is as small as possible.
** I mentioned that the value should be evenly divided, but that's not so important. I am more concerned about less number of baskets.
This struck me as a fun problem so I had a go at hacking out a quick solution. I think this might be an interesting starting point, it'll either give you a valid solution with as few numbers as possible, or with numbers as similar to each other as possible, all within the bounds of the range defined by the min_bound and max_bound
number = int(input("Number: "))
min_bound = 3
max_bound = 7
def improve(solution):
solution = list(reversed(solution))
for i, num in enumerate(solution):
if i >= 2:
average = sum(solution[:i]) / i
if average.is_integer():
for x in range(i):
solution[x] = int(average)
break
return solution
def find_numbers(number, division, common_number):
extra_number = number - common_number * division
numbers_in_solution = [common_number] * division
if extra_number < min_bound and \
extra_number + common_number <= max_bound:
numbers_in_solution[-1] += extra_number
elif extra_number < min_bound or extra_number > max_bound:
return None
else:
numbers_in_solution.append(extra_number)
solution = improve(numbers_in_solution)
return solution
def tst(number):
try:
solution = None
for division in range(number//max_bound, number//min_bound + 1): # Reverse the order of this for numbers as close in value to each other as possible.
if round (number / division) in range(min_bound, max_bound + 1):
solution = find_numbers(number, division, round(number / division))
elif (number // division) in range(min_bound, max_bound + 1): # Rarely required but catches edge cases
solution = find_numbers(number, division, number // division)
if solution:
print(sum(solution), solution)
break
except ZeroDivisionError:
print("Solution is 1, your input is less than the max_bound")
tst(number)
for x in range(1,100):
tst(x)
This code is just to demonstrate an idea, I'm sure it could be tweaked for better performance.

Count the Number of Zero's between Range of integers

. Is there any Direct formula or System to find out the Numbers of Zero's between a Distinct Range ... Let two Integer M & N are given . if I have to find out the total number of zero's between this Range then what should I have to do ?
Let M = 1234567890 & N = 2345678901
And answer is : 987654304
Thanks in advance .
Reexamining the Problem
Here is a simple solution in Ruby, which inspects each integer from the interval [m,n], determines the string of its digits in the standard base 10 positional system, and counts the occuring 0 digits:
def brute_force(m, n)
if m > n
return 0
end
z = 0
m.upto(n) do |k|
z += k.to_s.count('0')
end
z
end
If you run it in an interactive Ruby shell you will get
irb> brute_force(1,100)
=> 11
which is fine. However using the interval bounds from the example in the question
m = 1234567890
n = 2345678901
you will recognize that this will take considerable time. On my machine it does need more than a couple of seconds, I had to cancel it so far.
So the real question is not only to come up with the correct zero counts but to do it faster than the above brute force solution.
Complexity: Running Time
The brute force solution needs to perform n-m+1 times searching the base 10 string for the number k, which is of length floor(log_10(k))+1, so it will not use more than
O(n (log(n)+1))
string digit accesses. The slow example had an n of roughly n = 10^9.
Reducing Complexity
Yiming Rong's answer is a first attempt to reduce the complexity of the problem.
If the function for calculating the number of zeros regarding the interval [m,n] is F(m,n), then it has the property
F(m,n) = F(1,n) - F(1,m-1)
so that it suffices to look for a most likely simpler function G with the property
G(n) = F(1,n).
Divide and Conquer
Coming up with a closed formula for the function G is not that easy. E.g.
the interval [1,1000] contains 192 zeros, but the interval [1001,2000] contains 300 zeros, because a case like k = 99 in the first interval would correspond to k = 1099 in the second interval, which yields another zero digit to count. k=7 would show up as 1007, yielding two more zeros.
What one can try is to express the solution for some problem instance in terms of solutions to simpler problem instances. This strategy is called divide and conquer in computer science. It works if at some complexity level it is possible to solve the problem instance and if one can deduce the solution of a more complex problem from the solutions of the simpler ones. This naturally leads to a recursive formulation.
E.g. we can formulate a solution for a restricted version of G, which is only working for some of the arguments. We call it g and it is defined for 9, 99, 999, etc. and will be equal to G for these arguments.
It can be calculated using this recursive function:
# zeros for 1..n, where n = (10^k)-1: 0, 9, 99, 999, ..
def g(n)
if n <= 9
return 0
end
n2 = (n - 9) / 10
return 10 * g(n2) + n2
end
Note that this function is much faster than the brute force method: To count the zeros in the interval [1, 10^9-1], which is comparable to the m from the question, it just needs 9 calls, its complexity is
O(log(n))
Again note that this g is not defined for arbitrary n, only for n = (10^k)-1.
Derivation of g
It starts with finding the recursive definition of the function h(n),
which counts zeros in the numbers from 1 to n = (10^k) - 1, if the decimal representation has leading zeros.
Example: h(999) counts the zero digits for the number representations:
001..009
010..099
100..999
The result would be h(999) = 297.
Using k = floor(log10(n+1)), k2 = k - 1, n2 = (10^k2) - 1 = (n-9)/10 the function h turns out to be
h(n) = 9 [k2 + h(n2)] + h(n2) + n2 = 9 k2 + 10 h(n2) + n2
with the initial condition h(0) = 0. It allows to formulate g as
g(n) = 9 [k2 + h(n2)] + g(n2)
with the intital condition g(0) = 0.
From these two definitions we can define the difference d between h and g as well, again as a recursive function:
d(n) = h(n) - g(n) = h(n2) - g(n2) + n2 = d(n2) + n2
with the initial condition d(0) = 0. Trying some examples leads to a geometric series, e.g. d(9999) = d(999) + 999 = d(99) + 99 + 999 = d(9) + 9 + 99 + 999 = 0 + 9 + 99 + 999 = (10^0)-1 + (10^1)-1 + (10^2)-1 + (10^3)-1 = (10^4 - 1)/(10-1) - 4. This gives the closed form
d(n) = n/9 - k
This allows us to express g in terms of g only:
g(n) = 9 [k2 + h(n2)] + g(n2) = 9 [k2 + g(n2) + d(n2)] + g(n2) = 9 k2 + 9 d(n2) + 10 g(n2) = 9 k2 + n2 - 9 k2 + 10 g(n2) = 10 g(n2) + n2
Derivation of G
Using the above definitions and naming the k digits of the representation q_k, q_k2, .., q2, q1 we first extend h into H:
H(q_k q_k2..q_1) = q_k [k2 + h(n2)] + r (k2-kr) + H(q_kr..q_1) + n2
with initial condition H(q_1) = 0 for q_1 <= 9.
Note the additional definition r = q_kr..q_1. To understand why it is needed look at the example H(901), where the next level call to H is H(1), which means that the digit string length shrinks from k=3 to kr=1, needing an additional padding with r (k2-kr) zero digits.
Using this, we can extend g to G as well:
G(q_k q_k2..q_1) = (q_k-1) [k2 + h(n2)] + k2 + r (k2-kr) + H(q_kr..q_1) + g(n2)
with initial condition G(q_1) = 0 for q_1 <= 9.
Note: It is likely that one can simplify the above expressions like in case of g above. E.g. trying to express G just in terms of G and not using h and H. I might do this in the future. The above is already enough to implement a fast zero calculation.
Test Result
recursive(1234567890, 2345678901) =
987654304
expected:
987654304
success
See the source and log for details.
Update: I changed the source and log according to the more detailed problem description from that contest (allowing 0 as input, handling invalid inputs, 2nd larger example).
You can use a standard approach to find m = [1, M-1] and n = [1, N], then [M, N] = n - m.
Standard approaches are easily available: Counting zeroes.

Resources