Swift - search duplicate in multidimensional array - sudoku - arrays

I'm creating a 4x4 sudoku game in a multidimensional array filled by random generated numbers (from 1 to 4). Now I have to search duplicates and replace them with other random numbers until there are unique numbers on the single row, single column and on the four 2x2 sub-matrix.
How can I do that?
There's my code for generating the grid:
func fill (N:Int) {
for row in 0..<N {
//Append an empty row
matrix.append([Int]())
for _ in 0..<N {
//Populate the row
matrix[row].append(Int(arc4random_uniform(4)+1))
}
}
}
fill(N: 4)

You can change the array into a set(removes duplicates) and then back into an array. But your order might change.
matrix = Array(Set(matrix))

Related

N-dimensional array indexing in Matlab : find array in middle

I am working with N-dimensional array and have a problem with the array indexing. I have a task to find an (N-1)-dimensional array in the middle N-dimensional array.
Let me explain in detail with 3D array. A is a 3-dimensional array that has split into groups. In each group, there are b - number of 2-dimensional arrays in the group. I have simulated it as:
b=5;
A=rand(2,2,20);
groups = reshape(A, size(A,1), size(A,2),b, []);
groups is 4-dimensional array, the 4-th dimension is a number of groups ( here it 4).
To find a middle in each group I have added the following loop:
for ii=1:size(groups,4) % Loop over all groups/slices
middle(:,:,ii) = groups(:,:,(w-1)/2+1,ii); % 1 2 3 4 5 : the middle is 3
end
middle is 3-dimensional array that collects middle array in each group.
As you see in my example I have used b=5( odd number). My problem is with even number b.
I have tried to implement it as ( rewrite the loop above);
l=rem(w,2);
for ii=1:size(groups,4) % Loop over all groups/slices
if l==1
middle(:,:,ii) = groups(:,:,(w-1)/2+1,ii);
else
middle(:,:,ii) = groups(:,:,(w-1)/2,ii);
end
end
But it doesn't work. Matlab gives me an error in the line l=rem(w,2);
Could you suggest to me how I can fix it? Is there another way to implement it?
You should use floor of ceil to round the index to whichever element you want:
middle_index = floor((w-1)/2+1);
Here, the middle of 4 is 2, using ceil you’d pick index 3.
Next, you can extract the arrays in a single indexing operation:
middle = groups(:,:,middle_index,:);
Finally, use squeeze or reshape to get rid of the 3rd index:
middle = squeeze(middle);

Targeting specific elements of cell arrays (Matlab)

I currently have a cell array consisting of 7x1 vectors. I need to extract the first element (1,1) of each vector from each cell and store these values in a new array. This is what I currently have:
for j = 1:numel(xvalues)
cellj = xvalues{j};
a = cellj(1:1);
avalues(1:j) = a;
end
However, I am just generating a cell array with the first element of the last cell, repeating.
How can I fix this?
You can also use cellfun to apply a function to each element in a cell array. So to extract the first element of each vector the following should work.
avalues = cellfun(#(x) x(1),xvalues);
Cellfun loops through each element in the cell array and passes it in to the anonymous function via #(x). We then process x by taking the first element x(1).
In cases such as yours, where the cell contents are matrices of the same size, and assuming your inputs are small enough (meaning that neither memory nor runtime are imminent issues) you can convert the cell array into a numeric matrix and select a vector along the relevant dimension:
function out = q48740494
%% Generate some data:
c = squeeze(num2cell(randi(20,7,1,20),[1,2]));
% c = 20×1 cell array of {7x1 double}
%% Convert this into a numeric array and output:
out = cell2mat(c.'); out = out(1,:);
% BONUS: another version of the line above.
% out = subsref(cell2mat(c.'), substruct('()', {1,1:numel(c)}) ) ;

Loading 2 random numbers into an array with no duplicates

I want to generate random coordinates from 0-5 (Row,Col) without any duplicates using for loops. Basically if the numbers (3,2), (3,4), (1,4), (3,4) are generated then (3,4) will not be utilized and a new random set will be looked for.
These are the methods that generate two random numbers and loads them into the array shootP[ ]
int[] shootP = new int[2];
public static int shootRowP(int[] shootP)
{
Random rn = new Random();
shootP[0] = rn.nextInt(5)+1;//loads into ROW
System.out.print("Row:"+(shootP[0]));
return shootP[0]--;
}
public static int shootColP(int[] shootP,int[][]boardP)
{
Random rn = new Random();
shootP[1] = rn.nextInt(5)+1;//loads into Col
System.out.print(" Column:"+(shootP[1])+"/n");
return shootP[1]--;
}
I then want to have another method read in the values of shootP[0] and shootP[1] and check to see if those values were already used. Any suggestions?
Since the number of possible coordinates (X,Y) is not too large, first build a list of all possible coordinates. Then, at each random pick, choose a random element in this list (i.e. rn.nextInt(current_list_length)), remove the element from the list and return it.
Notes:
You must do something (exception?) when the list is empty
You can also shuffle your list at initialization and at each draw, you pick and delete the first (or last) element. See here how to shuffle an array, for example.
Instead of a list, a stack (an array + an element counter) can do the trick.

Extracting data from a 3D cell array into a 2D Matrix - MATLAB

I have a cell array that is three dimensional i.e. 16x10x3 and I would like for all values in :,:,1 :,:,2 and :,:,3 to be extracted into a column of a matrix each.
I thought about pre-allocating a matrix and then just running a basic loop such as:
for m=1:3
mat(:,m) = ([a{:,:,m}]);
end
Is there a more efficient way of doing this without having to rely on a loop?
EDIT: There are different numbers of values between :,:,1/2/3.
It's high time you get into bsxfun! Here's the implementation -
%// Get the number of elements in each column of the input cell array
lens = sum(cellfun('length',reshape(a,[],size(a,3))),1)
%// Store the maximum number of elements possible in any column of output array
max_lens = max(lens)
%// Setup output array, with no. of rows as max number of elements in each column
%// and no. of columns would be same as the no. of columns in input cell array
mat = zeros(max_lens,numel(lens))
%// Create as mask that has ones to the "extent" of number of elements in
%// each column of the input cell array using the lengths
mask = bsxfun(#le,[1:max_lens]',lens) %//'
%// Finally, store the values from input cell array into masked positions
mat(mask) = [a{:}]

How to remove a row from a matrix inside a cell array

I have a cell array (A) with size of 400 x 1 and each cell of this array includes a matrix with size 9 x 4. As such, it looks like this:
A={[9x4 double];[9x4 double];...;[9x4 double]};
Now, I want to remove the zero rows from these sub matrices and then obtain a new A cell array called A_new where its sub matrices don't have any zero rows like this:
A_new={[5x4 double];[7x4 double];...;[4x4 double]};
By my below code, I can find the index of rows which are not zero but I couldn't create my cell array like I mentioned above. This is my written code and for the bold part, I have a problem and I couldn't solve it.
for i=1:A_Length
[row,col]=find(A{i,1});
out=[row col];
NNZ_row=unique(row);
Length_NNZ= length(NNZ_row);
for j=1:Length_NNZ
**A_NonZero{i,1}= ??????????**
end
end
What I would do is take each cell, then use all on the opposite of the matrix over all of the columns in each row to determine which rows contain all zeroes. Once you do this, use these locations and remove those rows from this matrix and save this to your new matrix.
As such, do this:
A_new = cell(1,numel(A));
for i=1:numel(A)
mat = A{i};
ind = all(~mat, 2);
A_new{i} = mat(~ind,:);
end
The first line of code creates a new cell array that is the same size as A. Next, for each element in A, extract the matrix at each cell location, use all on the opposite of this matrix to find those elements that we need to keep, then save this new matrix into the corresponding location in A_new.
If you want to do this in a single line of code, use cellfun:
A_new = cellfun(#(x) x(~all(~x,2),:), A, 'uni', 0);
The first argument to cellfun is an anonymous function that performs what the for loop was doing. We find those rows that contain all zeroes and use those to remove the rows in each matrix in the cell array. The second argument is the matrix we want to operate on, which is A. The 'uni' and 0 flags are important because the outputs are not single values but matrices, and so the output of this function will be a cell array that is the same size as A where each element is the matrix for those corresponding locations in A with the zero rows removed.
You should use a combination of cellfun and any:
A_new = cellfun(#(x) x(any(x~=0,2),:), A, 'UniformOutput', false);
should do the trick.

Resources