I just started to code and try to build my first function in Python/NumPy. My first goal was to get a list for all multiplies of 31 which are not divisible by numbers 1>31 and I figured it out
Here is the code:
c = float(input("Range?"))
a = np.arange(1,c)
A = np.array([31*a])
B=(A[(A%2!=0) & (A%3!=0) & (A%5!=0) & (A%7!=0) & (A%11!=0) & (A%13!=0) & (A%17!=0) & (A%19!=0) & (A%23!=0) & (A%29!=0)] )
print(B)
The next step is to make the function more flexible, but easy ideas like this just don't work, obviously:
c = float(input("Range?"))
a = np.arange(1,c)
d = float(input("multiplier of?"))
A = np.array([d*a])
C=(A[(A%d!=0)])
The answer will be something like
def can_multiply(border_num, num) -> bool:
# 2 instead of 1 here because every num is divisible to 1
arr = [x for x in range(2, border_num)]
for number in arr:
if num % number == 0:
return False
return True
c = float(input("Range?"))
a = np.arange(1, c)
d = float(input("multiplier of?"))
A = np.array([d * a])
print(A[0])
C = [x for x in A[0] if can_multiply(int(d), x)]
print(C)
where [x for x in A[0] if ....] is a list comprehension meaning we take every element in array A[0] and add it to the new array C if can_multiply func returns True
Related
I'm a newbie in algorithms. I have recently started studying binary search and tryed to implement it on my own. The task is simple: we have an array of integers a and an integer x. If a contains x the result should be its index, otherwise the function should return -1.
Here is the code I have written:
def binary_search(a, x):
l = 0
r = len(a)
while r - l > 0:
m = (l + r) // 2
if a[m] < x:
l = m
else:
r = m
if a[l] == x:
return l
return -1
But this code stucks in infinite cycle on a = [1, 2] and x = 2. I suppose, that I have incorrect cycle condition (probably, should be r - l >= 0), but this solution does not help. Where am I wrong?
Let me do some desk checking. I'll assume a = [1, 2] and we are searching for a 2
So we start with
l = 0
r = 2
Since r - l = 2 > 0, we enter the while-loop.
m = (l + r) / 2 = (0 + 2) / 2 = 1
a[m] = a[1] = 2 == x (hence not less than x)
r = m = 1 (and l remains the same)
Now r - l = 1 - 0 = 1 > 0, so we continue
m = (l + r) / 2 = (0 + 1) / 2 = 0
a[m] = a[0] = 1 < x
l = m = 0 (and r remains the same)
After this iteration both r and l have the same value as before, which then produces an endless loop.
Ashok's answer is a great fix. But I think it'll be educational to do some desk checking on the fixed code and look what improves it.
Basically the problematic situation arises, when l + 1 = r.
Then m will always evaluate to l, a[l] < x and l is set to m again, which doesn't change the situation.
In a larger piece of code it'll make sense to make a table that contains a column for each variable to watch and a column to write down the code line that was evaluated. A column for remarks won't harm either.
As Mani mentioned you are not considering when A[m]==x. Include that case (at that point you've found a so just return m), and once you have that case we can let l=m+1 when we are still below x. Like this:
def binary_search(a, x):
l = 0
r = len(a)
while r - l > 0:
m = (l + r) // 2
if a[m] < x:
l = m + 1
elif a[m]==x:
return m
else:
r = m
if l<len(a) and a[l] == x:
return l
return -1
I want to find the number of ways, a given integer X can be decomposed into sums of numbers which are N-th powers and every summand must be unique. For example if X = 10 and N=3, I can decompose this number like that:
10 = 2^3+1^3+1^3 ,but this is not a valid decomposition, because the number 1 appears twice. A valid decomposition for X = 10 and N = 2 would be 10 = 3^2+1^2, since no summand is repeating here.
Now I tried it to use recursion and created the following Python Code
st = set(range(1,int(pow(X,1/float(N))))) # generate set of unique numbers
print(str(ps(X, N, st)))
def ps(x, n, s):
res = 0
for c in s:
chk = x-pow(c,n) # test validity
if chk > 0:
ns = s-set([c])
res += ps(chk,n,ns)
elif chk == 0:
res += 1 # one result is found
else:
res += 0 # no valid result
return res
I used a set called st and then I recursively called the function ps that includes the base case "decomposition found" and "decomposition not found". Moreover it reduces a larger number to a smaller one by considering only the ways how to decompose a given number into only two summands.
Unfortunately, I get completely wrong results, e.g.
X = 100, N = 3: Outputs 0, Expected 1
X = 100, N = 2: Outputs 122, Expected 3
X = 10, N = 2: Outputs 0, Expected 1
My thoughts are correct, but I think the Problem is anywhere in the recursion. Does anybody see what I make wrong? Any help would be greatly appreciated.
Hint:
>>> X = 100
>>> N = 3
>>> int(pow(X, 1/float(N)))
4
>>> list(range(1, 4))
[1, 2, 3]
The output is indeed correct for the input you are feeding it.
The problem is line res += 1 # one result is found in conjuction with res += ps(chk,n,ns) will make the algorithm add twice.
E.g X = 10, N = 2: Outputs 0, Expected 1 because:
c=1:
10 - 1^2 > 0 -> res += ps(chk,n,ns)
c=3:
9 - 3^2 == 0 -> res += 1 # one result is found ... return res
So, in c=3 res=1 is returned to the c=1 call, which will
res += ps(chk,n,ns), and ps(chk,n,ns) = 1, making res = 2 and doubling the result expected.
E.g. X = 29, N = 2.
29 = 2^2 + 3^2 + 4^2
Solving from bottom to top (the algorithm flow):
c=4 -> res += 1... return res
c=3 -> res += ps() -> res += 1 -> res = 2 ... return res
c=2 -> res += ps() -> res += 2 -> res = 4 ... return res
But res is supposed to be 1.
Solution: You cannot add res to res. And you must remove the previous iterated objects to avoid path repetition. Check the solution below (with prints for better understanding):
def ps(x, n, s):
print(s)
print("")
return ps_aux(x, n, s, 0) # level
def ps_aux(x, n, s, level):
sum = 0
for idx, c in enumerate(s):
print("----> " * level + "C = {}".format(c))
chk = x - pow(c,n) # test validity
if chk > 0:
ns = s[idx + 1:]
sum += ps_aux(chk,n,ns, level + 1)
elif chk == 0:
print("OK!")
sum += 1 # one result is found
else:
sum += 0 # no valid result
return sum
Try with:
X=10 # 1 solution
N=2
st = list(range(1,int(pow(X,1/float(N))) + 1 )) # generate set of unique numbers
print(str(ps(X, N, st)))
X=25 # 2 solutions [3,4], [5]
N=2
st = list(range(1,int(pow(X,1/float(N))) + 1 )) # generate set of unique numbers
print(str(ps(X, N, st)))
eg : `a = "452398" i want to take all the indices(one after - one after digits) like (4 , 2 , 9) double them == (8 , 4 , 18)
next step to check if the doubled digits is greater than 9 if so need to subtract from 9 (8 , 4 , 9) and finally i want add the digits in a ("854398") it must a string any idea how to do it ?
i tired for loop using range , len skip i sorted out everything till the last step but i couldn't apply the digits in "a" . so deleted the whole loop :(
This does what you described, but why would you want to do that:
a = "452398"
a_list = [int(x) for x in a]
numbers = [x*2 for x in a_list[::2]]
numbers = [x-9 if x>9 else x for x in numbers]
result = [j for i in zip(numbers,a_list[1::2]) for j in i]
result = map(str, result)
result = ''.join(result)
string is immutable so first you should create a list of characters using your string
a = '452398'
new = list(a)
then create a loop to do your conditions and change the value of characters in the list
for i in range(0,len(new),2):
num = int(new[i]) * 2
if num > 9:
new[i] = num - 9
else:
new[i] = num
now overwrite the value of your variable a using your new list of characters.
a = ''.join(map(str,new))
Here is the whole code.
a = '452398'
new = list(a)
for i in range(0,len(new),2):
num = int(new[i]) * 2
if num > 9:
new[i] = num - 9
else:
new[i] = num
a = ''.join(map(str,new))
print(a)
Here's how you do it using list comprehensions
A = "452398"
res = "".join([(str(min(int(a) * 2, 9)) if idx % 2 == 0 else a) for idx, a in enumerate(A)])
One of the simple answers could be.
a = '452398'
b = []
for i, x in enumerate(a):
if (i%2 == 0):
res = int(x) * 2
if len(str(res)) > 1:
res = res - 9
b.append(res)
else:
b.append(x)
b = map(str, b)
b = ''.join(b)
print(b)
I am learning Python and I am trying out some exercises. I am trying to sum all the odd numbers from 0 to 9 using list comprehension, for and if in one line.
I tried the following code:
for idx in range(10): s = 0 if idx == 0 else s = [(i % 2) for i in range(10)][idx] * range(10)[idx] + s
but I get the following error:
SyntaxError: can't assign to conditional expression
I don't quite understand it.
Your advice will be appreciated.
very short oneliner:
sum(range(1,10,2))
but the real formula is for any n:
((n+1)//2)**2
With that one, you're able compute the sum for a very big n very quickly.
Back to the point, you cannot accumulate using a list comprehension, or it's very difficult/hacky to do, so sum is required here. So the most logical if requirements are "use a comprehension notation and an if" is:
sum(x for x in range(1,10) if x % 2)
Note that there's no need to put an extra [] in that case. It's a generator comprehension (avoids generating an extra list, sum doesn't need to have all the info at once.
This is how you may do it
sum([x for x in range(1,10,2)])
Explaining why your code failed
Here is your code as given in the question
for idx in range(10):
s = 0 if idx == 0 else ([(i % 2) for i in range(10)][idx] * range(10)[idx] + s)
in the else part you may give the value to be assigned to s ie, s= is not required.You may re-write it as
for idx in range(10):
s = 0 if idx == 0 else ([(i % 2) for i in range(10)][idx] * range(10)[idx] + s)
The expression syntax for ternary operator in python is as follows
condition_is_true if condition else condition_is_false
Eg usage
value1 = 10
value2 = 20
a = 3
b = 4
value = value1 if a > b else value2
print value
#20
You can try this:
sum([x for x in range(10) if x % 2 != 0])
First you create a list of number from 0 to 9 with range, then you create the list (list comprehension) of the odd numbers (using if x % 2). Finally, you sum the contents of the array using sum.
you can one line it this reduce
reduce(lambda x,y: x+y if y%2 != 0 else x ,range(10))
output
25
you can do this ..
a = range(0,10)
b = sum([x for x in a if x%2 != 0])
print b
output :
25
numbers = range(0, 10)
def addOddNumbers(numbers):
for num in numbers:
if num % 2 == 1:
return sum
print sum(numbers)
if __name__ == '__main__':
addOddNumbers(numbers)
I must write a recursive function that gets a number(n) in the 10 base and converts it to a given number base(k) and return a list which its components are the final number digits,for example f(5, 3) must result [1, 2] which 5 in base 3 is 12, or f(22, 3) must result [2, 1, 1].
Here's the code I tried:
def cb(n, k):
b = []
if n == 0:
b.append(0)
if n < k:
b.append(n)
if n == k:
b.append(10)
else:
a = n // k
b.append(n - ((n // k) * k))
if a < k:
b.append(a)
else:
cb(a, k)
return b
print(cb(22, 3))
Actually I thought a lot on it but since I'm not so good at writing codes I couldn't go any further. I appreciate your help and modifications to my code .
If you think in terms of recursion the base case is when n < k for which the answer is n and to get the last digit of the n you do n%k so the recusive case is cb(n//k,k)+[n%k].
The code will look like this :
def cb(n, k):
if n < k:
return [n]
else:
return cb(n//k, k) + [n%k]
print(cb(22, 3))
you were very close, the only thing that you needed to do was change:
else:
cb(a, k)
to:
else:
b.extend(cb(a, k))
however, your output is going to be:
>>> cb(22, 3)
[1, 1, 2]
which is the reverse of what you want, since 22 in base 3 is 211. you can fix this by either reversing the list [1,1,2][::-1] == [2,1,1] or replace all your calls to append and your new call to extend to instead add at the beginning of the list like: b.insert(0,element) or b = cb(a,k) + b
The biggest problem is that you aren't doing anything with the results of the recursive call, so they never go in your list. I think you are also complicating this too much. Something like this should work:
def cb(n,k):
if n > 0:
q = n // k
r = n - q * k
b = cb(q, k)
b.append(r)
else:
b = [0]
if b[0] == 0 and len(b) > 1:
b = b[1:]
return b
I think if you don't do the last part, then you always get a 0 on the front? You could also simplify it further by just testing to see if it is less than the radix, which gives an even simpler solution
def cb(n,k):
if n < k:
return [n]
else:
q = n // k
r = n - q * k
b = cb(q, k)
b.append(r)
return b