so the assignment is: write a func that gets N ( int greater than 0 ) and return a 2d array of 1's where a path of 0 makes a diamond. the length of each diamond line(1 of 4 lines) is of length N. cannot use loops list comps or recursion.
i will add my own solution but I don't think it is very numpy oriented.. please note that my solution was originally for a diamond of 1's in a 0 matrix so it might look a bit odd
example: n=1
np.array([[0]])
n=2:
np.array([[1,0,1],[0,1,0],[1,0,1]])
n=3
np.array([[1,1,0,1,1],[1,0,1,0,1],[0,1,1,1,0],[1,0,1,0,1],[1,1,0,1,1]])
My Solution:
if n == 1:
finalMatrix = np.array([[0]])
return finalMatrix
rawMatrix = np.ones((2 * n - 1, 2 * n - 1))
midRowDiag = np.eye(2 * n - 1, k=n - 1)
midColDiag = np.eye(2 * n - 1, k=-(n - 1))
tempMatrix = rawMatrix - midRowDiag - midColDiag
halfMatrix = tempMatrix[::, n:]
# print(halfMatrix)
# Making the quarters
topRightQuart = halfMatrix[:n - 1, 0:n - 1]
topLeftQuart = np.fliplr(topRightQuart)
botLeftQuart = np.flipud(topLeftQuart)
botRightQuart = np.flipud(topRightQuart)
midCol = tempMatrix[:, n - 1]
midRow = tempMatrix[n - 1, :]
# Adding them all up
finalMatrix = np.zeros((2 * n - 1, 2 * n - 1))
finalMatrix[:, n - 1] = midCol
finalMatrix[n - 1, :] = midRow
finalMatrix[0:n - 1, 0:n - 1] = topLeftQuart
finalMatrix[0:n - 1, n:] = topRightQuart
finalMatrix[n:, 0:n - 1] = botLeftQuart
finalMatrix[n:, n:] = botRightQuart
finalMatrix[n - 1, n - 1] = 1
return finalMatrix
CodePudding user response:
arr = np.diagflat([1,1],1)
arr = np.maximum(arr,np.flip(arr,0))
arr = np.maximum(arr,np.flip(arr,1))
arr = np.where((arr==0)|(arr==1), arr^1, arr)
As per my understanding you are looking to make diamonds write. This is an example for 3x3 one for 5x5 the code is underneath
arr = np.diagflat([1,1,1],2)
arr = np.maximum(arr,np.flip(arr,0))
arr = np.maximum(arr,np.flip(arr,1))
arr = np.where((arr==0)|(arr==1), arr^1, arr)
so for n needs to be a odd number and n=odd number
list of 1 len = n//2 1
and the second parameter in np.diagflat
will be n//2
. This is important to use // or you can simply divide and round it off
if n is the length of diagonal then the second parameter will be n-1
CodePudding user response:
This pattern looks similar to a Toeplitz matrix. You can implement this using scipy.linalg.toeplitz
:
>>> p = np.array([1,1,0,1,1])
>>> T = toeplitz(p, p)
Notice the layout of T
:
array([[1, 1, 0, 1, 1],
[1, 1, 1, 0, 1],
[0, 1, 1, 1, 0],
[1, 0, 1, 1, 1],
[1, 1, 0, 1, 1]])
We can horizontally flip it (np.fliplr
) and point-wise multiply with itself:
>>> T*np.fliplr(T)
array([[1, 1, 0, 1, 1],
[1, 0, 1, 0, 1],
[0, 1, 1, 1, 0],
[1, 0, 1, 0, 1],
[1, 1, 0, 1, 1]])
Minimal implementation:
def diamond(n):
pad = (1,)*(n-1)
p = np.array(pad (0,) pad)
T = toeplitz(p, p)
return np.fliplr(T)*T
Then:
>>> diamond(1)
array([[0]])
>>> diamond(2)
array([[1, 0, 1],
[0, 1, 0],
[1, 0, 1]])
>>> diamond(3)
array([[1, 1, 0, 1, 1],
[1, 0, 1, 0, 1],
[0, 1, 1, 1, 0],
[1, 0, 1, 0, 1],
[1, 1, 0, 1, 1]])