2
\$\begingroup\$

I am solving interview questions from here.

Problem : Print concentric rectangular pattern in a 2d matrix. The outermost rectangle is formed by A, then the next outermost is formed by A-1 and so on. You will be given number as an argument to the function you need to implement, and you need to return a 2D array.

Example 1: Input: A = 4.

        Output:      

        4 4 4 4 4 4 4 
        4 3 3 3 3 3 4 
        4 3 2 2 2 3 4 
        4 3 2 1 2 3 4 
        4 3 2 2 2 3 4 
        4 3 3 3 3 3 4 
        4 4 4 4 4 4 4 

How can I make this code better?

def pretty_print(num):

    m = n = 2*num -1 ##    m x n matrix , length of each row and column
    k = 0 # row start counter
    l = 0 # column start counter
    i = 0 # iterator

    matrix = [[0 for _ in range(n)] for _ in range(m)]

    while k < m and l < n :  
        #insert the first row
        for i in range(l, n) :      
            if matrix[k][i] == 0:
                matrix[k][i] = num   # row index constt, change values in columns

        k += 1   # first row printed, so increment row start index

        #insert the last column
        for i in range(k, m) :         
            if matrix[i][n-1]==0:
                matrix[i][n-1] = num   # column index constt, change values in rows
        n -= 1   # last column printed, so decrement num of columns

        #insert the last row
        if (k<m):   #  if row index less than number of rows remaining
            for i in range(n-1, l-1, -1):
                if matrix[m-1][i] == 0:
                    matrix[m-1][i] = num   # row index constt, insert in columns
        m -= 1   # last row printed, so decrement num of rows

        #insert the first column
        if (l<n):    #  if column index less than number of columns remaining
            for i in range(m-1, k-1, -1):
                if matrix[i][l] == 0:
                    matrix[i][l] = num # column index constt, insert in rows
        l += 1      # first column printed, so increment column start index

        num -= 1    # all elements of value A inserted , so decrement

    return matrix

print pretty_print(6)
\$\endgroup\$
3
\$\begingroup\$

Simplify

I find the logic a bit complicated. It could be simpler:

  • Loop from -A to +A, let's call the loop variable n
  • Take the absolute value of n
  • Generate the values in the row:
    • Loop from -A to +A, let's call the loop variable m
    • Use the maximum of abs(n) + 1 and abs(m) + 1

Like this:

def pretty_print(num):
    def print_line(n):
        low = abs(n)
        print(' '.join(str(max(low + 1, abs(i) + 1)) for i in range(-num + 1, num)))

    for i in range(-num + 1, num):
        print_line(i)

Testing

Doctests are awesome, I recommend to use them. Here's the complete solution with doctests, you can run this with python -mdoctest pretty_print.py:

#!/usr/bin/env python


def pretty_print(num):
    """
    >>> pretty_print(1)
    1

    >>> pretty_print(2)
    2 2 2
    2 1 2
    2 2 2

    >>> pretty_print(6)
    6 6 6 6 6 6 6 6 6 6 6
    6 5 5 5 5 5 5 5 5 5 6
    6 5 4 4 4 4 4 4 4 5 6
    6 5 4 3 3 3 3 3 4 5 6
    6 5 4 3 2 2 2 3 4 5 6
    6 5 4 3 2 1 2 3 4 5 6
    6 5 4 3 2 2 2 3 4 5 6
    6 5 4 3 3 3 3 3 4 5 6
    6 5 4 4 4 4 4 4 4 5 6
    6 5 5 5 5 5 5 5 5 5 6
    6 6 6 6 6 6 6 6 6 6 6
    """

    def print_line(n):
        low = abs(n)
        print(' '.join(str(max(low + 1, abs(i) + 1)) for i in range(-num + 1, num)))

    for i in range(-num + 1, num):
        print_line(i)

pretty_print(6)

Style

There are some minor style issues with the posted code. I suggest to follow the PEP8 guidelines.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.