How to find all possible options in C? - c

I'm trying to find a efficient algorithm in C, which provides me all options of a given equation.
I have equation AX + BY = M, where A, B and M i got on input (scanf).
For example lets have: 5X + 10Y = 45
1st option: 5 * 9 + 10 * 0
2nd option: 5 * 7 + 10 * 1
n-th option: 5 * 1 +
10 * 4
And also I need to count how many possible options exist?
Some tips, hints?
I forgot to say that X and Y are in Z and >= 0, so there is no infinite options.

The question makes sense if you restrict to non-negative unknowns.
Rewrite the equation as
AX = M - BY.
There can be positive solutions as long as the RHS is positive, i.e.
BY ≤ M,
or
Y ≤ M/B.
Then for a given Y, there is a solution iff
A|(M - BY)
You can code this in Python as
for Y in range(M / B + 1):
if (M - B * Y) % A == 0:
X= (M - B * Y) / A
The solutions are
9 0
7 1
5 2
3 3
1 4
The number of iterations equals M / B. If A > B, it is better to swap X and Y.

you can calcule every solution if you put some limit in your input value, for example: use X and Y in a value included from 0 to 9... in this way you can use for to calculate every solution.

The number of solution is infinite:
find a first solution like: X=9, Y=0.
you can create another solution by using:
X' = X+2*p
Y' = Y-p
For any p in Z.
This proves your program will never terminate.

Related

binomial coefficient for very high numbers in c

So the task I have to solve is to calculate the binomial coefficient for 100>=n>k>=1 and then say how many solutions for n and k are over an under barrier of 123456789.
I have no problem in my formula of calculating the binomial coefficient but for high numbers n & k -> 100 the datatypes of c get to small to calculated this.
Do you have any suggestions how I can bypass this problem with overflowing the datatypes.
I thought about dividing by the under barrier straight away so the numbers don't get too big in the first place and I have to just check if the result is >=1 but i couldn't make it work.
Say your task is to determine how many binomial coefficients C(n, k) for 1 ≤ k < n ≤ 8 exceed a limit of m = 18. You can do this by using the recurrence C(n, k) = C(n − 1, k) + C(n − 1, k − 1) that can visualized in Pascal's triangle.
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 (20) 15 6 1
1 7 (21 35 35 21) 7 1
1 8 (28 56 70 56 28) 8 1
Start at the top and work your way down. Up to n = 5, everything is below the limit of 18. On the next line, the 20 exceeds the limit. From now on, more and more coefficients are beyond 18.
The triangle is symmetric and strictly increasing in the first half of each row. You only need to find the first element that exceeds the limit on each line in order to know how many items to count.
You don't have to store the whole triangle. It is enough to keey the last and current line. Alternatively, you can use the algorithm detailed [in this article][ot] to work your way from left to right on each row. Since you just want to count the coefficients that exceed a limit and don't care about their values, the regular integer types should be sufficient.
First, you'll need a type that can handle the result. The larget number you need to handle is C(100,50) = 100,891,344,545,564,193,334,812,497,256. This number requires 97 bits of precision, so your normal data types won't do the trick. A quad precision IEEE float would do the trick if your environment provides it. Otherwise, you'll need some form of high/arbitrary precision library.
Then, to keep the numbers within this size, you'll want cancel common terms in the numerator and the denominator. And you'll want to calculate the result using ( a / c ) * ( b / d ) * ... instead of ( a * b * ... ) / ( c * d * ... ).

MATLAB Vectorised Pairwise Distance

I'm struggling to vectorise a function which performs a somewhat pairwise difference between two vectors x = 2xN and v = 2xM, for some arbitrary N, M. I have this to work when N = 1, although, I would like to vectorise this function to apply to inputs with N arbitrary.
Indeed, what I want this function to do is for each column of x find the normed difference between x(:,column) (a 2x1) and v (a 2xM).
A similar post is this, although I haven't been able to generalise it.
Current implementation
function mat = vecDiff(x,v)
diffVec = bsxfun(#minus, x, v);
mat = diffVec ./ vecnorm(diffVec);
Example
x =
1
1
v =
1 3 5
2 4 6
----
vecDiff(x,v) =
0 -0.5547 -0.6247
-1.0000 -0.8321 -0.7809
Your approach can be adapted as follows to suit your needs:
Permute the dimensions of either x or v so that its number of columns becomes the third dimension. I'm choosing v in the code below.
This lets you exploit implicit expansion (or equivalently bsxfun) to compute a 2×M×N array of differences, where M and N are the numbers of columns of x and v.
Compute the vector-wise (2-)norm along the first dimension and use implicit expansion again to normalize this array:
x = [1 4 2 -1; 1 5 3 -2];
v = [1 3 5; 2 4 6];
diffVec = x - permute(v, [1 3 2]);
diffVec = diffVec./vecnorm(diffVec, 2, 1);
You may need to apply permute differently if you want the dimensions of the output in another order.
Suppose your two input matrices are A (a 2 x N matrix) and B (a 2 x M matrix), where each column represents a different observation (note that this is not the traditional way to represent data).
Note that the output will be of the size N x M x 2.
out = zeros(N, M, 2);
We can find the distance between them using the builtin function pdist2.
dists = pdist2(A.', B.'); (with the transpositions required for the orientation of the matrices)
To get the individual x and y distances, the easiest way I can think of is using repmat:
xdists = repmat(A(1,:).', 1, M) - repmat(B(1,:), N, 1);
ydists = repmat(A(2,:).', 1, M) - repmat(B(2,:), N, 1);
And we can then normalise this by the distances found earlier:
out(:,:,1) = xdists./dists;
out(:,:,2) = ydists./dists;
This returns a matrix out where the elements at position (i, j, :) are the components of the normed distance between A(:,i) and B(:,j).

Check subset sum for special array equation

I was trying to solve the following problem.
We are given N and A[0]
N <= 5000
A[0] <= 10^6 and even
if i is odd then
A[i] >= 3 * A[i-1]
if i is even
A[i]= 2 * A[i-1] + 3 * A[i-2]
element at odd index must be odd and at even it must be even.
We need to minimize the sum of the array.
and We are given a Q numbers
Q <= 1000
X<= 10^18
We need to determine is it possible to get subset-sum = X from our array.
What I have tried,
Creating a minimum sum array is easy. Just follow the equations and constraints.
The approach that I know for subset-sum is dynamic programming which has time complexity sum*sizeof(Array) but since sum can be as large as 10^18 that approach won't work.
Is there any equation relation that I am missing?
We can make it with a bit of math:
sorry for latex I am not sure it is possible on stack?
let X_n be the sequence (same as being defined by your A)
I assume X_0 is positive.
Thus sequence is strictly increasing and minimization occurs when X_{2n+1} = 3X_{2n}
We can compute the general term of X_{2n} and X_{2n+1}
v_0 =
X0
X1
v_1 =
X1
X2
the relation between v_0 and v_1 is
M_a =
0 1
3 2
the relation between v_1 and v_2 is
M_b =
0 1
0 3
hence the relation between v_2 and v_0 is
M = M_bM_a =
3 2
9 6
we deduce
v_{2n} =
X_{2n}
X_{2n+1}
v_{2n} = M^n v_0
Follow the classical diagonalization... and we (unless mistaken) get
X_{2n} = 9^n/3 X_0 + 2*9^{n-1}X_1
X_{2n+1} = 9^n X_0 + 2*9^{n-1}/3X_1
recall that X_1 = 3X_0 thus
X_{2n} = 9^n X_0
X_{2n+1} = 3.9^n X_0
Now if we represent the sum we want to check in base 9 we get
9^{n+1} 9^n
___ ________ ___ ___
X^{2n+2} X^2n
In the X^{2n} places we can only put a 1 or a 0 (that means we take the 2n-th elem from the A)
we may also put a 3 in the place of the X^{2n} place which means we selected the 2n+1th elem from the array
so we just have to decompose number in base 9, and check whether all its digits or either 0,1 or 3 (and also if its leading digit is not out of bound of our array....)

Matlab Convert Vector to Binary Matrix [duplicate]

This question already has answers here:
Create a zero-filled 2D array with ones at positions indexed by a vector
(4 answers)
Closed 6 years ago.
I have a vector v of size (m,1) whose elements are integers picked from 1:n. I want to create a matrix M of size (m,n) whose elements M(i,j) are 1 if v(i) = j, and are 0 otherwise. I do not want to use loops, and would like to implement this as a simple vector-matrix manipulation only.
So I thought first, to create a matrix with repeated elements
M = v * ones(1,n) % this is a (m,n) matrix of repeated v
For example v=[1,1,3,2]'
m = 4 and n = 3
M =
1 1 1
1 1 1
3 3 3
2 2 2
then I need to create a comparison vector c of size (1,n)
c = 1:n
1 2 3
Then I need to perform a series of logical comparisons
M(1,:)==c % this results in [1,0,0]
.
M(4,:)==c % this results in [0,1,0]
However, I thought it should be possible to perform the last steps of going through each single row in compact matrix notation, but I'm stumped and not knowledgeable enough about indexing.
The end result should be
M =
1 0 0
1 0 0
0 0 1
0 1 0
A very simple call to bsxfun will do the trick:
>> n = 3;
>> v = [1,1,3,2].';
>> M = bsxfun(#eq, v, 1:n)
M =
1 0 0
1 0 0
0 0 1
0 1 0
How the code works is actually quite simple. bsxfun is what is known as the Binary Singleton EXpansion function. What this does is that you provide two arrays / matrices of any size, as long as they are broadcastable. This means that they need to be able to expand in size so that both of them equal in size. In this case, v is your vector of interest and is the first parameter - note that it's transposed. The second parameter is a vector from 1 up to n. What will happen now is the column vector v gets replicated / expands for as many values as there are n and the second vector gets replicated for as many rows as there are in v. We then do an eq / equals operator between these two arrays. This expanded matrix in effect has all 1s in the first column, all 2s in the second column, up until n. By doing an eq between these two matrices, you are in effect determining which values in v are equal to the respective column index.
Here is a detailed time test and breakdown of each function. I placed each implementation into a separate function and I also let n=max(v) so that Luis's first code will work. I used timeit to time each function:
function timing_binary
n = 10000;
v = randi(1000,n,1);
m = numel(v);
function luis_func()
M1 = full(sparse(1:m,v,1));
end
function luis_func2()
%m = numel(v);
%n = 3; %// or compute n automatically as n = max(v);
M2 = zeros(m, n);
M2((1:m).' + (v-1)*m) = 1;
end
function ray_func()
M3 = bsxfun(#eq, v, 1:n);
end
function op_func()
M4= ones(1,m)'*[1:n] == v * ones(1,n);
end
t1 = timeit(#luis_func);
t2 = timeit(#luis_func2);
t3 = timeit(#ray_func);
t4 = timeit(#op_func);
fprintf('Luis Mendo - Sparse: %f\n', t1);
fprintf('Luis Mendo - Indexing: %f\n', t2);
fprintf('rayryeng - bsxfun: %f\n', t3);
fprintf('OP: %f\n', t4);
end
This test assumes n = 10000 and the vector v is a 10000 x 1 vector of randomly distributed integers from 1 up to 1000. BTW, I had to modify Luis's second function so that the indexing will work as the addition requires vectors of compatible dimensions.
Running this code, we get:
>> timing_binary
Luis Mendo - Sparse: 0.015086
Luis Mendo - Indexing: 0.327993
rayryeng - bsxfun: 0.040672
OP: 0.841827
Luis Mendo's sparse code wins (as I expected), followed by bsxfun, followed by indexing and followed by your proposed approach using matrix operations. The timings are in seconds.
Assuming n equals max(v), you can use sparse:
v = [1,1,3,2];
M = full(sparse(1:numel(v),v,1));
What sparse does is build a sparse matrix using the first argument as row indices, the second as column indices, and the third as matrix values. This is then converted into a full matrix with full.
Another approach is to define the matrix containing initially zeros and then use linear indexing to fill in the ones:
v = [1,1,3,2];
m = numel(v);
n = 3; %// or compute n automatically as n = max(v);
M = zeros(m, n);
M((1:m) + (v-1)*m) = 1;
I think I've also found a way to do it, and it would be nice if somebody could tell me which of the methods shown is faster for very large vectors and matrices. The additional method I thought of is the following
M= ones(1,m)'*[1:n] == v * ones(1,n)

How can i find the number of lowest possible square that can fit in the given square

let's suppose i have a square of 7x7.i can fill the square with other squares(i.e the squares of dimension 1x1,2x2.....6x6).How can i can fill the square with least possible smaller squares.please help me.
Consider a square with dimensions s x s. Cutting a smaller square of dimensions m x m out will result in a square of m x m, a square of n x n, and two rectangles of dimensions m x n, where m + n = s.
When s is even, the square can be divided such that m = n, in which case the rectangles will also be squares, resulting in an answer of 4.
However, when s is odd, values of m and n must be chosen such that the resulting rectangle can be filled with the least number of squares possible. There doesn't seem to be an immediately obvious way to figure out the best configuration, so I would suggest coming up with an algorithm to figure out the least number of squares that can be used to fill a rectangle of size m x n (this is a slightly simpler problem and I believe it can be solved with a recursive algorithm). The total number of squares needed will then be equal to 2 x ([number of squares in m x n rectangle] + 1). You can use a loop to check all the sizes of m between 1 and s/2.
Hope that gets you started.
Consider a square with dimensions s x s.
Factorialise s into primes. Then solve the problem for each prime sp. The answer will be the same for sp x sp as for s x s. It is probable that the smallest prime will give the lowest result. I have have no proof of this, but I have checked by hand up to 17 x 17.
This is a generalisation of Otaias notion of an even s resulting in an answer of 4.
Placiing algorithm:
You need to loop from n = (s+1)/2, rounded down, to n = s-1.
Put the n x n square in a corner.
Let m = s - n.
Place m x m squares in the adjacent corners and keep placing them until they (almost) reach the end of the n x n square.
The remaining space will be m x m (if you are lucky), or up to 2m-1 x 2m-1 with a corner piece missing.
Fill the remaining space with a similar algorithm. Start with placing a n2 x n2 square in the corner opposite to the missing corner piece.
Working by hand I have obtained the following results:
s minimum number of squares:
2 4
3 6
5 8
7 9
11 10
13 11
17 12
First check if n is even. If n is even, then the answer is four since there isn't a way to fit 3 squares or 2 squares together to make another square so that solves it for half of all possible cases
BEFORE YOU PROCEED: This approach is incomplete and this may be the WRONG approach
I just intend to throw out an out-of-the-box idea just because I feel like this may help and, hopefully, advance the problem. I feel like it may have some correlation with Goldbach's weak conjecture. The algorithm may be too long to compute for larger values, and I'm not sure how much optimization is happening.
Now my idea would be to try to enumerate all triples (n1,n2,n3) where n1 + n2 + n3 = n AND n1, n2, n3 are all prime (which are >= 2) AND n >= 7 AND n1 <= n2 <= n3
Now let me literally depict my algorithm:
Now my idea is find all possible triples (n1,n2,n3) so it fits the definition stated above. Next set n_s = n1 + n2. IF n_s > n3 follow the depiction above else flip n_s and n3
Now the problem is the white rectangles left over (that should be congruent to each other).
Let n4 x n3 denote the rectangles where:
n4 = n - 2 * n3 \\if following the depicted example
Enumerate all possible triples (n41, n42, n43) (treating n as n = n4, so n3 >= 7) and (n31, n32, n33) (treating n as n = n3, so n3 >= 7). Next find the value where n_s3 == n_s4 and both are the greatest they could be. For example:
Let's suppose x3 = 17 and x4 = 13
Enumeration of x3 = 17:
2 + 2 + 13
3 + 3 + 11
5 + 5 + 7
Enumeration of x_s3:
4 = 2 + 2
6 = 3 + 3
10 = 5 + 5
12 = 5 + 7
14 = 3 + 11
15 = 2 + 13
Enumeration of x4 = 13:
2 + 2 + 7
3 + 5 + 5
Enumeration of x_s4:
4 = 2 + 2
8 = 3 + 5
9 = 2 + 7
10 = 5 + 5
Since 10 is the largest value shared between 13 and 17, you fit a 10 by 10 square in the (both rectangles) and now you have a none parallelogram which get further and further more difficult to fill, but may be (I feel) towards the right direction.
All feed back appreciated.

Resources