I have polynomial coefficients. How to get a list of coefficients e.g. by multiplying 10 polynomials?
For example for two polynomials.
(x + 2)*(x + 2) = x^2 + 4x + 4
[1,2] * [1,2] = [1, 4, 4]
I am trying to solve a codewars task which gives me a list of roots and I have to return a polynomial.
My first idea was function from numpy, poly but there is too much difference with large numbers. Thank u!
Source: https://www.codewars.com/kata/5b2d5be2dddf0be5b00000c4
My code:
import re
from numpy import poly
from math import fabs
def polynomialize(roots):
result = ''
data = list(filter(lambda x : x[0] != 0, zip(poly(roots).tolist(), range(len(roots), -1, -1))))
for coe, power in data:
if coe > 0:
result += f'+ {int(coe)}x^{power} '
else:
result += f'- {int(fabs(coe))}x^{power} '
result = re.sub(r'(x\^1)(?![0-9]+)', 'x', result).replace('x^0', '')
result = re.sub(r'(?<![0-9])(1x)','x', result)
return result[2:] + '= 0'
This is likely related to the integer type that numpy uses in its arrays, while the inputs and the resulting coefficients may involve greater numbers than these integers can hold (wrapping around).
You could do this to get data:
coeff = [1]
for r in roots:
coeff = [t[1] - r * t[0] for t in zip(coeff + [0], [0] + coeff)]
data = list(filter(lambda x : x[1] != 0,
reversed(list(enumerate(coeff)))))
for power, coe in data: # notice the pairs are in reverse compared to your loop
Also fabs is limited to integer. I would change int(fabs(coe)) to -int(coe).
I submitted this solution and it was accepted:
import re
def polynomialize(roots):
coeff = [1]
for r in roots:
coeff = [t[1] - r * t[0] for t in zip(coeff + [0], [0] + coeff)]
data = list(filter(lambda x : x[1] != 0,
reversed(list(enumerate(coeff)))))
result = ''
for power, coe in data:
if coe > 0:
result += f'+ {int(coe)}x^{power} '
else:
result += f'- {-int(coe)}x^{power} '
result = re.sub(r'(x\^1)(?![0-9]+)', 'x', result).replace('x^0', '')
result = re.sub(r'(?<![0-9])(1x)','x', result)
return result[2:] + '= 0'
Is it what you want?
from sympy import symbols, Poly
x = symbols("x")
pol1 = Poly(x + 2)
pol = pol1 ** 2
pol.all_coeffs()
# [1, 4, 4]
I wrote the following code for a HackerRank problem involving repeated FOR loops with very similar syntax:
x, y = map(int, input().split())
inp = []
for _ in range(x):
inp.append(list(map(int, input().split())))
#I get the rest of the input as a nested list.
while len(inp) < 7:
inp.append([1, 0])
#Adding dummy values in the list
list = []
for a in inp[0][1:inp[0][0]+1]:
for b in inp[1][1:inp[1][0]+1]:
for c in inp[2][1:inp[2][0] + 1]:
for d in inp[3][1:inp[3][0] + 1]:
for e in inp[4][1:inp[4][0] + 1]:
for f in inp[5][1:inp[5][0] + 1]:
for g in inp[6][1:inp[6][0] + 1]:
list.append((a ** 2 + b ** 2 + c ** 2 + d ** 2 + e ** 2 + f ** 2 + g ** 2) % y)
#Given function
print(max(list))
I wonder if there's any way to do this in one go.
PS: I'm an absolute beginner in programming.
Use itertools.product can simplify the loops a little bits:
import itertools as it
K, M = map(int, input().strip().split())
# reading the K lines and appending lists to 'L'
L = []
for i in range(K):
lst = list(map(int, input().strip().split()))
L.append(lst[1:])
# Looping through Cartesian product
MAX = -1
for i in it.product(*L):
MAX = max(sum(map(lambda x: x**2, i))% M, MAX)
print(MAX)
This question was asked in a challenge in HackerEarth:
Mark is solving an interesting question. He needs to find out number
of distinct ways such that
(i + 2*j+ k) % (x + y + 2*z) = 0, where 1 <= i,j,k,x,y,z <= N
Help him find it.
Constraints:
1<= T<= 10
1<=N<= 1000
Input Format:
First line contains T, the number of test cases. Each of the test case
contains a single integer,N in a separate line.
Output Format:
For each test case , output in a separate line, the number of distinct
ways.
Sample Input
2
1
2
Sample Output
1
15
Explanation
In the first case, the only possible way is i = j = k = x =y = z = 1
I am not getting any way how to solve this problem, I have tried one and I know it's not even close to the question.
import random
def CountWays (N):
# Write your code here
i = random.uniform(1,N)
j = random.uniform(1,N)
k = random.uniform(1,N)
x = random.uniform(1,N)
y = random.uniform(1,N)
z = random.uniform(1,N)
d = 0
for i in range(N):
if (i+2*j+k)%(x+y+2*z)==0:
d += 1
return d
T = int(input())
for _ in range(T):
N = int(input())
out_ = CountWays(N)
print (out_)
My Output
0
0
Instead it should give the output
1
15
The value of the numerator (num) can range from 4 to 4N. The value of the denominator (dom) can range from 4 to num. You can split your problem into two smaller problems: 1) How many values of the denominator is a given value of the numerator divisible by? 2) How many ways can a given denominator and numerator be constructed?
To answer 1) we can simply loop through all the possible values of the numerator, then loop over all the values of the denominator where numerator % denominator == 0. To answer 2) we can find all the partitions of the numerator and denominator that satisfies the equality and constraints. The number of ways to construct a given numerator and denominator will be the product of the number of partitions of each.
import itertools
def divisible_numbers(n):
"""
Get all numbers with which n is divisible.
"""
for i in range(1,n+1):
if n % i == 0:
yield i
if i >= n:
break
def get_partitions(n):
"""
Generate ALL ways n can be partitioned into 3 integers.
Modified from http://code.activestate.com/recipes/218332-generator-for-integer-partitions/#c9
"""
a = [1]*n
y = -1
v = n
while v > 0:
v -= 1
x = a[v] + 1
while y >= 2 * x:
a[v] = x
y -= x
v += 1
w = v + 1
while x <= y:
a[v] = x
a[w] = y
if w == 2:
yield a[:w + 1]
x += 1
y -= 1
a[v] = x + y
y = a[v] - 1
if w == 3:
yield a[:w]
def get_number_of_valid_partitions(num, N):
"""
Get number of valid partitions of num, given that
num = i + j + 2k, and that 1<=i,j,k<=N
"""
n = 0
for partition in get_partitions(num):
# This can be done a bit more cleverly, but makes
# the code extremely complicated to read, so
# instead we just brute force the 6 combinations,
# ignoring non-unique permutations using a set
for i,j,k in set(itertools.permutations(partition)):
if i <= N and j <= N and k <= 2*N and k % 2 == 0:
n += 1
return n
def get_number_of_combinations(N):
"""
Get number of ways the equality can be solved under the given constraints
"""
out = 0
# Create a dictionary of number of valid partitions
# for all numerator values we can encounter
n_valid_partitions = {i: get_number_of_valid_partitions(i, N) for i in range(1,4*N+1)}
for numerator in range(4,4*N+1):
numerator_permutations = n_valid_partitions[numerator]
for denominator in divisible_numbers(numerator):
denominator_permutations = n_valid_partitions[denominator]
if denominator < 4:
continue
out += numerator_permutations * denominator_permutations
return out
N = 2
out = get_number_of_combinations(N)
print(out)
The scaling of the code right now is very poor due to the way the get_partitions and the get_number_of_valid_partitions functions interact.
EDIT
The following code is much faster. There's a small improvement to divisible_numbers, but the main speedup lies in get_number_of_valid_partitions not creating a needless amount of temporary lists as it has now been joined with get_partitions in a single function. Other big speedups comes from using numba. The code of get_number_of_valid_partitions is all but unreadable now, so I've added a much simpler but slightly slower version named get_number_of_valid_partitions_simple so you can understand what is going on in the complicated function.
import numba
#numba.njit
def divisible_numbers(n):
"""
Get all numbers with which n is divisible.
Modified fromĀ·
"""
# We can save some time by only looking at
# values up to n/2
for i in range(4,n//2+1):
if n % i == 0:
yield i
yield n
def get_number_of_combinations(N):
"""
Get number of ways the equality can be solved under the given constraints
"""
out = 0
# Create a dictionary of number of valid partitions
# for all numerator values we can encounter
n_valid_partitions = {i: get_number_of_valid_partitions(i, N) for i in range(4,4*N+1)}
for numerator in range(4,4*N+1):
numerator_permutations = n_valid_partitions[numerator]
for denominator in divisible_numbers(numerator):
if denominator < 4:
continue
denominator_permutations = n_valid_partitions[denominator]
out += numerator_permutations * denominator_permutations
return out
#numba.njit
def get_number_of_valid_partitions(num, N):
"""
Get number of valid partitions of num, given that
num = i + j + 2l, and that 1<=i,j,l<=N.
"""
count = 0
# In the following, k = 2*l
#There's different cases for i,j,k that we can treat separately
# to give some speedup due to symmetry.
#i,j can be even or odd. k <= N or N < k <= 2N.
# Some combinations only possible if num is even/odd
# num is even
if num % 2 == 0:
# i,j odd, k <= 2N
k_min = max(2, num - 2 * (N - (N + 1) % 2))
k_max = min(2 * N, num - 2)
for k in range(k_min, k_max + 1, 2):
# only look at i<=j
i_min = max(1, num - k - N + (N + 1) % 2)
i_max = min(N, (num - k)//2)
for i in range(i_min, i_max + 1, 2):
j = num - i - k
# if i == j, only one permutations
# otherwise two due to symmetry
if i == j:
count += 1
else:
count += 2
# i,j even, k <= N
# only look at k<=i<=j
k_min = max(2, num - 2 * (N - N % 2))
k_max = min(N, num // 3)
for k in range(k_min, k_max + 1, 2):
i_min = max(k, num - k - N + N % 2)
i_max = min(N, (num - k) // 2)
for i in range(i_min, i_max + 1, 2):
j = num - i - k
if i == j == k:
# if i == j == k, only one permutation
count += 1
elif i == j or i == k or j == k:
# if only two of i,j,k are the same there are 3 permutations
count += 3
else:
# if all differ, there are six permutations
count += 6
# i,j even, N < k <= 2N
k_min = max(N + 1 + (N + 1) % 2, num - 2 * N)
k_max = min(2 * N, num - 4)
for k in range(k_min, k_max + 1, 2):
# only look for i<=j
i_min = max(2, num - k - N + 1 - (N + 1) % 2)
i_max = min(N, (num - k) // 2)
for i in range(i_min, i_max + 1, 2):
j = num - i - k
if i == j:
# if i == j, only one permutation
count += 1
else:
# if all differ, there are two permutations
count += 2
# num is odd
else:
# one of i,j is even, the other is odd. k <= N
# We assume that j is odd, k<=i and correct the symmetry in the counts
k_min = max(2, num - 2 * N + 1)
k_max = min(N, (num - 1) // 2)
for k in range(k_min, k_max + 1, 2):
i_min = max(k, num - k - N + 1 - N % 2)
i_max = min(N, num - k - 1)
for i in range(i_min, i_max + 1, 2):
j = num - i - k
if i == k:
# if i == j, two permutations
count += 2
else:
# if i and k differ, there are four permutations
count += 4
# one of i,j is even, the other is odd. N < k <= 2N
# We assume that j is odd and correct the symmetry in the counts
k_min = max(N + 1 + (N + 1) % 2, num - 2 * N + 1)
k_max = min(2 * N, num - 3)
for k in range(k_min, k_max + 1, 2):
i_min = max(2, num - k - N + (N + 1) % 2)
i_max = min(N, num - k - 1)
for i in range(i_min, i_max + 1, 2):
j = num - i - k
count += 2
return count
#numba.njit
def get_number_of_valid_partitions_simple(num, N):
"""
Simpler but slower version of 'get_number_of_valid_partitions'
"""
count = 0
for k in range(2, 2 * N + 1, 2):
for i in range(1, N + 1):
j = num - i - k
if 1 <= j <= N:
count += 1
return count
if __name__ == "__main__":
N = int(sys.argv[1])
out = get_number_of_combinations(N)
print(out)
The current issue with your code is that you've picked random numbers once, then calculate the same equation N times.
I assume you wanted to generate 1..N for each individual variable, which would require 6 nested loops from 1..N, for each variable
Now, that's the brute force solution, which probably fails on large N values, so as I commented, there's some trick to find the multiples of the right side of the modulo, then check if the left side portion is contained in that list. That would only require two triple nested lists, I think
(i + 2*j+ k) % (x + y + 2*z) = 0, where 1 <= i,j,k,x,y,z <= N
(2*j + i + k) is a multiple of (2*z + x + y)
N = 2
min(2*j + i + k) = 4
max(2*j + i + k) = 8
ways to make 4: 1 * 1 = 1
ways to make 5: 2 * 2 = 4
ways to make 6: 2 * 2 = 4
ways to make 7: 2 * 2 = 4
ways to make 8: 1 * 1 = 1
Total = 14
But 8 is a multiple of 4 so we add one more instance for a total of 15.
I have this list that I want to sort based on bubble sort, and there is a function in code (Swap()) is refusing to work. I don't know why. there is the code
score = [92,95,7,5,85,55,789,47,125,3265,88,965,655,3,15,448,0,255,455]
size = len(score)
x = 0
COMPS = size - 1
def swap():
temp = score[x + 1]
score[x + 1] = score[x]
score[x] = temp
# The Sort Array Function
def SortArray():
y = 0
while y < COMPS:
x = 0
while x < COMPS:
if score[x] > score[x + 1]:
#This function not working.
swap()
x += 1
y += 1
#Display Array Function
def displayArray():
x = 0
while x < size:
print(score[x])
x += 1
SortArray()
displayArray()
but inserting the swap() code, thus the code under the swap() and replacing it underneath the SortArray(), below the if condition; just like this:
def SortArray():
y = 0
while y < COMPS:
x = 0
while x < COMPS:
if score[x] > score[x + 1]:
#This Works
temp = score[x + 1]
score[x + 1] = score[x]
score[x] = temp
x += 1
y += 1
then it works, so I want to know why the swap() function doesn't get called under the SortArray()
I want to know why the swap() function doesn't get called under the SortArray()
Actually, it IS called - which you can check by yourself adding a couple print() calls within or using the step debugger - but it doesn't do what you think it should do, because you're confusing local and global variables.
In SortArray() you define a local variable named x (it's defined as local because you assign it in the function), and this is obviously the one you expect swap() to use. But in your swap function, you use a variable x which is neither an argument of the function nor assigned within the function (both of which would make it a local variable), so it's resolved as the global x declared above.
IOW, swap uses the global x why you'd expect it to use the one which is local to SortArray(). This is also why the second version works, since this time it uses the proper variable.
The solution is to remove the global x and explicitely pass the correct value to swap(), ie:
def swap(x):
temp = score[x + 1]
score[x + 1] = score[x]
score[x] = temp
def SortArray():
y = 0
while y < COMPS:
x = 0
while x < COMPS:
if score[x] > score[x + 1]:
swap(x)
x += 1
y += 1
And while you're at it, you should also to the same with score - actually, you should avoid globals as much as possible (and believe me, you can write a lot of code without using globals):
def swap(score, x):
temp = score[x + 1]
score[x + 1] = score[x]
score[x] = temp
def SortArray(score):
comps = len(score) - 1
y = 0
while y < comps:
x = 0
while x < comps:
if score[x] > score[x + 1]:
swap(score, x)
x += 1
y += 1
def displayArray(score):
x = 0
while x < len(score):
print(score[x])
x += 1
if __name__ == "__main__":
score = [92,95,7,5,85,55,789,47,125,3265,88,965,655,3,15,448,0,255,455]
SortArray(score)
displayArray(score)
And now your functions can be used with any list or sequence. They are still totally unpythonic but that's obviously not the point here (python has one of the most optimized sort algorithm builtin anyway).
I am having problem with the simpsons rule. It is saying float object cannot be interpreted as an integer in for i in range(1, (n/2) + 1):
def simpson(f, a, b, n):
h=(b-a)/n
k=0.0
x= a + h
for i in range(1, (n/2) + 1):
k += 4*f(x)
x += 2*h
x = a + 2*h
for i in range(1, n/2):
k +=2*f(x)
x += 2*h
return (h/3)*(f(a)+f(b)+k)
result=simpson(lambda x:x, 0, 1, 4)
print (result)
n / 2 returns a float in Python 3, while range only works with integers. You need to use integer division (//):
range(1, (n // 2) + 1).