A friend recently asked me to code an algorithm that takes n 'people' and produces an n-1 by n/2 grid, where every possible pair occurs once and in each n/2 section nobody is allowed to occur twice. (i.e. person1 matched with person 2 and person1 matched with person3 is invalid).
If that doesn't make sense imagine this: for 100 people create 99 rounds of meetings where everyone meets someone new in each round but nobody has more than one meeting in a round. This way 50 unique meetings occur each round, for 99 rounds, totalling 4950 unique meetings.
I have coded this in python using recursive backtracking (not sure if this is the best method. This problem reminds me of sudoku and this is a popular method of solving sudoku) This takes a stupid amount of time even for smallish numbers (50 for example). Is there a faster method of coding this or are there augmentations I can add to make it run faster?
Code is here: https://pastebin.com/iyr2wdkz
import random
from itertools import combinations
import time as t
import sys
sys.setrecursionlimit(15000)
def isPrime(num):
"""Checks num for primality. Returns bool."""
if num == 2:
return True
elif num < 2 or not num % 2: # even numbers > 2 not prime
return False
# factor can be no larger than the square root of num
for i in range(3, int(num ** .5 + 1), 2):
if not num % i: return False
return True
def generatePrimes(n):
"""Returns a list of prime numbers with length n"""
primes = [2,]
noOfPrimes = 1 # cache length of primes for speed
testNum = 3 # number to test for primality
while noOfPrimes < n:
if isPrime(testNum):
primes.append(testNum)
noOfPrimes += 1
testNum += 2
return primes
class Person:
def __init__(self, name, ID):
self.name = name
self.primeID = ID
def __eq__(self, other):
return self.primeID == other
def __repr__(self):
return '%d' % (self.name)
class Schedule:
def __init__(self, numberofpeople):
self.x = 0 #current x pos
self.y = 0 #current y pos
self.fill = 0 #number of slots filled
self.board = [] #get initialized to an n-1 x n/2 grid to hold links
self.failed = [] #same as board but holds a list of failed links in each cell
self.uniqueLinks = [] #list of unique links, a link is the product of two primes
self.availableLinks = [] #links not yet placed in the grid
self.personList = [] #list of Person. A person is a name and a unique prime number
self.primeList = generatePrimes(numberofpeople) #list of the first n prime numbers
random.shuffle(self.primeList)
#initializes the empty lists
for i in range(numberofpeople):
self.personList.append(Person(i, self.primeList[i]))
self.uniqueLinks = list(map(lambda x: x[0] * x[1], combinations(self.primeList, 2)))
for i in self.uniqueLinks:
self.availableLinks.append(i)
tmp = len(self.uniqueLinks)
for i in range(tmp // (numberofpeople // 2)):
self.board.append(list())
self.failed.append(list())
for i in range(len(self.board)):
for j in range(numberofpeople//2):
self.board[i].append(None)
self.failed[i].append(list())
#checks if the candidate is valid in current position
def isValid(self, candidate):
factor1, factor2 = self.getFactor(candidate)
for i in self.board[self.x]:
if not i:
return True
if ((i % factor1) == 0) or ((i % factor2) == 0):
return False
return True
#moves to the next non-None value, return True if successful
def nextpos(self):
for i in range(len(self.board)):
for j in range(len(self.board[0])):
if not self.board[i][j]:
self.x = i
self.y = j
return True
return False
#sets the last non-None value to None and adds that value to availableLinks and the failed tracker
def prevpos(self):
for i in range(len(self.board)-1, -1, -1):
for j in range(len(self.board[0])-1, -1, -1):
if self.board[i][j]:
self.x = i
self.y = j
tmp = self.board[self.x][self.y]
self.availableLinks.append(tmp)
self.board[i][j] = None
self.failed[i][j].append(tmp)
self.fill -= 1
random.shuffle(self.availableLinks)
return True
#returns the prime factors of num
def getFactor(self, num):
for i in self.primeList:
if num % i == 0:
return i, num/i
#recursive backtracking solving algorithm
def solve(self):
print('%d links placed, %d remaining, pos is %d, %d' % (self.fill, len(self.availableLinks), self.x, self.y))
if not self.nextpos():
return True
for i in self.availableLinks:
if self.isValid(i): and self.checkFail(i):
self.fill += 1
self.board[self.x][self.y] = i
self.availableLinks.remove(i)
if self.solve():
return True
else:
self.prevpos()
return False
#replaces prime products with formatted names of people in the board
def decompose(self):
for i in range(len(self.board)):
for j in range(len(self.board[0])):
num1, num2 = self.getFactor(self.board[i][j])
for k in self.personList:
if k == num1:
person1 = str(k)
if k == num2:
person2 = str(k)
self.board[i][j] = person1 + '<-->' + person2
# checks if num has already been tried at current pos, returns false if is has.
def checkFail(self, num):
if num in self.failed[self.x][self.y]:
return False
else:
return True
# verifies that the board has no duplicate values
def verify(self):
visited = []
for i in self.board:
for j in i:
if j in visited:
print('Verification failed %s occurs twice'% j)
return False
visited.append(j)
print('Successfully verified')
return True
s =Schedule(50)
s.solve()
s.verify()
s.decompose()
print(s.board)
What an impressive amount of code!
Here is a solution in scala. I just use Ints, which you may map to Person.ID:
def greetAsMad (persons: List [Int]) : List [(Int, Int)] =
if (persons.size < 2) Nil else
persons.tail.map (p=> (persons.head, p)) ::: greetAsMad (persons.tail)
For 100 persons, it returns immediately (< 200ms).
To be prepared for a larger amount of persons, I would transform it into a tail-recursive function.
The idea is, that person 1 greets everybody and leaves the room. Then person 2 greets everybody and leaves too. In the end person 99 greets person 100 and both leave the room.
Then they start eating and drinking.
Here is a non recursive approach:
for (i <- 1 to 99;
j <- i + 1 to 100) yield (i, j)
Seems you need round-robin tournament algorithm.
In short: make two-rows table, fix the first entry of the first row, and shift all other entries in cyclic manner (n-1 times). At every round pairs are formed by top and bottom entries in the same columns
0 1
2 3
----- pairs 0-2, 1-3
0 2
3 1
---- pairs 0-3, 2-1
0 3
1 2
----- pairs 0-1, 3-2
Related
I know how to check if the number can be represented as the sum of two squares with a brute-force approach.
def sumSquare( n) :
i = 1
while i * i <= n :
j = 1
while(j * j <= n) :
if (i * i + j * j == n) :
print(i, "^2 + ", j , "^2" )
return True
j = j + 1
i = i + 1
return False
But how to do it for n distinct positive integers. So the question would be:
Function which checks if the number can be written as sum of 'n' different squares
I have some examples.
For e.g.
is_sum_of_squares(18, 2) would be false because 18 can be written as the sum of two squares (3^2 + 3^2) but they are not distinct.
(38,3) would be true because 5^2+3^2+2^2 = 38 and 5!=3!=2.
I can't extend the if condition for more values. I think it could be done with recursion, but I have problems with it.
I found this function very useful since it finds the number of squares the number can be split into.
def findMinSquares(n):
T = [0] * (n + 1)
for i in range(n + 1):
T[i] = i
j = 1
while j * j <= i:
T[i] = min(T[i], 1 + T[i - j * j])
j += 1
return T[n]
But again I can't do it with recursion. Sadly I can't wrap my head around it. We started learning it a few weeks ago (I am in high school) and it is so different from the iterative approach.
Recursive approach:
def is_sum_of_squares(x, n, used=None):
x_sqrt = int(x**0.5)
if n == 1:
if x_sqrt**2 == x:
return used.union([x_sqrt])
return None
used = used or set()
for i in set(range(max(used, default=0)+1, int((x/n)**0.5))):
squares = is_sum_of_squares(x-i**2, n-1, used.union([i]))
if squares:
return squares
return None
Quite a compelling exercise. I have attempted solving it using recursion in a form of backtracking. Start with an empty list, run a for loop to add numbers to it from 1 to max feasible (square root of target number) and for each added number continue with recursion. Once the list reaches the required size n, validate the result. If the result is incorrect, backtrack by removing the last number.
Not sure if it is 100% correct though. In terms of speed, I tried it on the (1000,13) input and the process finished reasonably fast (3-4s).
def is_sum_of_squares(num, count):
max_num = int(num ** 0.5)
return backtrack([], num, max_num, count)
def backtrack(candidates, target, max_num, count):
"""
candidates = list of ints of max length <count>
target = sum of squares of <count> nonidentical numbers
max_num = square root of target, rounded
count = desired size of candidates list
"""
result_num = sum([x * x for x in candidates]) # calculate sum of squares
if result_num > target: # if sum exceeded target number stop recursion
return False
if len(candidates) == count: # if candidates reach desired length, check if result is valid and return result
result = result_num == target
if result: # print for result sense check, can be removed
print("Found: ", candidates)
return result
for i in range(1, max_num + 1): # cycle from 1 to max feasible number
if candidates and i <= candidates[-1]:
# for non empty list, skip numbers smaller than the last number.
# allow only ascending order to eliminate duplicates
continue
candidates.append(i) # add number to list
if backtrack(candidates, target, max_num, count): # next recursion
return True
candidates.pop() # if combination was not valid then backtrack and remove the last number
return False
assert(is_sum_of_squares(38, 3))
assert(is_sum_of_squares(30, 3))
assert(is_sum_of_squares(30, 4))
assert(is_sum_of_squares(36, 1))
assert not(is_sum_of_squares(35, 1))
assert not(is_sum_of_squares(18, 2))
assert not(is_sum_of_squares(1000, 13))
I'm a new at programming, I like solving this euler questions and I know there are solutions for this problem but it's not about the problem at all actually.
So, i managed to create a working function for finding example: 33. triangular number. It works but i couldn't manage to properly desing my while loop. I wanted to make it like, it starts from first triangular checks it's divisors make list of it's divisors, checks the length of the divisors, because problem wants "What is the value of the first triangle number to have over five hundred divisors?" . But i never managed to work the while loop. Thank you for reading.
nums = [1]
triangles = [1]
divisors = []
def triangularcreator(x):
if x == 1:
return 1
n = 1
sum = 0
while n!=0:
n += 1
nums.append(n)
for i in range(len(nums)):
sum += nums[i]
triangles.append(sum)
sum = 0
if x == len(triangles):
n = 0
return triangles[-1]
counter = 1
while True:
for i in range(1, triangularcreator(counter) + 1):
if triangularcreator(counter) % i == 0:
divisors.append(i)
if len(divisors) == 500:
print(triangularcreator(counter))
break
counter +=1
divisors.clear()
You should try to change a few things, starting with calculating just once the value of triangularcreator(counter) and assigning this value to a variable that you can use in different points of your code.
Second, you create a loop which will be calculate always triangularcreator(1). At the end of each iteration you increase the value of counter+=1, but then at the beginign of the new iteration you assignt it again value 1, so it will not progress as you expect. Try this few things:
counter = 1
while True:
triangle = triangularcreator(counter)
for i in range(1, triangle + 1):
if triangle % i == 0:
divisors.append(i)
if len(divisors) == 500:
print(triangle )
break
counter +=1
Also these two arrays nums = [1], triangles = [1] should be declared and initialized inside the def triangularcreator. Otherwise you would be appending elements in each iteration
Edit: I believe it is better to give you my own answer to the problem, since you are doing some expensive operations which will make code to run for a long time. Try this solution:
import numpy as np
factor_num = 0
n = 0
def factors(n):
cnt = 0
# You dont need to iterate through all the numbers from 1 to n
# Just to the sqrt, and multiply by two.
for i in range(1,int(np.sqrt(n)+1)):
if n % i == 0:
cnt += 1
# If n is perfect square, it will exist a middle number
if (np.sqrt(n)).is_integer():
return (cnt*2)-1
else:
return (cnt*2)-1
while factor_num < 500:
# Here you generate the triangle, by summing all elements from 1 to n
triangle = sum(list(range(n)))
# Here you calculate the number of factors of the triangle
factor_num = factors(triangle)
n += 1
print(triangle)
Turns out that both of your while loop are infinite either in triangularcreatorin the other while loop:
nums = [1]
triangles = [1]
divisors = []
def triangularcreator(x):
if x == 1:
return 1
n = 1
sum = 0
while n:
n += 1
nums.append(n)
for i in range(len(nums)):
sum += nums[i]
triangles.append(sum)
sum = 0
if len(triangles) >= x:
return triangles[-1]
return triangles[-1]
counter = 1
while True:
check = triangularcreator(counter)
for i in range(1, check + 1):
if check % i == 0:
divisors.append(i)
if len(divisors) >= 500:
tr = triangularcreator(counter)
print(tr)
break
counter +=1
Solution
Disclaimer: This is not my solution but is #TamoghnaChowdhury, as it seems the most clean one in the web. I wanted to solve it my self but really run out of time today!
import math
def count_factors(num):
# One and itself are included now
count = 2
for i in range(2, int(math.sqrt(num)) + 1):
if num % i == 0:
count += 2
return count
def triangle_number(num):
return (num * (num + 1) // 2)
def divisors_of_triangle_number(num):
if num % 2 == 0:
return count_factors(num // 2) * count_factors(num + 1)
else:
return count_factors((num + 1) // 2) * count_factors(num)
def factors_greater_than_triangular_number(n):
x = n
while divisors_of_triangle_number(x) <= n:
x += 1
return triangle_number(x)
print('The answer is', factors_greater_than_triangular_number(500))
I am working on leetcode "762. Prime Number of Set Bits in Binary Representation" and I tested my code works fine on Jupiter Notebook and when I migrate into leetcode it shows null as a ending result. Could someone give me any hint on what the problems are?
class Solution:
def countPrimeSetBits(self, L, R):
"""
:type L: int
:type R: int
:rtype: int
"""
def isPrime(num):
if num == 0:
return False
list1 = list(range(num))
list1.remove(0)
if len(list1) != 0:
list1.remove(num-1)
for i in list1:
if num % (i+1) == 0:
return False
else:
return True
count = 0
for i in range(L, R+1):
newlist = list(bin(i)[2::])
newcount = 0
for j in newlist:
if j == '1':
newcount += 1
if isPrime(newcount) is True:
count += 1
return count
The expect result is 23 for the first test case which is L=842 and R=888
Jupiter Note book gives me back 23 as expected but Leetcode returns null as a result
You have two serious problems. The first is that the code as presented is indented incorrectly, such that the body of code for countPrimeSetBits() is instead part of the internal function isPrime(). The second problem is that, besides being the worst implementation ever, your isPrime() doesn't really work:
>>> isPrime(169)
True
>>> 13 * 13
169
>>>
due to this else clause placing the return at the wrong point in the code:
else:
return True
Below is your patched code which hopefully will work in both environments:
class Solution:
def countPrimeSetBits(self, L, R):
"""
:type L: int
:type R: int
:rtype: int
"""
def isPrime(number):
if number == 0:
return False
divisors = list(range(number))
divisors.remove(0)
if divisors:
divisors.remove(number - 1)
for divisor in divisors:
if number % (divisor + 1) == 0:
return False
return True
count = 0
for i in range(L, R + 1):
newlist = list(bin(i)[2::])
newcount = 0
for j in newlist:
if j == '1':
newcount += 1
if isPrime(newcount):
count += 1
return count
I am trying trying to find the number of circular primes from a given limit. The prime(x) will return whether a number is a prime or not. The rotations() will return a list of rotated numbers. Lastly, prime_count() will output the total amount of circular primes based on the given limit. Both prime() and rotations() gave me the correct output; however, prime_count() is not incrementing like it should. Any ideas on what i did wrong?
def prime(number): #return true or false
return all(number% i for i in range(2,number))
def rotations(num): #rotating number and return list
list = []
m = str(num)
counter = 0
while counter < len(str(num)):
m=m[1:] + m[0]
list.append(int(m))
counter+=1
list1=sorted(list,key=int)
return list1
def prime_count(limit): #return numbers of circular primes from given limit
counter = 0
for i in range(1,limit+1):
a=rotations(i)
for j in a:
if j == prime(j):
counter+=1
return counter
print(prime_count(100))
There are a few problems with your code:
Your prime function has a bug:
In [8]: prime(1)
Out[8]: True
It erroneously returns True for any number less than 2 due to range(2, n) being empty and any([]) == True.
prime_count should be counting the total number of circular primes below limit. prime(j) returns a boolean, but you check j == prime(j), which can only be true if j is zero or one, which definitely isn't what you want. Try creating an is_circular_prime function that takes in an integer n and returns whether or not the prime is circular. Then, prime_count becomes easy to write.
This is the heart of the problem:
a=rotations(i)
for j in a:
if j == prime(j):
counter+=1
You're counting the wrong thing (e.g. 13 counts twice independent of 31 counting twice) and you're comparing the wrong thing (numbers against booleans.) The problem is simpler than you're making it. Rearranging your code:
def prime(number):
return number > 1 and all(number % i != 0 for i in range(2, number))
def rotations(num):
rotated = []
m = str(num)
for _ in m:
rotated.append(int(m))
m = m[1:] + m[0]
return rotated
def prime_count(limit):
counter = 0
for number in range(1, limit + 1):
if all(prime(rotation) for rotation in rotations(number)):
counter += 1
return counter
print(prime_count(100))
Note that you don't need to sort the rotations for this purpose. Also list, or any other Python built-in function, is a bad name for a variable.
Problem may be here:
for i in range(1,limit+1):
a=rotations(i)
for j in a:
if j == prime(j): # Prime will return True or False, comapring with J will cause it False ,except when J = 1
counter+=1
Changing it to prime(j)
for i in range(2,number//2):
if(number%i==0):
return False
return True
def rotations(num):
count=0
rotation_lst=[]
num=str(num)
while(count<len(num)):
num=num[1:]+num[0]
count+=1
rotation_lst.append(int(num))
rotation_lst1=sorted(rotation_lst,key=int)
return rotation_lst1
def get_circular_prime_count(limit):
count=0
for i in range(1,limit+1):
a=rotations(i)
for j in a:
if(check_prime(j)):
count+=1
return count
print(get_circular_prime_count(1000) ```
We've been asked to make a program that takes in polynomial coefficients(i.e. [1, 2, 1] representing x^2 + 2x + 1 and use the rational root theorem to find and print the roots in a list of fractional strings. We were only allowed to use import math. The problem with my code is it only works if I input [1, 2, 1] and when I input other polynomials, it prints a blank list.
import math
roots = []
pr = []
pf = []
qf = []
count = 1
t = 0
co = raw_input('Input Coefficients: ')
co = co.split(' ')
p = co[0]
q = co[-1]
def gcd(a,b): #function for computing gcf between two numbers. will be used to simplify fractions into lowest terms
r = a%b
if r == 0:
return b
else:
return gcd(b,r)
def rmvvalues(coefficients, val): #remove the zeroes from the list because zero is not factorable
for i in range(coefficients.count(val)):
coefficients.remove(val)
while int(p) == 0: #if the constant was 0, it means 0 is automatically a root
roots.append(0)
rmvvalues(co, str('0'))
p = co[0]
q = co[-1]
while count <= math.fabs(int(p)): #factors of the constant
if int(p) % count == 0:
pf.append(count)
pf.append(count*(-1))
count = count + 1
else:
count = count + 1
count = 1
while count <= math.fabs(int(q)): #factors of the last term
if int(q) % count == 0:
qf.append(count)
qf.append(count*(-1))
count = count + 1
else:
count = count + 1
count = 1
for i in range(len(pf)): #every element in the first list of factors is to be divided by every element of the other list of factors
for j in range(len(qf)):
result = 0
for c in range(len(co)): #and each pf/qf is to be checked if it would make the polynomial zero
result = int(result) * (int(pf[i])/int(qf[j])) + int(co[c])
if result == 0: #if it makes it zero, it appends the answer in fraction string to the list of roots
if (int(pf[i]) / int(qf[j])) == 1: #add 1 to the list of roots if p/q == 1 and would make the equation zero
roots.append(1)
elif int(pf[i])/int(qf[j]) == -1: #add -1 to the list of roots if p/q == -1 and would make the equation zero
roots.append(-1)
else: #if they would be fractions
a = int(pf[i]) / int(gcd(int(pf[i]),int(qf[j])))
b = int(qf[j]) / int(gcd(int(pf[i]),int(qf[j])))
roots.append(str(a) + '/' +str(b))
roots = sorted(set(roots))
print roots
p.s.(I just copy/pasted the code from my editor so the indentation may be a little off)
I have an implementation to propose, but not a debugging of yours.
The fact is that you are writing a big one bloc code that I don't understand.
As I want to help you I give you an example of implementation that I hope you will find helpful AND readable. My big suggest when coding is to split the code in little function easy to understand with meaningful name, and then add an algorithm function that call all the sub-functions. This make the algorithm to looks like pseudocode and be mode understandable.
Additionally, more specifically related to python, your code is supposed to follow some rule. Runtime code is supposed to be placed after if __name__ == "__main__": bloc.
Hope it helps you (take a look at the findSolution method):
class Polynom():
""" A class representing a polynom that provides methods to find roots of the polynom. """
#-----------------------------------------------------------------------------------------
def __init__(self, coefficients):
"""
Constructor of the class.
Takes a coeficient list [n, n-1, ..., n1, n0] that are the coefficients of a polynom.
Example :
Polynom([1,2,3]) stand for : x² + 2x + 3
"""
self.coefficients = coefficients
#-----------------------------------------------------------------------------------------
def _dividers(self, coefficient):
"""Returns the list of the divider of a number by filtering the values in [1, 2, ... , |coefficient| ] that divide coefficient. """
def filter_dividers(coefficient, candidate_values):
# lambda function explanations : http://www.diveintopython.net/power_of_introspection/lambda_functions.html
return filter(lambda number : coefficient%number == 0, candidate_values)
return list(filter_dividers(coefficient, range(1, abs(coefficient)+1)))
#-----------------------------------------------------------------------------------------
def _gcd(self, x, y):
""" Returns the greatest common diviser of the integers x and y """
if y == 0:
return abs(x)
else:
r = x%y
return self._gcd(y, r)
#-----------------------------------------------------------------------------------------
def _positiveAndNegativeCombinations(self, p_values, q_values):
"""
Returns the list of positives and negatives combination of (p,q) pairs.
Example :
[1,2]
-> [(1,4), (-1,4), (2,4), (-2,4), (1,5), (-1,5), (2,5), (-2,5)]
[4,5]
"""
def combinations(p, q_values):
if len(q_values) == 1:
return [(p, q_values[0])]
else:
return [(p, q_values[0])] + combinations(p, q_values[1:])
result = []
for p in p_values:
p_combinations = combinations(p, q_values)
for combination in p_combinations:
result += [combination, (-1*combination[0], combination[1])]
return result
#-----------------------------------------------------------------------------------------
def __repr__(self):
""" Representation of the object in a string for printing purpose."""
def from_number_to_string_exposant(number):
"""
Returns a string that is the number given as exposant.
Example : 1 -> "¹"
"""
utf8_exposant = {"0":"⁰", "1":"¹", "2":"²", "3": "³", "4":"⁴", "5":"⁵", "6":"⁶", "7":"⁷", "8":"⁸", "9":"⁹"}
string = str(number)
result = ""
for digit in string:
result += utf8_exposant[digit]
return result
result = ""
degree = 0
coefficients = self.coefficients
while coefficients != [] :
coef, coefficients = coefficients[-1], coefficients[0:-1]
result = "+ " +str(coef)+"x"+ from_number_to_string_exposant(degree) + result
degree+=1
return "<Polynom :" + result[1:] + " = 0 >"
#-----------------------------------------------------------------------------------------
def valueFor(self, value):
""" Returns ture or false depending on the fact that the given value is or not a polunom's solution. """
total_value = 0
degree = 0
coefficients = self.coefficients
while coefficients != [] :
coef, coefficients = coefficients[-1], coefficients[0:-1]
total_value += coef*(value**degree)
degree += 1
return total_value
#-----------------------------------------------------------------------------------------
def isSolution(self, value):
""" Returns true or false depending if the given value is a polynom solution or not """
return (self.valueFor(value) == 0)
#-----------------------------------------------------------------------------------------
def findSolution(self):
"""
Return a pair (p,q) that verify that p/q is a solution of this polynom. If no valid pair is find, return None.
Call to this function come with log printing.
"""
print("Search solution for ", self)
a0 = self.coefficients[-1]
aN = self.coefficients[0]
if a0 == 0 or aN == 0:
return None #algorithm is not applicable in this case.
else:
p_values = self._dividers(a0)
q_values = self._dividers(aN)
print("finded dividers of p :", p_values)
print("finded dividers of q :", q_values)
candidate_solutions = self._positiveAndNegativeCombinations(p_values,q_values)
print("(p,q) pairs to evaluate are : \n\t",candidate_solutions)
for candidate in candidate_solutions :
candidate_value = 1.0 * candidate[0] / candidate[1]
print("pair : ",candidate, " | value : ", candidate_value)
if self.isSolution(candidate_value):
print()
return candidate
else:
print("The pair ", candidate, "is invalid, replacing x by it leads to say that 0=", self.valueFor(candidate_value))
return None
#-----------------------------------------------------------------------------------------
if __name__ == "__main__":
poly = Polynom([2,1,-6])
print(poly.findSolution())
Execute it with python3 (or change the print calls).
Arthur.
https://code.activestate.com/recipes/577974-polynomial-factoring-using-rational-root-theorem/
Here's a working link.
from math import ceil
listOfFactors = lambda n: {i for i in range(1,ceil(abs(n)/2)+1) if n%i == 0}
def removeDuplicates(mylist):
if mylist:
mylist.sort()
last = mylist[-1]
for i in range(len(mylist)-2, -1, -1):
if last == mylist[i]:
del mylist[i]
else:
last = mylist[i]
return mylist
def polyRoots(polyListCoeff):
allFactors = set()
allFactorsListOld = list(allFactors.union(listOfFactors(polyListCoeff[0]),{polyListCoeff[0]},listOfFactors(polyListCoeff[-1]),{polyListCoeff[-1]}))
allFactorsListOld.extend([-1*i for i in allFactorsListOld])
allFactorsList = list()
for k in allFactorsListOld:
for j in allFactorsListOld:
allFactorsList.append(k/j)
allFactorsList = removeDuplicates(allFactorsList)
polyListCoeff.reverse()
roots = [i for i in allFactorsList if sum([pow(i,j)*polyListCoeff[j] for j in range(0,len(polyListCoeff))]) == 0]
factorList = list()
for i in roots:
if i<0:
factorList.append("(x+{})".format(-i))
else:
factorList.append("(x-{})".format(i))
return "".join(factorList)
if __name__ == "__main__":
polyRoots([1,0,-4])
# '(x+2.0)(x-2.0)'