The Pattern
You are given only the side length of a square:
- The side length is ALWAYS = ODD.
- The middle of the square's value ALWAYS = 0.
- Every other value = distance from the center of the square.
Write a program that generalizes this algorithm and creates a list representation of the input square by outputting a List of Lists
Example Output
"""
if input = 1
Matching square: 0 => List Equivalent = [[0]]
if input = 3
Matching square: 1 1 1 => List Equivalent = [[1, 1, 1],
1 0 1 [1, 0, 1],
1 1 1 [1, 1, 1]]
if input = 5
Matching square: 2 2 2 2 2 => List Equivalent = [[2, 2, 2, 2, 2],
2 1 1 1 2 [2, 1, 1, 1, 2],
2 1 0 1 2 [2, 1, 0, 1, 2],
2 1 1 1 2 [2, 1, 1, 1, 2],
2 2 2 2 2 [2, 2, 2, 2, 2]]
if input = 7
Matching square: 3 3 3 3 3 3 3 => List Equivalent = [[3, 3, 3, 3, 3, 3, 3],
3 2 2 2 2 2 3 [3, 2, 2, 2, 2, 2, 3],
3 2 1 1 1 2 3 [3, 2, 1, 1, 1, 2, 3],
3 2 1 0 1 2 3 [3, 2, 1, 0, 1, 2, 3],
3 2 1 1 1 2 3 [3, 2, 1, 1, 1, 2, 3],
3 2 2 2 2 2 3 [3, 2, 2, 2, 2, 2, 3],
3 3 3 3 3 3 3 [3, 3, 3, 3, 3, 3, 3]]
"""
I'm tryin a solution that I will post that splits the square unevenly about 0 like so:
side = 5 _ _ _ _ _ _
Matching square: 2 2 2 2 2 Split square: 2 1 0 1 2
2 1 1 1 2 2 1 1 1 2
2 1 0 1 2 2 2 2 2 2
2 1 1 1 2
2 2 2 2 2
And figure out how to generate each row based on its distance from the top row etc
Question
Any existing solutions to this kind of pattern / problem that I'm trying to solve? I do not know what to search
CodePudding user response:
One relatively easy but not elegant way to do it is to spiral the matrix from the outside to the inside and decrement the value for each new cycle. As follows:
def create_matrix(n):
curr = n // 2
matrix = [[0]*n for _ in range(n)]
counter = 0
N = n*n
left, right, top, bottom = 0, n-1, 0, n-1
while True:
# top
for i in range(left, right 1):
matrix[top][i] = curr
counter = 1
top = 1
if counter >= N:
break
# right
for i in range(top, bottom 1):
matrix[i][right] = curr
counter = 1
right -= 1
if counter >= N:
break
# bottom
for i in range(left, right 1):
matrix[bottom][i] = curr
counter = 1
bottom -= 1
if counter >= N:
break
# left
for i in range(top, bottom 1):
matrix[i][left] = curr
counter = 1
left = 1
if counter >= N:
break
curr -= 1
return matrix
A quick test:
In [2]: create_matrix(11)
Out[2]:
[[5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
[5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5],
[5, 4, 3, 3, 3, 3, 3, 3, 3, 4, 5],
[5, 4, 3, 2, 2, 2, 2, 2, 3, 4, 5],
[5, 4, 3, 2, 1, 1, 1, 2, 3, 4, 5],
[5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5],
[5, 4, 3, 2, 1, 1, 1, 2, 3, 4, 5],
[5, 4, 3, 2, 2, 2, 2, 2, 3, 4, 5],
[5, 4, 3, 3, 3, 3, 3, 3, 3, 4, 5],
[5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5],
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]]
In [3]: create_matrix(5)
Out[3]:
[[2, 2, 2, 2, 2],
[2, 1, 1, 1, 2],
[2, 1, 0, 1, 2],
[2, 1, 1, 1, 2],
[2, 2, 2, 2, 2]]
CodePudding user response:
Solved in a much simpler way
square_size = 11
centre_x = (square_size - 1) // 2
centre_y = (square_size - 1) // 2
matrix = []
for x in range(square_size):
row = []
for y in range(square_size):
x_dif = abs(x - centre_x)
y_dif = abs(y - centre_y)
value = max(x_dif, y_dif)
row.append(value)
matrix.append(row)