i am tackling on a problem. i have gotten stuck, so i decided to ask here. so, the problem is, given n team and their points respectively of a world cup group. determine whether the set is possible or not. each team plays with every other team in the group once. hence, each group plays (n-1) times. for 1<=n<=5. in a match if a team win, they'll get 3 points, if lose 0 points, and tied, 1 point. my idea of the solution is using 2d(n x n) array which act like a scoreboard.
A B C D E //column
A X 1 3 0 1 //r
B 1 X 0 1 0 //o
C 0 3 X 0 3 //w
D 3 1 3 X 1
E 1 3 0 1 X
so for every column and row representing one distinct team in a multiplication table fashion(team in column 1(a) is same as team row 1(A), and so on)note that the alphabet above and beside the array(A,B..) isn't included, just for clearance. every intersection between a row and a column is representing a match, except intersection between same column and row. e.g. column 1, row 2, means team A tied against team B, column 2, row 1 means team B tied against A.
my idea is to use recursive brute-force-wise algorithm to check every possibilities. i have developed one, it's work good enough in 4 teams setting, but doesn't so well for 5. so the algorithm work like starting from column 2 row 1 check 1 out of 3 possibility then crawl to the bottom-side and right-side of it and repeat through the second last column, and last row.
you may have noticed that x diagonal act like mirror. when we change column 1 row 3(A against C) to win, we must change column 3 row 1(C against A) to lose simultaneously. here some part of my code
/*
* scoreBoard[][] array <- the array which i have described above
* scores[] array <- store the given score
* x <- current column
* y <- current row
* n <- gnumber of team
*/
bool Solve(int x, int y, int scoreBoard[][5], int scores[], int n)
{
bool con1, con2, con3;
if((x < y)&&(y < n)) {
scoreBoard[x][y] = 3;//win-lose - possibiiity 1
scoreBoard[y][x] = 0;
//crawl to the right and bottom side array
con1 = (Solve( x + 1, y, scoreBoard, scores, n)) || (Solve( x, y + 1, scoreBoard, scores, n));
scoreBoard[x][y] = 0;//lose-win - possibility 2
scoreBoard[y][x] = 3;
con2 = (Solve( x + 1, y, scoreBoard, scores, n)) || (Solve( x, y + 1, scoreBoard, scores, n));
scoreBoard[x][y] = 1;//tied - possibility 3
scoreBoard[y][x] = 1;
//crawl to the right and bottom side array
con3 = (Solve( x + 1, y, scoreBoard, scores, n)) || (Solve( x, y + 1, scoreBoard, scores,n));
return con1 || con2 || con3;
} else {
if((x==y)&&(y==n-1))
return CheckArr(scoreBoard, scores, n); //to check whether the current array equal with the given score or not
else
return 0;
}
}
i presume, the problem is that this algorithm does not cover every possibility, because it work on(give the expected output for some, and dont so for other) a few 5 team setting possiblity. but i haven't managed how to fix it.
thanks in advance for every suggestion, and helpful link, also, i'll welcome any other strategy. hope this clear enough.
Related
Given an array of values, how can I update a range with a sequence within that array, efficiently?
Updates are performed multiple times. After all updates are performed, we can query any index of the array for its final value.
If we update a value of v at index i, every element at index j is increased with a value of max { v - | i - j | , 0 }
For example.
array = {1,1,1,1,1,1}
Now I do an update at index 4 with a value of 3 the resulting array will look like this:
array = {1,1,2,3,4,3}
I want to perform both operations efficiently.
You can't update a range of elements "efficiently". Questions like these are always about figuring out how to avoid updating a range of elements altogether.
To figure out this one, consider two operations:
INTEGRATE(A) takes an array and replaces every element A[i] with sum(A[0]...A[i]).
DIFF(A) takes an array and replaces every element with its difference from the previous element (the first element is left unaltered).
These operations have some important properties:
They are inverses: INTEGRATE(DIFF(A)) = DIFF(INTEGRATE(A)) = A for all arrays A; and
They are linear: If A = B+C, then INTEGATE(A) = INTEGRATE(B) + INTEGRATE(C), and similarly for DIFF.
Your final array is the sum of the original array, plus a whole bunch of those "triangle" arrays. Let's say it's A + T1 + T2 + T3... etc.
Each one of those triangles has a whole bunch of non-zero elements, but watch what happens when you apply DIFF twice:
[0,0,1,2,3,2,1,0,0] -> [0,0,1,1,1,-1,-1,-1,0] -> [0,0,1,0,0,-2,0,0,1]
The result has only 3 non-zero elements. That gives us a way to calculate your final array quickly.
Let D(X) = DIFF(DIFF(X)) and let I(X) = INTEGRATE(INTEGRATE(X)). Then instead of calculating A + T1 + T2 + T3..., you calculate I( D(A) + D(T1) + D(T2) + D(T3)... )
Since all those D(Tx) have at most 3 non-zero elements, it's quick and easy to add them into the result.
I'm deliberately explaining how to solve it, without giving you full code. This also handles the complex case of interleaved updates and lookups, but therefore is more complex than what Matter Timmermans came up with.
You obviously can't use an array as your representation. It makes lookups fast, but an update with value k will be an O(k) operation.
Our second try, is to just have a list of the updates. Now updates are O(1), but after m updates a lookup is O(m).
What we need is to have a way to store updates such that both adding an update and doing a lookup are fast.
The first step is to change an update from "update at a value" to "update a range by a linear rule". That is currently you say:
update at 4 by 3
Instead we'd say:
from 2 to 3:
update by x - 2
from 4 to 5:
update by 7 - x
This isn't yet a win. But it becomes one when you rewrite the ranges in terms of a standard set of intervals. First the original array
from 0 to 5 1 + 0x
Now the array after update:
from 0 to 5, 1 + 0x +
from 2 to 3, -1 + x
from 4 to 5, 7 - x
This can be represented compactly in 2 arrays:
m = [0, 0, 1, 0, -1, 0]
b = [1, 0, -1, 0, 7, 0]
And as complicated as it feels, now both updates and lookups wind up with O(log(n)) work.
For example for a lookup:
def rising_binary (n):
power = 1
m = 0
yield m
while m < n:
if n & power:
m += power
yield m
power *= 2
...
answer = 0
for bin in rising_binary(k):
answer += m[bin] * k + b[bin]
If i'm adding a newvlaue to a row vector x, it would be
x = [newvlue, x] % use of ,
but if to a column vector x, it would be
x = [newvlue; x] % use of ;
so i have to know in advance if it's a row or column vector in order to perform this front insertion. But i might not always know as x is meant to be a user inputs. So every time i need to perform this row vector or column vector check beforehand. However, let's say I don't really want to care if it's a row or column vector, I just need to add one element at the front of the array. Is there any elegant way to write the code?
You will have to check for the dimension of the input:
x = [1, 2, 3]
% or
x = [1; 2; 3]
new = 0;
% flexible concatenation
y = cat(~(size(x,1) > 1) + 1, new ,x)
Explanation
d = size(x,1) > 1 % check if column (=1) or row vector (>1)
z = ~(d) + 1 % results in either 1 or 2 for column or row vector
% as input for cat
y = cat(z, new ,x) % concatenate in correct dimension
or by using isrow as suggested in ThomasIsCoding's answer, but I guess it almost does the same:
z = isrow(x) + 1;
In any way you should use isvector to check, whether the input is actually a vector and not a matrix. But actually I would recommend to convert any input, row or column vector, into a column vector with
x = x(:)
to allow for consisting coding within your underlying function.
I like one-liners, try this one
a(1:end+1)=[100;a(:)]
works for both row and column matrices.
As #rahnema1 said, just add the new value to the end:
x = flip(x);
x(end+1) = newvalue;
x = flip(x);
Maybe you can define your custom function like below
function y = addhead(x,val)
if isrow(x)
y = horzcat(val,x);
else
y = vertcat(val,x);
end
end
You can use indexing to shift all elements by 1, then insert the new element at the beginning.
x(2:end+1)=x;
x(1)=7;
Suppose I have an array of length N. I want to choose n positions randomly, make them zero and then add the existing elements to the next non-zero element.
For example, suppose r = (r1,r2,r3,r4,r5), N = 5. Let n = 2. And the randomly picked positions are 3rd and 4th. Then I want to transform r to
r_new = (r1, r2, 0, 0, r3+r4+r5).
Instead if the randomly selected positions were 1 and 3, then I want to have
r_new = (0, r1 + r2, 0, r3+r4, r5).
I am coding in MATLAB. Here is my current code.
u = randperm(T);
ind = sort(u(1:n(i)));
tmp = r(ind);
r(ind) = 0;
x = find( r );
I am not necessarily looking for MATLAB code. Pseudocode would be helpful enough.
I'm assuming the last position can never be selected, otherwise the intended behaviour is undefined. So you randomly select n positions uniformly distributed from 1 up to N-1 (not up to N).
Here's one approach:
Select n distinct random positions from 1 to N-1, and sort them. Call the resulting vector of positions pos. This can be easily done with randperm and sort.
For each value in pos, say p, accumulate r(p) into r(p+1), and set r(p) to zero. This is done with a for loop.
In step 2, if position p+1 happens to belong to pos too, the accumulated value will be moved further to the right in a subsequent iteration. This works because pos has been sorted, so the randomly selected positions are processed from left to right.
r = [3 5 4 3 7 2 8]; %// data
n = 2; %// number of positions
pos = sort(randperm(numel(r)-1,n)); %// randomly select positions, and sort them
for p = pos
r([p p+1]) = [0 r(p)+r(p+1)]; %// process position p
end
Assuming N, n and r are already generated, then we select random indexes:
inds = randi(N,n,1);
Then to achieve the desired results you can loop as follows:
inds = sort(inds);
for ii=1:numel(inds)
if(inds(ii)<N)
r(inds(ii)+1)=r(inds(ii)+1) +r(inds(ii));
r(inds)=0;
else
r(inds)=0;
end
end
This will create the desired outcome of adding the values to the next index that wasn't selected to be set to 0.
Note I had to assume an edge case where if the last index is set to 0, then its value is not added to anything.
I am having trouble implementing this code due to the variable s_k being logical 0/1. In what way can I implement this statement?
s_k is a random sequence of 0/1 generated using a rand() and quantizing the output of rand() by its mean given below. After this, I don't know how to implement. Please help.
N =1000;
input = randn(N);
s = (input>=0.5); %converting into logical 0/1;
UPDATE
N = 3;
tmax = 5;
y(1) = 0.1;
for i =1 : tmax+N-1 %// Change here
y(i+1) = 4*y(i)*(1-y(i)); %nonlinear model for generating the input to Autoregressive model
end
s = (y>=0.5);
ind = bsxfun(#plus, (0:tmax), (0:N-1).');
x = sum(s(ind+1).*(2.^(-ind+N+1))); % The output of this conversion should be real numbers
% Autoregressive model of order 1
z(1) =0;
for j =2 : N
z(j) = 0.195 *z(j-1) + x(j);
end
You've generated the random logical sequence, which is great. You also need to know N, which is the total number of points to collect at one time, as well as a list of time values t. Because this is a discrete summation, I'm going to assume the values of t are discrete. What you need to do first is generate a sliding window matrix. Each column of this matrix represents a set of time values for each value of t for the output. This can easily be achieved with bsxfun. Assuming a maximum time of tmax, a starting time of 0 and a neighbourhood size N (like in your equation), we can do:
ind = bsxfun(#plus, (0:tmax), (0:N-1).');
For example, assuming tmax = 5 and N = 3, we get:
ind =
0 1 2 3 4 5
1 2 3 4 5 6
2 3 4 5 6 7
Each column represents a time that we want to calculate the output at and every row in a column shows a list of time values we want to calculate for the desired output.
Finally, to calculate the output x, you simply take your s_k vector, make it a column vector, use ind to access into it, do a point-by-point multiplication with 2^(-k+N+1) by substituting k with what we got from ind, and sum along the rows. So:
s = rand(max(ind(:))+1, 1) >= 0.5;
x = sum(s(ind+1).*(2.^(-ind+N+1)));
The first statement generates a random vector that is as long as the maximum time value that we have. Once we have this, we use ind to index into this random vector so that we can generate a sliding window of logical values. We need to offset this by 1 as MATLAB starts indexing at 1.
I am fairly new to OCaml and I want to implement a game which is similar to four-in-a-line.
What I need is some data structure to keep the game state. The game board is a 4x4 square with a total of 16 tiles.
I am looking for a representation for this in OCaml that will make it easy and fast to retrieve (or do some operation on) all the elements in entire column, row or diagonal.
I will be doing minimax search on this game, which is why speed is important.
So far I have considered a one-dimensional list. The problem with a list is that its hard to figure out what elements belong to each row/column/diagonal, and then retrieve them with a List.map for example.
I thought about using Array.make 4 (Array.make 4 Empty);;. This is absolutely perfect when it comes to rows. Its easy to get them and do a pattern match on it. But it is a chore to do pattern matching on individual columns and diagonals.
What I would like to be able to do is have a function that takes a game board and returns a list of lists containing all the rows/columns/diagonals. I would then like to do, for example, match (rows,columns,diagonals) with (Empty, Empty, Empty, Empty) -> something.
Since length is fixed, prefer arrays over lists: they use less memory and are faster to read and write.
I'm afraid you will need to write a function to get diagonals, there is no simple pattern matching.
When you write "do some operation on [a diagonal]", I assume you're thinking about a function f that takes an array of length 4 storing the elements, for instance [|Empty;Empty;Empty;Empty|].
Maybe f could instead take as arguments the position p, and an array of indices inside the position:
f p [|x1,y1; x2,y2; x3,y3; x4,y4|] would extract the squares p.(x1).(y1) ... p.(x4).(y4). Then just pass different x's and y's to make f operate on row/columns/diagonals.
Once the code is working and you're turning to optimization, you might want to have a look at bitvectors:
if there are a lot of positions stored in the tree of you minmax search, reducing the memory footprint means more cache hits and faster execution. You might event want to encode a position in a single int yourself, but this is some tricky work, you don't want to do it too early.
Sometimes matching doesn't work. Here, I think you should try to use functions as much as possible, and then getting your cells row first or column first won't be that complex, and you could even move from one representation to the other by reversing the indices order.
If I use the following type:
type color = Red | Yellow;;
type cell = Empty | Color of color;;
type board = Array.make 4 (Array.make 4 Empty);;
and decide for column first, then the following functions will get me rows or columns:
let column (b: board) i j = b.(i).(j)
let row (b: board) i j = b.(j).(i)
For the diagonals, there are 2 sets of them, one going top-left toward down-right, and the other one in the other direction (top-right to bottom-left):
let ldiag (b: board) i j = b.((i + j) mod 4).(j)
let rdiag (b: board) i j = b.((i - j + 4) mod 4).(j)
Then I guess that checking a row, column, or diagonal is just a matter of checking the 4 cells of that line.
let check predicate linef k = predicate (linef b k 0) &&
predicate (linef b k 1) &&
predicate (linef b k 2) &&
predicate (linef b k 3)
then for instance, checking if there's a diagonal of red:
let has_line linef b color =
let cmp x = x = color in
let check k = check cmp linef b k in
check 0 || check 1 || check 2 || check 3
let has_ldiag b color = has_line ldiag b color
let has_rdiag b color = has_line rdiag b color
let has_red_diagonal b = has_ldiag b Red | has_rdiag b Red
Etc.
How about indexing your tiles with the corresponding coordinate? So, the elements on your one-d list would be of the form:
(int * int * ref tile)
Then you can filter rows / columns / diagonals like this:
Row n: (precondition: 0 <= n, u, v <= 3)
List.filter tiles (fun x -> match x with (u, v, _) -> u = n);;
Column n: (precondition: 0 <= n, u, v <= 3)
List.filter tiles (fun x -> match x with (u, v, _) -> v = n);;
Diagonal 1: (precondition: 0 <= u, v <= 3)
List.filter tiles (fun x -> match x with (u, v, _) -> u = v);;
Diagonal 2: (precondition: 0 <= u, v <= 3)
List.filter tiles (fun x -> match x with (u, v, _) -> u + v = 3);;
It should also be possible to index the tiles with just one integer (the index of the tile within the one-d list), but that would need some calculations in the filter function (given index, figure out the coordinate and then decide if it belongs to the desired row / column / diagonal).