Plese write a solution for a prolog task - arrays

I have a matrix M x N, I need to switch places of the elements with indexed [1,N] and [M,N].
Update
I am really new to Prolog, here is my solution that returns false :(
main([FirstRow|Tail],X):-
last(FirstRow, A),
last(Tail, LastRow),
last(LastRow, B),
skipLastItem(FirstRow,FirstRowWithoutA),
skipLastItem(LastRow,LastRowWithoutB),
append(FirstRowWithoutA,[B],FirstRowNew),
append(LastRowWithoutB,[A],LastRowNew),
assign([FirstRowNew],X),
skipLastItem(Tail,Middle),
appendAllElements(Middle,X),
append(X,LastRowNew,X).
appendAllElements([X|Tail],List):-
append(List,X,NewList),
appendAllElements(Tail,NewList).
appendAllElements([],_).
assign(Item,Item).
skipLastItem([_],[ ]) :- !.
skipLastItem([H|T],[H|S]) :-
skipLastItem(T,S).

This sounds like homework, so I'm going to be a bit vague here...
Start with the simpler problem of replacing one value in a list. Write a recursive predicate
swap_list(X,N,A,B,Y)
which should be read as "for a list X, at position N, removing the value A and replacing it with B gives the list Y".
Now we can extend this to the case of matrices. Write a second recursive predicate
swap_matrix(X,M,N,A,B,Y)
which should be read as "for a matrix X, at position (M,N), removing element A and replacing it with B gives the matrix Y". The base case of this recursion, where M=0, will contain a call to swap_list.
Now, you can swap two positions (M1,N1) and (M2,N2) with the following:
swap(X,M1,N1,M2,N2,Y) :-
swap_matrix(X,M1,N1,A,B,Z),
swap_matrix(Z,M2,N2,B,A,Y).
Note that we insert B into the matrix Z before we even know what it is - B isn't assigned a value until the second swap_matrix call.

Related

Does the array “sum and/or sub” to `x`?

Goal
I would like to write an algorithm (in C) which returns TRUE or FALSE (1 or 0) depending whether the array A given in input can “sum and/or sub” to x (see below for clarification). Note that all values of A are integers bounded between [1,x-1] that were randomly (uniformly) sampled.
Clarification and examples
By “sum and/or sub”, I mean placing "+" and "-" in front of each element of array and summing over. Let's call this function SumSub.
int SumSub (int* A,int x)
{
...
}
SumSub({2,7,5},10)
should return TRUE as 7-2+5=10. You will note that the first element of A can also be taken as negative so that the order of elements in A does not matter.
SumSub({2,7,5,2},10)
should return FALSE as there is no way to “sum and/or sub” the elements of array to reach the value of x. Please note, this means that all elements of A must be used.
Complexity
Let n be the length of A. Complexity of the problem is of order O(2^n) if one has to explore all possible combinations of pluses and minus. However, some combinations are more likely than others and therefore are worth being explored first (hoping the output will be TRUE). Typically, the combination which requires substracting all elements from the largest number is impossible (as all elements of A are lower than x). Also, if n>x, it makes no sense to try adding all the elements of A.
Question
How should I go about writing this function?
Unfortunately your problem can be reduced to subset-sum problem which is NP-Complete. Thus the exponential solution can't be avoided.
The original problem's solution is indeed exponential as you said. BUT with the given range[1,x-1] for numbers in A[] you can make the solution polynomial. There is a very simple dynamic programming solution.
With the order:
Time Complexity: O(n^2*x)
Memory Complexity: O(n^2*x)
where, n=num of elements in A[]
You need to use dynamic programming approach for this
You know the min,max range that can be made in in the range [-nx,nx]. Create a 2d array of size (n)X(2*n*x+1). Lets call this dp[][]
dp[i][j] = taking all elements of A[] from [0..i-1] whether its possible to make the value j
so
dp[10][3] = 1 means taking first 10 elements of A[] we CAN create the value 3
dp[10][3] = 0 means taking first 10 elements of A[] we can NOT create the value 3
Here is a kind of pseudo code for this:
int SumSub (int* A,int x)
{
bool dp[][];//set all values of this array 0
dp[0][0] = true;
for(i=1;i<=n;i++) {
int val = A[i-1];
for(j=-n*x;j<=n*x;j++) {
dp[i][j]=dp[ i-1 ][ j + val ] | dp[ i-1 ][ j - val ];
}
}
return dp[n][x];
}
Unfortunately this is NP-complete even when x is restricted to the value 0, so don't expect a polynomial-time algorithm. To show this I'll give a simple reduction from the NP-hard Partition Problem, which asks whether a given multiset of positive integers can be partitioned into two parts having equal sums:
Suppose we have an instance of the Partition Problem consisting of n positive integers B_1, ..., B_n. Create from this an instance of your problem in which A_i = B_i for each 1 <= i <= n, and set x = 0.
Clearly if there is a partition of B into two parts C and D having equal sums, then there is also a solution to the instance of your problem: Put a + in front of every number in C, and a - in front of every number in D (or the other way round). Since C and D have equal sums, this expression must equal 0.
OTOH, if the solution to the instance of your problem that we just created is YES (TRUE), then we can easily create a partition of B into two parts having equal sums: just put all the positive terms in one part (say, C), and all the negative terms (without the preceding - of course) in the other (say, D). Since we know that the total value of the expression is 0, it must be that the sum of the (positive) numbers in C is equal to the (negated) sum of the numbers in D.
Thus a YES to either problem instance implies a YES to the other problem instance, which in turn implies that a NO to either problem instance implies a NO to the other problem instance -- that is, the two problem instances have equal solutions. Thus if it were possible to solve your problem in polynomial time, it would be possible to solve the NP-hard Partition Problem in polynomial time too, by constructing the above instance of your problem, solving it with your poly-time algorithm, and reporting the result it gives.

how to simulate loop in turbo prolog

I want to compute the summation of odd numbers in a given range like 1 to 9 is the given input. and my program will show the summation of all odd numbers between 1 to 9. Though the task is so simple theoriticaly, but as a starter of turbo prolog, I can't handle the loop to compute the summation. Any help would be appreciating..
Advance thanks.
I'm not going to write the full solution for you, but can give an idea how to "loop" through a summation in a general way. Looping in Prolog is often done through recursion. The recursion gets around the fact that Prolog will not let you reinstantiate a variable within the same predicate clause once it's instantiated (unless you backtrack). The following is ISO Prolog syntax.
sum_values(First, Last, Sum) :-
sum_values(First, Last, 0, Sum).
sum_values(First, Last, Sum, Sum) :-
First > Last.
sum_values(First, Last, Acc, Sum) :-
First =< Last,
NewAcc is Acc + First,
NewFirst is First + 1,
sum_values(NewFirst, NewAcc, Sum).
The first clause sets up an accumulator starting at the value 0.
The second clause handles the normal recursive case where the first value does not exceed the last. The first value is added to the accumulator to create an updated accumulator, and the "first" value is incremented to create a new first value. The recursive call to sum_values computes the rest of the sum with the new accumulator.
The last (third) clause unifies the final sum with the accumulator when the first value finally exceeds the last.
Note that I could have implemented this without introducing the accumulator, but then I wouldn't have the tail recursion which can be optimized (if desired) by the Prolog system. The non-accumulator version looks like this:
sum_values(First, Last, 0) :- First > Last.
sum_values(First, Last, Sum) :-
First =< Last,
NewFirst is First + 1,
sum_values(NewFirst, Last, PartialSum),
Sum is PartialSum + First.
This is a little shorter, but there's no tail recursion that can be refactored.
Modifications you would need to make for your problem (these are ones I'm aware of, as I'm only a little familiar with some of TP's syntax):
Replace is/2 with =/2 (I think TP uses =/2 for expression evaluation)
You might have to replace =< with <= (I don't recall which one TP likes)
Check that First is odd. If it's not, you need to skip adding it to the accumulator.
You could also do an initial check for odd First and if it's not odd, increment it to form a new First, then proceed doing a summation incrementing by 2 through the recursion instead of by 1.

Smart and Fast Indexing of multi-dimensional array with R

This is another step of my battle with multi-dimensional arrays in R, previous question is here :)
I have a big R array with the following dimensions:
> data = array(..., dim = c(x, y, N, value))
I'd like to perform a sort of bootstrap comparing the mean (see here for a discussion about it) obtained with:
> vmean = apply(data, c(1,2,3), mean)
With the mean obtained sampling the N values randomly with replacement, to explain better if data[1,1,,1] is equals to [v1 v2 v3 ... vN] I'd like to replace it with something like [v_k1 v_k2 v_k3 ... v_kN] with k values sampled with sample(N, N, replace = T).
Of course I want to AVOID a for loop. I've read this but I don't know how to perform an efficient indexing of this array avoiding a loop through x and y.
Any ideas?
UPDATE: the important thing here is that I want a different sample for each sample in the fourth (value) dimension, otherwise it would be simple to do something like:
> dataSample = data[,,sample(N, N, replace = T), ]
Also there's the compiler package which speeds up for loops by using a Just In Time compiler.
Adding thes lines at the top of your code enables the compiler for all code.
require("compiler")
compilePKGS(enable=T)
enableJIT(3)
setCompilerOptions(suppressAll=T)

algorithm to sort elements of three arrays

Here's the stumper:
Start with three arrays A, B and C with a total of 2n+1 entries.
Write an algorithm to sort all of the entries from all of the arrays
using only the following two methods:
X = sort(X) replaces the array X with the sorted version.
(X , Y) = doubleUp(X , Y) does nothing if X has more elements
than Y, otherwise it removes the first length(X) entries from Y
and appends them to the end of X.
Here's what I've tried so far. If two of the arrays are empty, then just use sort on the nonempty array.
If one of the arrays is empty, then I think I can use doubleUp to get one array to have just one thing and the other array to have everything else, and if that singleton array has the smallest (or largest) element, then that works. So I can use sort after I use doubleUp each time to make sure this happens. I coded this up in Maple and it worked for all the cases I checked.
I have no idea how to do it with 3 arrays though. Anyone have any ideas?
Sounds like nonsense. The total number of entries is odd. The only way to increase the length of an array is to make it the smaller first argument of doubleUp, in which case it ends up with an even number of elements. So unless all the elements are in one array to begin with there's no way to make one array contain all the elements, sorted or otherwise.
So, the desired final result is not a single array containing all the elements in order. Or if it is, then the answer to the question is "it cannot be done".

Entry level question about Matlab array operation

Hey guys. I have this question to ask. In C programming, if we want to store several values in an array, we implement that using loops like this:
j=0; //initialize
for (idx=1,idx less than a constant; idex++)
{
slope[j]=(y2-y1)/(x2-x1);
j++;
}
My question is in Matlab do we have any simpler way to get the same array 'slope' without manually increasing j? Something like:
for idx=1:constant
slope[]=(y2-y1)/(x2-x1);
Thank you!
Such operations can usually be done without looping.
For example, if the slope is the same for all entries, you can write
slope = ones(numRows,numCols) * (y2-y1)/(x2-x1);
where numRows and numCols are the size of the array slope.
If you have a list of y-values and x-values, and you want the slope at every point, you can call
slope = (y(2:end)-y(1:end-1))./(x(2:end)-x(1:end-1)
and get everything in one go. Note that y(2:end) are all elements from the second to the last, and y(1:end-1) are all elements from the first to the second to last. Thus, the first element of the slope is calculated from the difference between the second and the first element of y. Also, note the ./ instead of /. The dot makes it an element-wise operation, meaning that I divide the first element of the array in the numerator by the first element of the array in the denominator, etc.

Resources