How can I find whether this equation works? - python

So I programmed this code to find whether all numbers in a list are multiples of a number k: or not, but it doesn't seem to work. can anyone give some examples for me to draw ideas from?

Use %7 instead of //7. // will give you whole number quotient and % will give you remainder. Let use say some number 49, 49//7 is 7 and 49%7 is 0. Another example 26, 26//7 is 3 and 26%7 is 5

There two issues with your code.
First you need to use % to get the rest of the division x / k.
Second as you're doing it, you exit the function as soon as you have found a number
in your list that is a multiple of k: you don't check remaining items in your list.
Here is a modified version of your code:
k = 4
a: list= [3, 4, 4, 3]
def allMultiplesofK(k, a):
for x in list(a):
if x % k != 0:
return False
return True # all items of a are multiples of k
print(allMultiplesofK(k, a))

In your code the return inside the loop will quit the loop as soon as the condition will be satisfied, so, it will will not check all numbers in the list. You can use for example list comprehension and the all function from the standard library, see docs,
def allMultiplesofK(k, a):
return all(map(lambda p: p % k == 0, a))
return all([p % k == 0 for p in a]) # with list comprehension
k = 4
a: list= [3, 4, 4, 8]
print(allMultiplesofK(k, a))
# False
a: list= [12, 4, 4, 8]
print(allMultiplesofK(k, a))
# True

You aren't actually checking every item of the loop.
for x in list(a):
if x // k == 0:
return True
if x // k != 0:
return False
This is returning from the function after only checking the first item in the list.
Also the way you are checking if one number is divisible by another isn't quite right. You should be using the modulo operator "%". This operator gives you the remainder after the division.
3 % 4 = 3 # since 4 goes into 3, 0 times with 3 remaining.
Therefore your program should become:
k = 4
a: list= [3, 4, 4, 3]
def allMultiplesofK(k, a):
for x in list(a):
if x % k != 0:
return False
return True
print(allMultiplesofK(k, a))

Use modulo instead of floor division.
Floor division:
This will gives you the quotient
Modulus:
This will give you the remainder.
k = 4
a = [3, 4, 4, 3]
def allMultiplesofK(k, a):
for x in list(a):
if x % k == 0:
return True
else:
return False
print(allMultiplesofK(k, a))
output: False
But this will not give all numbers result i.e it will print last values 3%4 False.
result = [True if i % k == 0 else False for i in a]
print(result)
Output: [False, True, True, False]

Related

Python program to make a list even odd parity

Task: count the number of operations required to make an array's values alternate between even and odd.
Given: items = [6, 5, 9, 7, 3] (Example test case)
Operations we can do: make n number of operations: floor(item/2)
My code
def change(expected):
return 1 if (expected == 0) else 0
def getMinimumOperations(items, expected):
countOp = 0
for i in items:
if (int(i % 2 == 0) != expected):
countOp += 1
expected = change(expected)
return countOp
def minChangeToGetMinOp(items):
minStack = [getMinimumOperations(items, 1), getMinimumOperations(items, 0)]
return min(minStack)
if __name__ == "__main__":
items = [6, 5, 9, 7, 3]
print(minChangeToGetMinOp(items))
ANS: 3
What I'm asking: A good approach to solve this
Taking the comment that the division by 2 can be repeated multiple times on the same input number -- until its parity is as expected (or the number becomes 0 and the odd parity is required), the program would need an inner loop:
def getMinimumOperations(items, expected):
countOp = 0
for i in items:
while i % 2 != expected:
if not i:
return float("inf") # Not possible
i //= 2
countOp += 1
expected = 1 - expected
return countOp
def minChangeToGetMinOp(items):
return min(getMinimumOperations(items, 1), getMinimumOperations(items, 0))
if __name__ == "__main__":
items = [6, 5, 9, 7, 3]
print(minChangeToGetMinOp(items)) # 3
This seems like more of a math/logic problem than a Python problem.
To make a list's elements alternate between odd and even, either all the elements at even indices should be even and the rest odd, or all the elements at even indices should be odd and the rest even.
It appears you're not looking to change the order of elements, but to add or subtract one to make them comply.
So, to make the list comply, either you need to change all even elements at odd indices and all odd elements at even indices, or vice versa.
The answer therefore:
def needed_changes(xs):
c = sum((i + n) % 2 for i, n in enumerate(xs))
return min(c, len(xs) - c)
if __name__ == '__main__':
xs = [6, 5, 9, 7, 3]
print(needed_changes(xs))
Output:
2
The solution adds each element to its index, and then takes the mod 2 of it, so that each element becomes either 1 if the index or the value is odd, or 0 if both are odd, or both are even. As a result, the sum of those 1's will be the number of elements that need to be changed - but if that number is more than half, you could just change the rest of the elements instead, which is what the last lines decides.
Edit: From your comment it became clear that operations allowed are limited and the only operation allowed is x = floor(x / 2). This complicates the issue because this operation only results in an even outcome for every other two numbers. The pattern looks like this:
0 0 # 'even' to start with
1 0 # 'even' after 1 operation
2 1 # even to start with
3 1 # still odd after 1 op, after another 'even' (0)
4 2 # even to start with
5 2 # even after 1 op
6 3 # even to start with
7 3 # still odd after 2 ops, needs 3
8 4 # even to start with
..
So, each 4th number will be both odd, and its floor(x/2) will also be odd. If you apply the operation again, only half of those results will be even, etc.
Another way to look at the problem then: if a number's binary representation ends in a 0, it is even. If you take the floor(x/2) of a number, you're really just performing a "shift right" operation. So, if an number's binary representation has a 0 as the second least significant bit, performing the operation will make it even. And so on.
So, a solution using only that operation:
def needed_changes(xs):
ns = []
for x in xs:
n = 0
while x % 2:
n, x = n + 1, x >> 1
ns.append(n)
return min(sum(ns[0::2]), sum(ns[1::2]))
Or, if you don't like building a whole new list and want the solution to save space:
def needed_changes(xs):
ns = [0, 0]
for i, x in enumerate(xs):
n = 0
while x % 2:
n, x = n + 1, x >> 1
ns[i % 2] += n
return min(ns)

Recursive function to move all multiples of an integer to the end of a list

I was asked to write a recursive function to move all multiples of an integer (k) to the end of the list. This function move_multi(num_list, k) takes a list of integers (num_list) and an integer (k) as parameters and returns None.
Sample run of the code:
nums = [1, 2, 3, 4, 5, 6, 7, 8]
k = 3
move_multi(nums, k)
print(nums)
Expected output:
[1, 2, 4, 5, 7, 8, 3, 6]
Rules:
A helper function may be used.
No loop allowed.
The non-multiples and multiples have to be in the original relative order.
move_multi(num_list, k) must return None and only has 2 parameters.
I have a problem identifying the base case and thus completely clueless to even start working on the question.
My attempt:
def move_multi(num_list, k):
if len(num_list) == 0: # base case
return None
if num_list[0] % k == 0: # if [0] is a multiple of k
num_list.append(num_list.pop(0))
move_multi(num_list[1:], k)
else: # if [0] is not a multiple of k
move_multi(num_list[1:], k)
return None
But after calling the function, the list is still the same as before.
If the order of the elements within each of the two categories must stay the same, then you can use this algorithm:
Have an index go from left to right through the list. Whenever a value is a multiple of k, then pop it out the list and append it to the end. At the same time increase a counter named done that keeps track of how many multiples have been moved like that to the end of the list.
When the index reaches the start of the last section of the list (having done number of values), then the base case is reached.
As you are allowed to create a helper function, you can provide such helper function with the two indexes as arguments; the recursion happens in the nested, helper function:
def move_multi(nums, k):
def recur(i, done):
if i + done >= len(nums):
return
if nums[i] % k == 0:
nums.append(nums.pop(i))
recur(i, done+1)
else:
recur(i+1, done)
recur(0, 0)
nums = [1, 2, 3, 4, 5, 6, 7, 8]
k = 3
move_multi(nums, k)
print(nums)
Output:
[1, 2, 4, 5, 7, 8, 3, 6]
Your attempt
The attempt that you added to your question fails because it uses slicing when passing a list to the recursive call:
num_list[1:]
But then you have no way to get the result back: any mutation through append and pop will now happen on a copy of num_list of which you have no reference once the function returns. You should pass the list itself, and not a sliced copy of it, and pass an additional index.
Minimising the number of moves
To minimise the number of movements in the list, I would have preferred the algorithm below, which however does not maintain the original order of the values within each of the two categories, but it has a better time complexity in the worst case:
Have two indexes in the list move from both ends to the list towards each other. Only move an index if the value it referenced was at the correct side of the list (based on whether it divides by k). If neither of these two indexes can move, swap their values, and then move both of them. When the two indexes cross (= base case) the goal is achieved.
In a recursive fashion this can be as follows:
def move_multi(nums, k, i=0, j=-1): # Two extra arguments with default values
if i - j >= len(nums): # NB: j is always negative
return # all values have been inspected
if nums[j] % k == 0:
move_multi(nums, k, i, j-1)
elif nums[i] % k > 0:
move_multi(nums, k, i+1, j)
else:
nums[i], nums[j] = nums[j], nums[i] # swap
move_multi(nums, k, i+1, j-1)
nums = [1, 2, 3, 4, 5, 6, 7, 8]
k = 3
move_multi(nums, k)
print(nums)
Output:
[1, 2, 8, 4, 5, 7, 6, 3]
You can use next method:
def move_multi(nums, k, idx=0):
if idx >= len(nums):
return nums
if nums[idx] % k:
return [nums.pop(idx)] + move_multi(nums, k, idx)
else:
return move_multi(nums, k, idx + 1)
This returns new list which doesn't fully meet your requirements but I've decided to leave it like it is. It's possible to patch it to rewrite source list by using this function as inner function and nums[:] = move_multi_inner(nums, k).
... which will look like this:
def move_multi(nums, k):
def move_multi_inner(nums, k, idx=0):
if idx >= len(nums):
return nums
if nums[idx] % k:
return [nums.pop(idx)] + move_multi_inner(nums, k, idx)
else:
return move_multi_inner(nums, k, idx + 1)
nums[:] = move_multi_inner(nums, k)
nums = [1, 2, 3, 4, 5, 6, 7, 8]
move_multi(nums, 3)
To be frank with you, I find this exercise a kind of abuse of recursion. You could slice the the array into the first element and the remaining n-1 elements. You then apply recursively the function to the remaining n-1 elements. you have now n-1 elements with the multiples at the end. The first element can either be appended at the start or appended at the end if it's a multiple.
You could split the list into two, recursively call the function on both sublists then merge the two lists by first taking the non multiple elements from both lists and appending them to a new list, then take the multiple elements from both sublists and appending them at the end of the resultant list. Pointless and inefficient, but meets the requirements.
The following is another approach that switches elements:
def move_multi(l, n, idx=0):
if idx == len(l)-1:
if l[idx] % n == 0:
return idx - 1
else:
return idx;
else:
last_non_div = move_multi(l, n, idx+1)
if l[idx] % n == 0:
l[idx], l[last_non_div] = l[last_non_div], l[idx]
return last_non_div - 1
else:
return last_non_div
n = 2
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
move_multi(l, n)
print(l)
n = 3
move_multi(l, n)
print(l)
l = [2] * 10
move_multi(l, n)
print(l)
l = [1] * 10
move_multi(l, n)
print(l)
n = 2
l = [2, 3, 1, 2, 5, 2, 4]
move_multi(l, n)
print(l)
This one's also working fine, except it is non-recursive.
def multiplier(l1, r):
l2 = []
for i in range(0, r):
if l1[i] % 10 == 0:
l2.append(l1[i])
for j in l2:
if j in l1:
l1.remove(j)
l1.append(j)
return l1

Checking for alternating parity

I am struggling to find a way to check if every other number in my list is of an alternating parity (i.e. even, odd, even, odd, etc.)
[1,2,3,4] # odd, even, odd, even (True, because they alternate)
[1,3,2,4] # odd, odd, even, even (False, because they don't alternate)
Anyone have any idea how I can check for this?
You can use the Python modulus operator % on adjacent values within an input list and check for equality while iterating.
If you choose this route and efficiency is a concern, I advise you use 3rd party libraries such as NumPy / numba so the iteration does not take place at Python level:
from numba import jit
#jit(nopython=True)
def check_alt_parity(L):
for i in range(len(L)-1):
if L[i] % 2 == L[i+1] % 2:
return False
return True
def check_alt_parity_list(L):
for i in range(len(L)-1):
if L[i] % 2 == L[i+1] % 2:
return False
return True
A = [1, 2, 3, 4] * 10000
B = [1, 3, 2, 4] * 10000
%timeit check_alt_parity(A) # 780 µs
%timeit check_alt_parity_list(A) # 9.09 ms
Here
def alter(ls):
for i in range(len(ls)-1):
if ls[i]%2 == ls[i+1]%2:
return False
return True
You can iterate over all indices of your sequence and then compare it with the next one:
def is_alternating_parity(seq):
for i in range(len(seq) - 1):
if seq[i] % 2 == seq[i + 1] % 2:
return False
return True
print(is_alternating_parity([1, 2, 3, 4])) # True
print(is_alternating_parity([1, 3, 2, 4])) # False
Try this function, l for list comprehension and getting bool for odd or even, then checking if all are true (the every second even index element is all True or all False, and same with every odd index element:
def oddeven_alter(l):
l=[i%2 for i in l]
return all([any([all(l[::2]),all(not i for i in l[::2])]),any([all(l[1::2]),all(not i for i in l[1::2])])])
)
print(oddeven_alter([1,2,3,4]))
print(oddeven_alter([1,3,2,4]))
Output:
True
False
Kind of complex looking tho

How to return a list of numbers of the power of 2?

def problem(n):
myList = []
for j in range(0, n):
number = 2 ** j
myList.append(number)
return myList
I want this code to return the powers of 2 based upon the first n powers of 2. So for example, if I enter in 4, I want it to return [2,4,6,8,16]. Right now, the code returns [1,2,4,8] if I enter in 4. I think it's my range that's messing up the code.
just use range(1,n+1) and it should all work out. range is a little confusing for some because it does not include the endpoint. So, range(3) returns the list [0,1,2] and range(1,3) returns [1,2].
As a side note, simple loops of the form:
out = []
for x in ...:
out.append(...)
should typically be replaced by list comprehensions:
out = [ 2**j for j in range(1,n+1) ]
Yet another simple and efficient solution (every step in O(1)) without the power operator:
def problem(n):
return [1 << i for i in range(n)]
The 1 << i operations is a bitwise operation which translates to 2 ^ i for i integer positive.
https://en.wikipedia.org/wiki/Arithmetic_shift
If you want to do every step in O(1):
def gen(x):
i = 2
for n in range(x + 1):
yield i
i <<= 1
>>> list(gen(4))
[2, 4, 8, 16, 32]
PS: There's a typo in the question and if you want 4 numbers for gen(4), use range(x) instead
As #JBernardo pointed out, I assume there is a typo in your question.
def squares(n):
power = n
square_list = []
for i in range(1,n+1):
square_list.append(2 ** i)
return square_list
print squares(4)
will return
[2,4,8,16]
import math
n = input()
a = [i for i in xrange(2, n+1) if (math.log(i)/math.log(2)).is_integer()]
print a
>>> [2, 4, 8, 16 ...]
Returns list of powers of 2 less than or equal to n
Explanation:
A number can only be a power of 2 if its log divided by the log of 2 is an integer.
eg. log(32) = log(2^5) = 5 * log(2)
5 * log(2) when divided by log(2) gives 5 which is an integer.
Also there will be floor(math.log(n, 2)) elements in the list, as that is the formula for the number of powers of 2 below n if n itself is not a power of 2
You can use map:
x = [1, 2, 3, 4]
def power(n):
return n * n
list(map(power, x))
#output
[1, 4, 9, 16]

List and Integer query

If i had a list of numbers and some maybe negative, how would i ensure all numbers in my list were positive? I can covert the items in the list to integers thats no problem.
Another question, I want to compare items in my list to an integer value say 'x' and sum all the values in my list that are less than x.
Thank you.
If you have a list Ns of numbers (if it's a list of strings as in several similar questions asked recently each will have to be made into an int, or whatever other kind of number, by calling int [[or float, etc]] on it), the list of their absolute values (if that's what you mean by "ensure") is
[abs(n) for n in Ns]
If you mean, instead, to check whether all numbers are >= 0, then
all(n >= 0 for n in Ns)
will give you a bool value respecting exactly that specification.
The sum of the items of the list that are <x is
sum(n for n in Ns if n < x)
Of course you may combine all these kinds of operations in one sweep (e.g. if you need to take the abs(n) as well as checking if it's < x, checking if it's >= 0, summing, whatever).
# input list is named "lst"
pos_list = [int(a) for a in lst if int(a) > 0]
# And num 2 (notice generator is used instead of list)
return sum(a for a in lst if a < x)
Answer / First part:
>>> a = [1, 2, -3, 4, 5, 6]
>>> b = [1, 2, 3, 4, 5, 6]
>>> max(map(lambda x: x < 0, a))
False
>>> max(map(lambda x: x < 0, b))
True
Or just use min:
>>> min(a) < 0
True
>>> min(b) < 0
False
Second part:
>>> x = 3
>>> sum(filter(lambda n: n < x, a))
>>> 0
>>> sum(filter(lambda n: n < x, b))
>>> 3
If I understand correctly your question, I guess you are asking because of some class about functional programming.
In this case, what you are asking for can be accomplished with functional programming tools available in Python.
In particular, the first point can be solved using filter, while the second with map and reduce (or, better, with map and sum).
>>>mylist = [1,2,3,-2]
>>>any(item for item in mylist if item < 0)
True
>>>mylist.pop()
-2
>>>any(item for item in mylist if item < 0)
False
answers your first question.
>>> x = 3
>>> sum(item for item in mylist if item < x)
3
answers your second question.

Categories

Resources