Finding the set of all winning tic tac toe board states - arrays

Here's my problem. I want to create an algorithm which generates an array of arrays of every possible winning board state for an n-dimensional tic-tac-toe board. Say you have an n = 2 board, meaning 2x2, then the function should return the following array:
wins = [
[1,2],
[1,3],
[1,4],
[2,4]
]
I know this isn't specifically a MATLAB problem, however I'm trying to expand my understanding of how MATLAB works. My general idea is an algorithm that does the following:
generate an n-dimensional board of zeros
1. Go to the first cell, record that index ([1,])
2. Go to the end of the row, and that's your first board state ([1,2])
3. Go to the end of the column, that's your second board state ([1,3])
4. Go to the end of the diagonal, that's your third board state ([2,3])
5. Advance to the next cell, repeat, checking if you have already created that board state first ([2,4] should be the only one it hasn't done)
I think I'm overthinking the problem, but I'm not sure how to approach it. Can someone give me some guidance how to do this in a MATLAB-y way? My guess is that traversing the matrix and just picking whole rows/colums/diagonals is easy, it's the 'checking if it exists' part that I'm not getting. How would you call this algorithm, in general? Thanks for any help!

Better idea: you don't do this square by square, you do this by dimension. For each dimension on the board, you have these possibilities for the coordinate to vary or not through winning combinations:
iterate through all the possible values, low to high
iterate through all the possible values, high to low
hold constant as the other dimensions iterate, but do so for each value in range, repeating for the other coordinates.
For instance, for a 4^3 board, let's look at the last coordinate (call them x1, x2, x3), x3. Assume that you've already determined x1 will iterate low to high, x2 is constant at 2. You will now treat x3 with:
iterate through all the possible values, low to high
(1, 2, 1), (2, 2, 2), (3, 2, 3)
iterate through all the possible values, high to low
(1, 2, 3), (2, 2, 2), (3, 2, 1)
hold constant as the other dimensions iterate, but do so for each value in range, repeating for the other coordinates.
(1, 2, 1), (2, 2, 1), (3, 2, 1)
(1, 2, 2), (2, 2, 2), (3, 2, 2)
(1, 2, 3), (2, 2, 3), (3, 2, 3)
Does that get you moving?

Related

minimum operations to make array left part equal to right part

Given an even length array, [a1, a2,....,an], a beautiful array is an array where a[i] == a[i + n / 2] for 0<= i < n / 2. define an operation as change all array elements equal to value x to value y. what's the minimum operations required to make a given array beautiful? all elements are in range [1, 100000]. If simply return unmatch array pairs (ignore order) in left and right part of array, it will return wrong results in some cases such as [1, 1, 2, 5, 2, 5, 5, 2], unmatched pairs are (1, 2), (1, 5), (2, 5), but when change 2 -> 5, than (1, 2) and (1, 5) become the same. so what's the correct method to solve this problem?
It is a graph question.
For every pair(a[i], a[i+n/2]) where a[i]!=a[i+n/2], add an undirected edge between the two nodes.
Note that you shouldn't add multiple edges between 2 numbers.
Now you essentially need to remove all the edges in the graph by performing some operations. The final answer is the number of operations.
In each operation, you remove an edge. After removing an edge between two vertices, combine the vertices and rearrange their edges.

Find total number of ways possible to create an array of size M

Suppose I have M = 2 and N = 5 and K = 2 where
M = size of array
N = Maximum number that can be present as an array element
K = Minimum number that can be present as an array element.
So how do I find the number of possible ways to create an array using the above conditions. Also the current number should be not be greater than the previous element.
The arrays created using the above conditions are
[5,5],[5,4],[5,3],[5,2],[4,4],[4,3],[4,2],[3,3],[3,2],[2,2]
i.e 10 array can be created from the above conditions.
I tried doing it by using combinations and factorials, but not getting the desired output. Any help would be appreciated.
Assuming you are just interested in the number of combinations the formula is -
(N-K+M)!/(M!(N-K+1)!)
See more here
This is known as a combinations_with_replacement: combination because the order doesn't matter (or it would be a permutation), and with replacement because elements can be repeated, like [5, 5].
list(itertools.combinations_with_replacement(range(2, 6), 2))
# [(2, 2), (2, 3), (2, 4), (2, 5), (3, 3), (3, 4), (3, 5), (4, 4), (4, 5), (5, 5)]
If you want the exact ones you listed, you will have to reverse each element, and the list itself.
list(reversed([tuple(reversed(element)) for element in itertools.combinations_with_replacement(range(2,6), 2)]))

NumPy array loses dimension upon assignment/copy, why?

I have the following code:
print(type(a1), a1.shape)
a2 = a1 #.reshape(-1,1,2) this solves my problem
print(type(a2), a2.shape)
The output is:
<class 'numpy.ndarray'> (8, 1, 2)
<class 'numpy.ndarray'> (8, 2)
I know the (commented out) reshape solves my problem, however, I'd like to understand why a simple assignment results in losing the central dimension of the array.
Does anybody know what is going on? Why referring to the array with another name changes its dimensions?
Looking at the openCV script mentioned in the comments, the reshape to three dimensions is necessary because a dimension is being lost via Boolean indexing, and not by the assignment alone.
The names of the arrays in that script which motivated the question are p0 and good_new.
Here is a breakdown of the operations in that script:
p0 is a 3D array with shape (17, 1, 2).
The line:
p1, st, err = cv.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
creates new arrays, with array p1 having shape (17, 1, 2) and array st having shape (17, 1).
The assignment good_new = p1[st==1] creates a new array object by a Boolean indexing operation on p1. This is a 2D array has shape (17, 2). A dimension has been lost through the indexing operation.
The name p0 needs to be assigned back to the array data contained in good_new, but p0 also needs to be 3D. To achieve this, the script uses p0 = good_new.reshape(-1, 1, 2).
For completeness, it is worth summarising why the Boolean indexing operation in step (3) results in a dimension disappearing.
The Boolean array st == 1 has shape (17, 1) which matches the initial dimensions of p1, (17, 1, 2).
This means that the selection occurs in the second dimension of p1: the indexer array st == 1 is determining which arrays of shape (2,) should be in the resulting array. The final array will be of shape (n, 2), where n is the number of True values in the Boolean array.
This behaviour is detailed in the NumPy documentation here.
I am not sure why your are getting this.but it should not return like this.Can you please share how your a1 has been created.
I tried like below but not able to re create it
a1=np.ones((8,1,2),dtype=np.uint8)
print(type(a1), a1.shape)
<class 'numpy.ndarray'> (8, 1, 2)
a2=a1
print(type(a2), a2.shape)
<class 'numpy.ndarray'> (8, 1, 2)`

Binning then sorting arrays in each bin but keeping their indices together

I have two arrays and the indices of these arrays are related. So x[0] is related to y[0], so they need to stay organized. I have binned the x array into two bins as shown in the code below.
x = [1,4,7,0,5]
y = [.1,.7,.6,.8,.3]
binx = [0,4,9]
index = np.digitize(x,binx)
Giving me the following:
In [1]: index
Out[1]: array([1, 2, 2, 1, 2])
So far so good. (I think)
The y array is a parameter telling me how well measured the x data point is, so .9 is better than .2, so I'm using the next code to sort out the best of the y array:
y.sort()
ysorted = y[int(len(y) * .5):]
which gives me:
In [2]: ysorted
Out[2]: [0.6, 0.7, 0.8]
giving me the last 50% of the array. Again, this is what I want.
My question is how do I combine these two operations? From each bin, I need to get the best 50% and put these new values into a new x and new y array. Again, keeping the indices of each array organized. Or is there an easier way to do this? I hope this makes sense.
Many numpy functions have arg... variants that don't operate "by value" but rather "by index". In your case argsort does what you want:
order = np.argsort(y)
# order is an array of indices such that
# y[order] is sorted
top50 = order[len(order) // 2 :]
top50x = x[top50]
# now top50x are the x corresponding 1-to-1 to the 50% best y
You should make a list of pairs from your x and y lists
It can be achieved with the zip function:
x = [1,4,7,0,5]
y = [.1,.7,.6,.8,.3]
values = zip(x, y)
values
[(1, 0.1), (4, 0.7), (7, 0.6), (0, 0.8), (5, 0.3)]
To sort such a list of pairs by a specific element of each pair you may use the sort's key parameter:
values.sort(key=lambda pair: pair[1])
[(1, 0.1), (5, 0.3), (7, 0.6), (4, 0.7), (0, 0.8)]
Then you may do whatever you want with this sorted list of pairs.

Construct a decision-tree classifier with binary splits at each node?

Construct a decision-tree classifier with binary splits at each node, using tuples in relation r (A, B, C) shown below as training data; attribute C denotes the class.
Show the final tree, and with each node show the best split for each attribute along with its information gain value.
Training Data:
(1, 2, a), (2, 1, a), (2, 5, b), (3, 3, b), (3, 6, b), (4, 5, b), (5, 5, c), (6, 3, b), (6, 7, c) ?
How to proceed?
Any link will be helpful?
Have you found what algorithm (i.e. ID3) do you want to use to build your decision tree? To predict the class, you need to train your decision tree based on observations about data (i.e. features). This lilnk explains the decision tree learning.

Resources