I have to create a Sudoku grid with the following pattern in C:
1 2 3 4
3 4 1 2
2 3 4 1
4 1 2 3
The first number in the top left corner (here: 1) must be an editable variable for a start value. There is another variable to create the grid with by the square size, in this example the square size is 2 and the 1 2 3 4 are in one square. 3 4 1 2 are in another square and so on...
If the start value is e.g. 3, the grid looks like this:
3 4 1 2
1 2 3 4
4 1 2 3
2 3 4 1
I noticed that there is a pattern: If the row number is odd, the new start value of the next row is the second last one. If the row number is even, the new start value of the next row is the last one. I tried to do it in C, but the even rows are cloning themselves. Note that arrays and pointers are not allowed here, only loops and other control-structures.
I tried the following approach, but the even rows are cloning themselves:
#include <stdio.h>
const int intSquareSize = 2;
const int intFieldLength = intSquareSize * intSquareSize;
int intStartValue = 3;
int main() {
int a = 0;
int b = 0;
int m = 0;
for (int intRowCounter = 1; intRowCounter <= intFieldLength; intRowCounter++) {
m = intFieldLength - 1;
for (int intColumnCounter = 1; intColumnCounter <= intFieldLength; intColumnCounter++) {
a = intStartValue + (intColumnCounter - 1);
b = a;
if (a > intFieldLength) {
a = intFieldLength - m;
m--;
}
if (intRowCounter % 2 == 0 && intColumnCounter == intFieldLength) {
intStartValue = a;
} else if (intRowCounter % 2 == 1 && intColumnCounter == (intFieldLength - 1)) {
intStartValue = b;
}
printf("%d\t", a);
}
printf("\n");
}
return 0;
}
What did I wrong and how can I fix it?
If the row number is odd, the new start value of the next row is the second last one. If the row number is even, the new start value of the next row is the last one.
I don't think it is helpful to think in terms of odd and even. The involved numbers are just symbols, and one could even replace them with distinct colors (for example). Odd/even is not a significant thing here, and it would certainly not play the same role in other board sizes.
The pattern I see is this:
In the first intSquareSize rows, the values shift horizontally (compared to the previous row) by intSquareSize. For example with intSquareSize=3 the first three rows could be:
3 4 5 6 7 8 9 1 2
6 7 8 9 1 2 3 4 5
9 1 2 3 4 5 6 7 8
Notice the shift of 3 positions to the left at each next row.
Then the pattern for the next chunks of intSquareSize rows would be the same, but with one shift. So the complete 9x9 sudoku would look like this:
3 4 5 6 7 8 9 1 2
6 7 8 9 1 2 3 4 5
9 1 2 3 4 5 6 7 8
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
1 2 3 4 5 6 7 8 9
5 6 7 8 9 1 2 3 4
8 9 1 2 3 4 5 6 7
2 3 4 5 6 7 8 9 1
This is just one possible pattern you could follow. There could be others. But the following code will apply the above logic. Note I used your variables, but I prefer to use 0-based logic, so loop variables start at 0, and the value of a is also 0-based. Only at the time of printing 1 is added to that value, so it becomes 1-based:
int a = intStartValue - 1; // Move from 1-based to 0-based
for (int intBlockCounter = 0; intBlockCounter < intSquareSize; intBlockCounter++) {
for (int intRowCounter = 0; intRowCounter < intSquareSize; intRowCounter++) {
for (int intColumnCounter = 0; intColumnCounter < intFieldLength; intColumnCounter++) {
printf("%d\t", (a + 1)); // back to 1-based
a = (a + 1) % intFieldLength;
}
printf("\n");
a = (a + intSquareSize) % intFieldLength; // Shift within a block
}
a = (a + 1) % intFieldLength; // Shift between blocks
}
Lets say I have a 4 dimensional matrix, from which I would like to retrieve the maximum values over the 2nd and 3rd dimension.
A = rand(4, 4, 4, 4);
[max_2, in_2] = max(A, [], 2);
[max_3, in_3] = max(max_2, [], 3);
How could I use ind_2 and ind_3 to obtain a logical 4 dimensional matrix, where a 1 entry means this entry is maximum in the 2nd and 3rd dimension?
I would use this approach:
A = rand(4, 4, 4, 4); % example data
B = permute(A, [1 4 2 3]); % permute dims 2 and 3 to the end
B = reshape(B, size(A,1), size(A,4), []); % collapse last two dims
C = bsxfun(#eq, B, max(B, [], 3)); % maximize over collapsed last dim
C = reshape(C, size(A,1), size(A,4), size(A,2), size(A,3)); % expand dims back
C = permute(C, [1 3 4 2]); % permute dims back. This is the final result
Here's an approach working with linear indices and uses argmax indices from max function, so it would only consider the first argmax in case of ties for the max value -
% Get size parameters
[m,n,p,q] = size(A);
% Reshape to merge second and third dims
[~, in_23] = max(reshape(A,m,[],q), [], 2);
% Get linear indices equivalent that could be mapped onto output array
idx1 = reshape(in_23,m,q);
idx2 = bsxfun(#plus,(1:m)', m*n*p*(0:q-1)) + (idx1-1)*m;
% Initialize output array an assign 1s at linear indices from idx2
out = false(m,n,p,q);
out(idx2) = 1;
Explanation with a sample
1) Input array :
>> A
A(:,:,1,1) =
9 8
9 1
A(:,:,2,1) =
2 9
8 1
A(:,:,1,2) =
1 7
8 1
A(:,:,2,2) =
8 5
9 7
2) Reshape array for a better visualization :
>> reshape(A,m,[],q)
ans(:,:,1) =
9 8 2 9
9 1 8 1
ans(:,:,2) =
1 7 8 5
8 1 9 7
3) The question is to take max value from each of the rows. For that, we had idx2 as the linear indices :
>> idx2
idx2 =
1 13
2 14
Looking back at the reshape version, thus we chose (bracketed ones) -
>> reshape(A,m,[],q)
ans(:,:,1) =
[9] 8 2 9
[9] 1 8 1
ans(:,:,2) =
1 7 [8] 5
8 1 [9] 7
So, looking closely, we see that for the first row, we had two 9s, but we are choosing the first one only.
4) Finally, we are assigning these into the output array initialized as logical zeros :
>> out
out(:,:,1,1) =
1 0
1 0
out(:,:,2,1) =
0 0
0 0
out(:,:,1,2) =
0 0
0 0
out(:,:,2,2) =
1 0
1 0
Let say I have 3 MATs
X = [ 1 3 9 10 ];
Y = [ 1 9 11 20];
Z = [ 1 3 9 11 ];
Now I would like to find the values that appear only once, and to what array they belong to
I generalized EBH's answer to cover flexible number of arrays, arrays with different sizes and multidimensional arrays. This method also can only deal with integer-valued arrays:
function [uniq, id] = uniQ(varargin)
combo = [];
idx = [];
for ii = 1:nargin
combo = [combo; varargin{ii}(:)]; % merge the arrays
idx = [idx; ii*ones(numel(varargin{ii}), 1)];
end
counts = histcounts(combo, min(combo):max(combo)+1);
ids = find(counts == 1); % finding index of unique elements in combo
uniq = min(combo) - 1 + ids(:); % constructing array of unique elements in 'counts'
id = zeros(size(uniq));
for ii = 1:numel(uniq)
ids = find(combo == uniq(ii), 1); % finding index of unique elements in 'combo'
id(ii) = idx(ids); % assigning the corresponding index
end
And this is how it works:
[uniq, id] = uniQ([9, 4], 15, randi(12,3,3), magic(3))
uniq =
1
7
11
12
15
id =
4
4
3
3
2
If you are only dealing with integers and your vectors are equally sized (all with the same number of elements), you can use histcounts for a quick search for unique elements:
X = [1 -3 9 10];
Y = [1 9 11 20];
Z = [1 3 9 11];
XYZ = [X(:) Y(:) Z(:)]; % one matrix with all vectors as columns
counts = histcounts(XYZ,min(XYZ(:)):max(XYZ(:))+1);
R = min(XYZ(:)):max(XYZ(:)); % range of the data
unkelem = R(counts==1);
and then locate them using a loop with find:
pos = zeros(size(unkelem));
counter = 1;
for k = unkelem
[~,pos(counter)] = find(XYZ==k);
counter = counter+1;
end
result = [unkelem;pos]
and you get:
result =
-3 3 10 20
1 3 1 2
so -3 3 10 20 are unique, and they appear at the 1 3 1 2 vectors, respectively.
I have a 2-D array in which I have to calculate the sum of the neighbours of each element, wrapping around margins and corners.
So, if we had the matrix:
1 2 3
4 5 6
7 8 9,
computing the sum of the neighbours of the last element at position (2, 2):
neighSum(A[2][2]) = 8 + 5 + 6 + 4 + 7 + 1 + 3 + 2
The way I want to implement this is by adding outside borders to the matrix. There's no point in explaining because it would take a lot longer than a visual example, so building upon the previous one, the matrix becomes:
7 8 9
3 1 2 3 1
6 4 5 6 4
9 7 8 9 7
1 2 3
For the corners, there is a catch however. The matrix is considered to be a toroid, which is a geometric shape that has the form of a donut. Think of it as taking the original matrix, wrapping it around a vertical cylinder, and then wrapping it around a horizontal cylinder. This operation makes all the corners be neighbours and we just have to fill in what is left after adding borders.
9 7 8 9 7
3 1 2 3 1
6 4 5 6 4
9 7 8 9 7
3 1 2 3 1
So far I have come up with this algorithm, which pretty much works fine, except for the rightmost column, or so I think. It is behaving strangely, sometimes overwriting some of the values in the right border, sometimes the ones in the left border as well
/* Copy the original matrix to the bordered one */
for (i = 1; i < N + 1; i++)
{
for (j = 1; j < M + 1; j++)
{
B[i][j] = A[i][j];
}
}
/* Add the left and right borders */
for(i = 1; i < M + 1; i++)
{
B[0][i] = B[N][i];
B[N+1][i] = B[1][i];
}
/* Add the top and down borders */
for(j = 1; j < N+1; j++)
{
B[i][0] = B[i][M];
B[i][M+1] = B[i][1];
}
/* Mirror the corners */
B[0][0] = B[N][M];
B[M+1][N+1] = B[1][1];
B[N+1][0] = B[1][M];
B[0][M+1] = B[N][1];
Your last loop iterator is 'j' but you use 'i' to index elements.
If I have a 4x4 gameboard which I'm representing in my program as a 1d integer array of size 16.
How can I get the indexs of the squares above, below, to the left and to the right any given index?
So, for example:
A = { 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 }
Which represents this board
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
Lets say I am currently on index #8 in the board (value = 7). How can I get the index for 4 (value = 3) , 5 (value = 6), 10 (value = 11) and realize that there is no right square because it is on the right hand edge of the board.
I know I need to use some modulus math but I'm failing to come up with the right way to get the indexes for adjacent squares.
I'm thinking something like...
if ((i % 4) + 1 < 3) right = i + 1;
if ((i % 4) - 1 > 0) left = i - 1;
if ((i % 4) + 4 < 15) bottom = i + 4;
if ((i % 4) - 4 > 0 ) top = i - 4;
Does this seem like it is the right approach?
To get row,column from your index, use the following:
row = index/num_columns;
column = index % num_columns;
to get back to the index, use
index = row * num_columns + column;
One you're in rows and columns, it's easy to get the surrounding positions.
above = (row-1, column)
left = (row, column-1)
etc...