Algorithm to solve for partitions of an Integer - algorithm

Problem: x1+x2....xn=C where x1,x2....xn >= 0 and is a integer. Find an algorithm that finds every point (x1,x2...xn) that solves this.
Why: I am trying to iterate a multivariable polynomial's terms. The powers of each term can be described by the points above. (You do this operation for C = 0 to C = degree of the polynomial)
I am stuck trying to make an efficient algorithm that produced only the unique solutions (non duplicates) and wanted to see if there is any existing algorithm

After some thought on this problem (and alot of paper), here is my algorithm:
It finds every combination of array of length N that sum to k and the elements are greater then or equal to 0.
This does not do trial and error to get the solution however it does involve quite alot of loops. Greater optimization can be made by creating a generating function when k and n are known beforehand.
If anyone has a better algorithm or finds a problem with this one, please post below, but for now this solves my problem.
Thank you #kcsquared and #Kermit the Frog for leading me in the right direction
""" Function that iterates a n length vector such that the combination sum is always equal to k and all elements are the natural numbers
.Returns if it was stopped or not
Invokes lambda function on every iteration
iteration_lambda (index_vector::Vector{T}, total_iteration::T)::Bool
Return true when it should end
"""
function partition(k::T, n::T, iteration_lambda::Function; max_vector = nothing, sum_vector = nothing, index_vector = nothing)::Bool where T
if n > 0
max_vector = max_vector == nothing ? zeros(T, n) : max_vector
sum_vector = sum_vector == nothing ? zeros(T, n) : sum_vector
index_vector = index_vector == nothing ? zeros(T, n) : index_vector
current_index_index::T = 1
total_iteration::T = 1
max_vector[1] = k
index_vector[1] = max(0, -(k * (n - 1)))
#label reset
if index_vector[current_index_index] <= max_vector[current_index_index]
if current_index_index != n
current_index_index += 1
sum_vector[current_index_index] = sum_vector[current_index_index - 1] + index_vector[current_index_index - 1]
index_vector[current_index_index] = max(0, -(k * (n - current_index_index - 1) + sum_vector[current_index_index]))
max_vector[current_index_index] = k - sum_vector[current_index_index]
else
if iteration_lambda(index_vector, total_iteration)
return true
end
total_iteration += 1
index_vector[end] += 1
end
#goto reset
end
if current_index_index != 1
current_index_index -= 1
index_vector[current_index_index] += 1
#goto reset
end
end
return false
end

Related

Python Codility Frog River One time complexity

So this is another approach to probably well-known codility platform, task about frog crossing the river. And sorry if this question is asked in bad manner, this is my first post here.
The goal is to find the earliest time when the frog can jump to the other side of the river.
For example, given X = 5 and array A such that:
A[0] = 1
A[1] = 3
A[2] = 1
A[3] = 4
A[4] = 2
A[5] = 3
A[6] = 5
A[7] = 4
the function should return 6.
Example test: (5, [1, 3, 1, 4, 2, 3, 5, 4])
Full task content:
https://app.codility.com/programmers/lessons/4-counting_elements/frog_river_one/
So that was my first obvious approach:
def solution(X, A):
lista = list(range(1, X + 1))
if X < 1 or len(A) < 1:
return -1
found = -1
for element in lista:
if element in A:
if A.index(element) > found:
found = A.index(element)
else: return -1
return found
X = 5
A = [1,2,4,5,3]
solution(X,A)
This solution is 100% correct and gets 0% in performance tests.
So I thought less lines + list comprehension will get better score:
def solution(X, A):
if X < 1 or len(A) < 1:
return -1
try:
found = max([ A.index(element) for element in range(1, X + 1) ])
except ValueError:
return -1
return found
X = 5
A = [1,2,4,5,3]
solution(X,A)
This one also works and has 0% performance but it's faster anyway.
I also found solution by deanalvero (https://github.com/deanalvero/codility/blob/master/python/lesson02/FrogRiverOne.py):
def solution(X, A):
# write your code in Python 2.6
frog, leaves = 0, [False] * (X)
for minute, leaf in enumerate(A):
if leaf <= X:
leaves[leaf - 1] = True
while leaves[frog]:
frog += 1
if frog == X: return minute
return -1
This solution gets 100% in correctness and performance tests.
My question arises probably because I don't quite understand this time complexity thing. Please tell me how the last solution is better from my second solution? It has a while loop inside for loop! It should be slow but it's not.
Here is a solution in which you would get 100% in both correctness and performance.
def solution(X, A):
i = 0
dict_temp = {}
while i < len(A):
dict_temp[A[i]] = i
if len(dict_temp) == X:
return i
i += 1
return -1
The answer already been told, but I'll add an optional solution that i think might help you understand:
def save_frog(x, arr):
# creating the steps the frog should make
steps = set([i for i in range(1, x + 1)])
# creating the steps the frog already did
froggy_steps = set()
for index, leaf in enumerate(arr):
froggy_steps.add(leaf)
if froggy_steps == steps:
return index
return -1
I think I got the best performance using set()
take a look at the performance test runtime seconds and compare them with yours
def solution(X, A):
positions = set()
seconds = 0
for i in range(0, len(A)):
if A[i] not in positions and A[i] <= X:
positions.add(A[i])
seconds = i
if len(positions) == X:
return seconds
return -1
The amount of nested loops doesn't directly tell you anything about the time complexity. Let n be the length of the input array. The inside of the while-loop needs in average O(1) time, although its worst case time complexity is O(n). The fast solution uses a boolean array leaves where at every index it has the value true if there is a leaf and false otherwise. The inside of the while-loop during the entire algotihm is excetuded no more than n times. The outer for-loop is also executed only n times. This means the time complexity of the algorithm is O(n).
The key is that both of your initial solutions are quadratic. They involve O(n) inner scans for each of the parent elements (resulting in O(n**2)).
The fast solution initially appears to suffer the same fate as it's obvious it contains a loop within a loop. But the inner while loop does not get fully scanned for each 'leaf'. Take a look at where 'frog' gets initialized and you'll note that the while loop effectively picks up where it left off for each leaf.
Here is my 100% solution that considers the sum of numeric progression.
def solution(X, A):
covered = [False] * (X+1)
n = len(A)
Sx = ((1+X)*X)/2 # sum of the numeric progression
for i in range(n):
if(not covered[A[i]]):
Sx -= A[i]
covered[A[i]] = True
if (Sx==0):
return i
return -1
Optimized solution from #sphoenix, no need to compare two sets, it's not really good.
def solution(X, A):
found = set()
for pos, i in enumerate(A, 0):
if i <= X:
found.add(i)
if len(found) == X:
return pos
return -1
And one more optimized solution for binary array
def solution(X, A):
steps, leaves = X, [False] * X
for minute, leaf in enumerate(A, 0):
if not leaves[leaf - 1]:
leaves[leaf - 1] = True
steps -= 1
if 0 == steps:
return minute
return -1
The last one is better, less resources. set consumes more resources compared to binary list (memory and CPU).
def solution(X, A):
# if there are not enough items in the list
if X > len(A):
return -1
# else check all items
else:
d = {}
for i, leaf in enumerate(A):
d[leaf] = i
if len(d) == X:
return i
# if all else fails
return -1
I tried to use as much simple instruction as possible.
def solution(X, A):
if (X > len(A)): # check for no answer simple
return -1
elif(X == 1): # check for single element
return 0
else:
std_set = {i for i in range(1,X+1)} # list of standard order
this_set = set(A) # set of unique element in list
if(sum(std_set) > sum(this_set)): # check for no answer complex
return -1
else:
for i in range(0, len(A) - 1):
if std_set:
if(A[i] in std_set):
std_set.remove(A[i]) # remove each element in standard set
if not std_set: # if all removed, return last filled position
return(i)
I guess this code might not fulfill runtime but it the simplest I could think of
I am using OrderedDict from collections and sum of first n numbers to check the frog will be able to cross or not.
def solution(X, A):
from collections import OrderedDict as od
if sum(set(A))!=(X*(X+1))//2:
return -1
k=list(od.fromkeys(A).keys())[-1]
for x,y in enumerate(A):
if y==k:
return x
This code gives 100% for correctness and performance, runs in O(N)
def solution(x, a):
# write your code in Python 3.6
# initialize all positions to zero
# i.e. if x = 2; x + 1 = 3
# x_positions = [0,1,2]
x_positions = [0] * (x + 1)
min_time = -1
for k in range(len(a)):
# since we are looking for min time, ensure that you only
# count the positions that matter
if a[k] <= x and x_positions[a[k]] == 0:
x_positions[a[k]] += 1
min_time = k
# ensure that all positions are available for the frog to jump
if sum(x_positions) == x:
return min_time
return -1
100% performance using sets
def solution(X, A):
positions = set()
for i in range(len(A)):
if A[i] not in positions:
positions.add(A[i])
if len(positions) == X:
return i
return -1

Minimum number of squares required to cover a rectangular grid of size n by m

The problem statement is to find Minimum number of squares required whose side is of power of 2 required to cover a rectangular grid of size n by m.
I wrote the following code :
ll solve(ll n,ll m)
{
if(n==0||m==0)
return 0;
else if(n%2==0&&m%2==0)
return solve(n/2,m/2);
else if(n%2==0&&m%2==1)
return (solve(n/ 2,m/ 2));
else if(n%2==1&&m%2==0)
return (solve(n/ 2,m/ 2));
else
return (n+m-1+solve(n/2,m/2));
}
Suggest me, as it gives wrong answer.
W.l.o.g. we say n>=m and choose m to be of the form 2^x. (If m is arbitrary <= n as well it only means that we apply the same approach to a second rectangle that is n times m-2^x in size, where x=int_floor(ld(m)) and ld is log to the base of 2 of course.)
The following snippet should compute the number of squares needed.
countSquares(m,n,x) :
if n == 0 : return 0
if n == 1 : return m
if n/2^x >= 1 :
return m/2^x + countSquares(m,n-2^x,x-1)
else
countSquares(m,n,x-1)
The return in the 3rd if: m/2^x is always a natural number as m is of the form 2^x in the beginning and any 2^(x-(x-i)) remains a natural number.
If we are only interested in a lower bound. I would assume choosing a rectangle of size a times b, where a:=2^x - 1, and b:=2^y -1 should result in roughly ld(a) times ld(b) number of squares.
Extending the code snippet to an arbitrary m seems to involve a second recursion:
partitionAndCount(n,m) :
if n < m : swap(n,m)
var x = floor(ld(m))
var mRes = m - 2^x
if mRes == 0 : return countSquares(2^x,n,x-1)
if mRes == 1 : n + return countSquares(2^x,n,x-1)
return partitionAndCount(n,mRes) + countSquares(2^x,n,x-1)

Finding all the Combination to sum set of coins to a certain number

I have given an array and I have to find the targeted sum.
For Example:
A[] ={1,2,3};
S = 5;
Total Combination = {1,1,1,1,1} , {2,3} ,{3,2} . {1,1,3} , {1,3,1} , {3,1,1} and other possible pair
I know it sounds like coin change problem, But the problem is how to find the Combination i.e {2,3} and {3,2} are 2 different solutions.
In the original coin change problem, you "choose" an arbitrary coin - and "guess" if it is or is not in the solution, this is done because the order is not important.
Here, you will have to iterate all possibilities for "which coin is first", until you are done:
D(0) = 1
D(x) = 0 | x < 0
D(x) = sum { D(x-coins[0]) , D(x-coins[1]), ..., D(x-coins[n-1] }
Note that for each step, you are giving all possibilities for the choosing the next coin, and moving on. At the end, you sum up all the solutions, for all possibilities to place each coin at the head of the solution.
Complexity of this solution using DP is O(n*S), where n is the number of coins and S is the desired sum.
Matlab code (wrote it in imperative style, this is my current open IDE, sorry it's matlab and not more common language like java or C)
function [ n ] = make_change( coins, x )
D = zeros(x,1);
for k = 1:x
for t = 1:length(coins)
curr = k-coins(t);
if curr>0
D(k) = D(k) + D(curr);
elseif curr == 0
D(k) = D(k) + 1;
end
end
end
n = D(x);
end
Invoking will yield:
>> make_change([1,2,3],5)
ans =
13
Which is correct, since all possibilities are [1,1,1,1,1],[1,1,1,2]*4, [1,1,3]*3,[1,2,2]*3,[2,3]*2 = 13

How do I find the lowest common multiple of two numbers?

I know this is a classic interview question, but here is my quick attempt at creating a function which returns the lowest common multiple of two numbers, something I never have to do in my day job:
def calc_common_multiplyer(int_low, int_high)
i = 1
int_high_res = []
while true
int_high_res << int_high * i
if int_high_res.include?(int_low * i)
return int_low * i
end
i = i+1
end
end
I feel that this is very clunky. Is there a more efficient or standard solution?
I'd do this in Ruby:
x.lcm(y)
:)
First calculate the greatest common divisor (for example with the Euclidean algorithm), then
lcm(a,b) = if a == 0 && b == 0 then return 0 else return (a*b)/gcd(a,b)
def find_lcm(n,m)
n, m = m, n if m < n
count = m
until count % n == 0
count += m
end
count
end

Can I reduce the computational complexity of this?

Well, I have this bit of code that is slowing down the program hugely because it is linear complexity but called a lot of times making the program quadratic complexity. If possible I would like to reduce its computational complexity but otherwise I'll just optimize it where I can. So far I have reduced down to:
def table(n):
a = 1
while 2*a <= n:
if (-a*a)%n == 1: return a
a += 1
Anyone see anything I've missed? Thanks!
EDIT: I forgot to mention: n is always a prime number.
EDIT 2: Here is my new improved program (thank's for all the contributions!):
def table(n):
if n == 2: return 1
if n%4 != 1: return
a1 = n-1
for a in range(1, n//2+1):
if (a*a)%n == a1: return a
EDIT 3: And testing it out in its real context it is much faster! Well this question appears solved but there are many useful answers. I should also say that as well as those above optimizations, I have memoized the function using Python dictionaries...
Ignoring the algorithm for a moment (yes, I know, bad idea), the running time of this can be decreased hugely just by switching from while to for.
for a in range(1, n / 2 + 1)
(Hope this doesn't have an off-by-one error. I'm prone to make these.)
Another thing that I would try is to look if the step width can be incremented.
Take a look at http://modular.fas.harvard.edu/ent/ent_py .
The function sqrtmod does the job if you set a = -1 and p = n.
You missed a small point because the running time of your improved algorithm is still in the order of the square root of n. As long you have only small primes n (let's say less than 2^64), that's ok, and you should probably prefer your implementation to a more complex one.
If the prime n becomes bigger, you might have to switch to an algorithm using a little bit of number theory. To my knowledge, your problem can be solved only with a probabilistic algorithm in time log(n)^3. If I remember correctly, assuming the Riemann hypothesis holds (which most people do), one can show that the running time of the following algorithm (in ruby - sorry, I don't know python) is log(log(n))*log(n)^3:
class Integer
# calculate b to the power of e modulo self
def power(b, e)
raise 'power only defined for integer base' unless b.is_a? Integer
raise 'power only defined for integer exponent' unless e.is_a? Integer
raise 'power is implemented only for positive exponent' if e < 0
return 1 if e.zero?
x = power(b, e>>1)
x *= x
(e & 1).zero? ? x % self : (x*b) % self
end
# Fermat test (probabilistic prime number test)
def prime?(b = 2)
raise "base must be at least 2 in prime?" if b < 2
raise "base must be an integer in prime?" unless b.is_a? Integer
power(b, self >> 1) == 1
end
# find square root of -1 modulo prime
def sqrt_of_minus_one
return 1 if self == 2
return false if (self & 3) != 1
raise 'sqrt_of_minus_one works only for primes' unless prime?
# now just try all numbers (each succeeds with probability 1/2)
2.upto(self) do |b|
e = self >> 1
e >>= 1 while (e & 1).zero?
x = power(b, e)
next if [1, self-1].include? x
loop do
y = (x*x) % self
return x if y == self-1
raise 'sqrt_of_minus_one works only for primes' if y == 1
x = y
end
end
end
end
# find a prime
p = loop do
x = rand(1<<512)
next if (x & 3) != 1
break x if x.prime?
end
puts "%x" % p
puts "%x" % p.sqrt_of_minus_one
The slow part is now finding the prime (which takes approx. log(n)^4 integer operation); finding the square root of -1 takes for 512-bit primes still less than a second.
Consider pre-computing the results and storing them in a file. Nowadays many platforms have a huge disk capacity. Then, obtaining the result will be an O(1) operation.
(Building on Adam's answer.)
Look at the Wikipedia page on quadratic reciprocity:
x^2 ≡ −1 (mod p) is solvable if and only if p ≡ 1 (mod 4).
Then you can avoid the search of a root precisely for those odd prime n's that are not congruent with 1 modulo 4:
def table(n):
if n == 2: return 1
if n%4 != 1: return None # or raise exception
...
Based off OP's second edit:
def table(n):
if n == 2: return 1
if n%4 != 1: return
mod = 0
a1 = n - 1
for a in xrange(1, a1, 2):
mod += a
while mod >= n: mod -= n
if mod == a1: return a//2 + 1
It looks like you're trying to find the square root of -1 modulo n. Unfortunately, this is not an easy problem, depending on what values of n are input into your function. Depending on n, there might not even be a solution. See Wikipedia for more information on this problem.
Edit 2: Surprisingly, strength-reducing the squaring reduces the time a lot, at least on my Python2.5 installation. (I'm surprised because I thought interpreter overhead was taking most of the time, and this doesn't reduce the count of operations in the inner loop.) Reduces the time from 0.572s to 0.146s for table(1234577).
def table(n):
n1 = n - 1
square = 0
for delta in xrange(1, n, 2):
square += delta
if n <= square: square -= n
if square == n1: return delta // 2 + 1
strager posted the same idea but I think less tightly coded. Again, jug's answer is best.
Original answer: Another trivial coding tweak on top of Konrad Rudolph's:
def table(n):
n1 = n - 1
for a in xrange(1, n // 2 + 1):
if (a*a) % n == n1: return a
Speeds it up measurably on my laptop. (About 25% for table(1234577).)
Edit: I didn't notice the python3.0 tag; but the main change was hoisting part of the calculation out of the loop, not the use of xrange. (Academic since there's a better algorithm.)
Is it possible for you to cache the results?
When you calculate a large n you are given the results for the lower n's almost for free.
One thing that you are doing is repeating the calculation -a*a over and over again.
Create a table of the values once and then do look up in the main loop.
Also although this probably doesn't apply to you because your function name is table but if you call a function that takes time to calculate you should cache the result in a table and just do a table look up if you call it again with the same value. This save you the time of calculating all of the values when you first run but you don't waste time repeating the calculation more than once.
I went through and fixed the Harvard version to make it work with python 3.
http://modular.fas.harvard.edu/ent/ent_py
I made some slight changes to make the results exactly the same as the OP's function. There are two possible answers and I forced it to return the smaller answer.
import timeit
def table(n):
if n == 2: return 1
if n%4 != 1: return
a1=n-1
def inversemod(a, p):
x, y = xgcd(a, p)
return x%p
def xgcd(a, b):
x_sign = 1
if a < 0: a = -a; x_sign = -1
x = 1; y = 0; r = 0; s = 1
while b != 0:
(c, q) = (a%b, a//b)
(a, b, r, s, x, y) = (b, c, x-q*r, y-q*s, r, s)
return (x*x_sign, y)
def mul(x, y):
return ((x[0]*y[0]+a1*y[1]*x[1])%n,(x[0]*y[1]+x[1]*y[0])%n)
def pow(x, nn):
ans = (1,0)
xpow = x
while nn != 0:
if nn%2 != 0:
ans = mul(ans, xpow)
xpow = mul(xpow, xpow)
nn >>= 1
return ans
for z in range(2,n) :
u, v = pow((1,z), a1//2)
if v != 0:
vinv = inversemod(v, n)
if (vinv*vinv)%n == a1:
vinv %= n
if vinv <= n//2:
return vinv
else:
return n-vinv
tt=0
pri = [ 5,13,17,29,37,41,53,61,73,89,97,1234577,5915587277,3267000013,3628273133,2860486313,5463458053,3367900313 ]
for x in pri:
t=timeit.Timer('q=table('+str(x)+')','from __main__ import table')
tt +=t.timeit(number=100)
print("table(",x,")=",table(x))
print('total time=',tt/100)
This version takes about 3ms to run through the test cases above.
For comparison using the prime number 1234577
OP Edit2 745ms
The accepted answer 522ms
The above function 0.2ms

Resources