Python program to print the pattern 1 121 12321 12 1 for n rows

Viewed 6018

When n = 5 the pattern must be:

    1
   121
  12321
   121
    1

What I tried till now:

# Pattern 1-121-12321 pyramid pattern

# Reading number of rows
row = int(input('Enter how many lines? '))

# Generating pattern
for i in range(1,row+1):
    
    # for space
    for j in range(1, row+1-i):
        print(' ', end='')
    
    # for increasing pattern
    for j in range(1,i+1):
        print(j, end='')
    
    # for decreasing pattern 
    for j in range(i-1,0,-1):
        print(j, end='')
    
    # Moving to next line
    print()

Output I am getting:

    1
   121
  12321
 1234321
123454321

I know the logic for similar such patterns like:

    *
   ***
  *****
 *******

But the number pattern seems to be confusing and I am not able to get the logic.

TL;DR

Python Program for generating the following Pattern for printing n rows:

eg. When n=7:

   1
  121
 12321
1234321
 12321
  121
   1 
7 Answers

How about this code:

for i in range(n):
    temp = 0 # Store the value of the number to square (so 1, 11,...)
    if (i < n / 2):
        for j in range(i + 1):
            temp += 10 ** j # Construct the number (1 = 1, 11 = 1 + 10, 111 = 1 + 10 + 10 ^ 2,...)
        for _ in range(int(n / 2 - i)):
            print(' ', end = '') # Add space indentation
    else:
        for j in range(n - i): # Count in reverse now
            temp += 10 ** j # Construct the number (1 = 1, 11 = 1 + 10, 111 = 1 + 10 + 10 ^ 2,...)
        for _ in range(int(i - n / 2) + 1):
            print(' ', end = '') # Add space indentation
    print(temp ** 2) # Square the temporary value

(Fun mathematical fact: the string you print have a property of:
1 = 1 ^ 2; 121 = 11 ^ 2; 12321 = 111 ^ 2;...)

I will also give my suggestion. So here I initially just outsource the production of the line into a method. I first calculate the length of the current line and depending on the maximum number of lines you want to print determine the padding to get this star shape. Then I produce the actual string, which is dependent on the middle point of the string, so as soon as I exceed this, I decrease the numbering again.

from math import ceil
def produce_line(line, maximum):
    middle = ceil(maximum / 2)
    padding = abs(middle - line)
    line_width = maximum - 2 * padding
    half_lw = ceil(line_width / 2)
    res = (" " * padding) + "".join([str(a) if a <= half_lw else str(abs(2 * half_lw - a)) for a in range(1, line_width + 1)])
    return res
    
lines = 9
for i in range(1, lines + 1):
    print(produce_line(i, lines))

You could add an if statement and start from a count with a new variable c:

row = int(input('Enter how many lines? '))
c = row // 2
for i in range(1,row+1):
    if i <= (row // 2 + 1):    
        # for space
        for j in range(1, row+1-i):
            print(' ', end='')
        
        # for increasing pattern
        for j in range(1,i+1):
            print(j, end='')
        
        # for decreasing pattern 
        for j in range(i-1,0,-1):
            print(j, end='')
    else:
        for j in range(1, i):
            print(' ', end='')
        
        # for increasing pattern
        for j in range(1, c):
            print(j, end='')
        
        # for decreasing pattern 
        for j in range(c, 0, -1):
            print(j, end='')
        c -= 1
        
        # Moving to next line
    print()

Output:

Enter how many lines? 7
      1
     121
    12321
   1234321
    12321
     121
      1

Here is a short solution with a single loop an without test, it generates the range/string only once, all the rest is calculating the indices and slicing:

n = 5

n2 = (n+3)//2                      # half length +1 e.g. 4 for n=5
s = ''.join(map(str,range(1, n2))) # generate '123' for n=5

for i in range(n):
    stop = n//2-abs(i-n//2)        # calculate length of half-string 0,1,2,1,0 for n=5
    S = s[:stop+1]                 # slice string
    print(S.rjust(n2)+S[-2::-1])   # print line e.g. '123' + '21'

output:

   1
  121
 12321
  121
   1

You can try it:

for i in range(1, row+1):
    if i > (row+1)/2:
        i = (row+1)-i
    # for space
    for j in range(1, row+1-i):
        print(' ', end='')

    # for increasing pattern
    for j in range(1, i+1):
        print(j, end='')

    # for decreasing pattern
    for j in range(i-1, 0, -1):
        print(j, end='')

    # Moving to next line
    print()

input:

9

output:

        1
       121
      12321
     1234321
    123454321
     1234321
      12321
       121
        1

input:

7

output:

      1
     121
    12321
   1234321
    12321
     121
      1

You can also try to simplify the problem be writing a function to get one line. And when you have that working, calling this for each line.

def create_line(number, spaces):
    return ''.join([' ' for s in range(spaces)] + 
        [str(x) for x in range(1, number)] + 
        [str(x) for x in range(number, 0, -1)] +
        [' ' for s in range(spaces)])

def print_pattern(n):
    highest_number = (n + 1) // 2
    for line_no in range(1, n + 1):
        print(create_line(highest_number -  abs(highest_number - line_no), 
              abs(highest_number - line_no)))

row = int(input('Enter how many lines? '))
print_pattern(row)

With the same approach you have taken if you have divided the problem into two as first half and second half you can generate the pattern easily with your initial approach. I have provided an easy way to break your problem like below.

# Reading number of rows
row = int(input('Enter how many lines? '))


def firsthalf(rows):
    for i in range(1, rows + 1):

        # for space
        for j in range(1, rows + 1 - i):
            print(' ', end='')

        # for increasing pattern
        for j in range(1, i + 1):
            print(j, end='')

        # for decreasing pattern
        for j in range(i - 1, 0, -1):
            print(j, end='')

        # Moving to next line
        print()


def bottomHalf(rows):
    for i in range(rows, 0, -1):

        # for space
        for j in range(1, rows + 2 - i):
            print(' ', end='')

        # for increasing pattern
        for j in range(1, i + 1):
            print(j, end='')

        # for decreasing pattern
        for j in range(i - 1, 0, -1):
            print(j, end='')
  
def pattern(rows):
    firsthalf((rows // 2) + 1)
    bottomHalf(rows // 2)


pattern(row)
 
Related