Home > Software engineering >  How to create a concentric pattern with numbers
How to create a concentric pattern with numbers

Time:02-10

Here is what I did:

n= 11
size=3 4*(n-1)
for i in range(1,12):
    for j in range(1,12):
        if i==1 or i==n or j==1 or j==n:
            print("1", end="")
        else:
            print(" ", end="")
    print()

n=7
for i in range(1,8):
    for j in range(1,8):
        if i == 1 or i == n or j == 1 or j == n:
            print("2", end="")
        else:
            print(" ", end="")
    
    print()

n=3
for i in range(1,4):
    for j in range(1,4):
        if i == 1 or i == n or j == 1 or j == n:
            print("3", end="")
        else:
            print(" ", end="")
    print()

Output

11111111111
1         1
1         1
1         1
1         1
1         1
1         1
1         1
1         1
1         1
11111111111
2222222
2     2
2     2
2     2
2     2
2     2
2222222
333
3 3
333

It printed all the squares separately but I'm trying to put them all together from the smallest to the largest square. How do I do that?

CodePudding user response:

You can use the chessboard distance to the center to compute the squares. This works only for odd n

n = 11
m = n // 2
for i in range(n):
    for j in range(n):
        e = max(abs(m - i), abs(m - j))
        print(' ' if (e m)%2 else (m-e)//2 1, end='')
    print()

Output

11111111111
1         1
1 2222222 1
1 2     2 1
1 2 333 2 1
1 2 3 3 2 1
1 2 333 2 1
1 2     2 1
1 2222222 1
1         1
11111111111

CodePudding user response:

You could progressively build a list of lists containing the numbers. Start with the central number and, for each smaller number add a row of repeated numbers on top and at the bottom, then add a column of repeated numbers before and after the existing content:

Then print the list of lists (without separating spaces)

n = 5
m = [[n]]                         # start with single number at center
for i in range(n-1,0,-1):         # go through smaller numbers (4,3,2,1)
    m.insert(0,[i]*len(m[0]))        # add row on top
    m.append([i]*len(m[0]))          # add row at bottom
    m = [ [i,*row,i] for row in m ]  # add column left and right

for row in m:
    print(*row,sep="")   # print each line without separating spaces
    
111111111
122222221
123333321
123444321
123454321
123444321
123333321
122222221
111111111

Alternatively you could print as you go by iterating from 1 up to n then back down to 1. This can be achieved in a single for-loop by starting at 1-n and going up to n. Taking n-abs(i) will give you the up and down progressions. Printing the appropriate numbers on each line only takes a bit of math. You will have an increasing set of digits on the left side and the same set of digits in decreasing order on the right side. The two sides will surround a middle part made of a repeating digit corresponding to the top or bottom edge of an inner square.

n = 5
for i in range(1-n,n):
    side   = "".join(map(str,range(1,n-abs(i))))
    middle = str(n-abs(i))*(abs(i)*2 1)
    print(side   middle   side[::-1])

            i   n-abs(i)  side    abs(i)*2 1   middle     side[::-1]
111111111  -4   1         ""      9          "111111111"       ""
122222221  -3   2         "1"     7           "2222222"       "1"
123333321  -2   3         "12"    5            "33333"       "21"
123444321  -1   4         "123"   3             "444"       "321"
123454321   0   5         "1234"  1              "5"       "4321"
123444321   1   4         "123"   3             "444"       "321"
123333321   2   3         "12"    5            "33333"       "21"
122222221   3   2         "1"     7           "2222222"       "1"
111111111   4   1         ""      9          "111111111"       ""

If you want some spacing between the layers, you'll have to print spacers before or after each line and separate numbers on the sides with spaces as well. The middle parts will be twice as wide.

n = 5
for i in range(1-n,n):
    side   = " ".join(map(str,range(1,n-abs(i))))   " "*(abs(i)<n-1)
    middle = str(n-abs(i))*(abs(i)*4 1)
    edge   = side   middle   side[::-1]
    spacer = edge.replace(middle[0]," ")
    if i<=0: print(spacer)                # spacer before
    print(edge)                           # top/bottom edge
    if i>=0: print(spacer)                # spacer after

11111111111111111
1               1
1 2222222222222 1
1 2           2 1
1 2 333333333 2 1
1 2 3       3 2 1
1 2 3 44444 3 2 1
1 2 3 4   4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4   4 3 2 1
1 2 3 44444 3 2 1
1 2 3       3 2 1
1 2 333333333 2 1
1 2           2 1
1 2222222222222 1
1               1
11111111111111111

Note that all these solutions will only fork for single digit values of n (from 1 to 9)

  •  Tags:  
  • Related