1

Trying to make a matrix alphabet pattern. The desired output should look like this:

DDDDDDD
DCCCCCD
DCBBBCD
DCBABCD
DCBBBCD
DCCCCCD
DDDDDDD

I have found this solution for the matrix number pattern:

Input: 4

N = int(input('Enter N value:'))
k = (2 * N) - 1
low = 0
high = k - 1
value = N
matrix = [[0 for i in range(k)] for j in range(k)]
for i in range(N):
    for j in range(low, high + 1):
        matrix[i][j] = value
    for j in range(low + 1, high + 1):
        matrix[j][i] = value
    for j in range(low + 1, high + 1):
        matrix[high][j] = value
    for j in range(low + 1, high):
        matrix[j][high] = value

    low = low + 1
    high = high - 1
    value = value - 1

for i in range(k):
    for j in range(k):
        print(matrix[i][j], end =' ')
    print()

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 

Not sure if this matrix number pattern code is the smoothest solution.

martineau
  • 119,623
  • 25
  • 170
  • 301
Emiiri93
  • 77
  • 1
  • 6
  • 1
    You need to transform numbers in letters ? – azro Feb 11 '21 at 18:11
  • Yes and I am not sure how to do it. – Emiiri93 Feb 11 '21 at 18:14
  • 1
    Does this answer your question? [Convert numbers into corresponding letter using Python](https://stackoverflow.com/questions/23199733/convert-numbers-into-corresponding-letter-using-python) – Tomerikoo Feb 11 '21 at 18:45
  • 1
    it is the last step of my solution. `chr(64+matrix[i][j])` in your print loop gives you the ascii character you are willing for – brunoff Feb 11 '21 at 20:04
  • Thank you, for the link! It is very helpful. – Emiiri93 Feb 11 '21 at 20:13
  • 1
    Hi, as you have now answers now, you may think about [accepting an answer](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) to reward the one that gives you the most helpful comment. – azro Feb 13 '21 at 09:43

3 Answers3

1

It seems you just need to pass from digits to uppercase letters, also you don't need the extra variables low and value, just use the existing N and i

from string import ascii_uppercase # simple string of all alphabet

N = int(input('Enter N value:'))
k = (2 * N) - 1
high = k - 1
matrix = [[0 for _ in range(k)] for _ in range(k)]

for i in range(N):
    for j in range(i, high + 1):
        matrix[i][j] = N - i
    for j in range(i + 1, high + 1):
        matrix[j][i] = N - i
    for j in range(i + 1, high + 1):
        matrix[high][j] = N - i
    for j in range(i + 1, high):
        matrix[j][high] = N - i

    high = high - 1
    
for i in range(k):
    for j in range(k):
        print(ascii_uppercase[matrix[i][j] - 1], end='')
    print()
azro
  • 53,056
  • 7
  • 34
  • 70
1

consider it as a distance from the center of the matrix with an offset.

[[int(max(abs((n-1)/2-i),abs((n-1)/2-j)))+1 for i in range(n)] for j in range(n)]

[[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]]

here n is an odd value, the center of the matrix is (n-1)/2. Since you want "1" at the center add one as offset, division converts the numbers to float format, so int() for nice formatting. List comprehension can be converted to nested loop but seems fine this way since eliminates the matrix initialization step.

The distance is called Chebyshev distance (or chessboard distance).

To covert the matrix into a String array, convert digits to corresponding chars and join the rows. At this point readability fails

[''.join([chr(ord('A')+int(max(abs((n-1)/2-i),abs((n-1)/2-j)))) for i in range(n)]) for j in range(n)]

['DDDDDDD', 'DCCCCCD', 'DCBBBCD', 'DCBABCD', 'DCBBBCD', 'DCCCCCD', 'DDDDDDD']

use functions!

def chebDist(i,j,n):
    return int(max(abs((n-1)/2-i),abs((n-1)/2-j)))

def toChar(d):
    return chr(ord('A')+d-1) 

[''.join([toChar(chebDist(i,j,n)+1) for i in range(n)]) for j in range(n)]

will give you

['DDDDDDD', 'DCCCCCD', 'DCBBBCD', 'DCBABCD', 'DCBBBCD', 'DCCCCCD', 'DDDDDDD']

or perhaps this format

print('\n'.join([''.join([toChar(chebDist(i,j,n)+1) for i in range(n)]) for j in range(n)]))

DDDDDDD
DCCCCCD
DCBBBCD
DCBABCD
DCBBBCD
DCCCCCD
DDDDDDD

readable and with reusable functions!

You can perhaps make it more readable by separating the conversions, tradeoff is efficiency due to intermediate values

first create the numerical matrix

m=[[chebDist(i,j,n)+1 for i in range(n)] for j in range(n)]

convert to char mapping

c=[[toChar(e) for e in row] for row in m]

convert to String representation and print.

print('\n'.join([''.join(row) for row in c]))

UPDATE

Finally, all wrapped up into 4 generic functions and 2 lines of code.

def chebDist(i,j,n):
    return int(max(abs((n-1)/2-i),abs((n-1)/2-j)))

def toChar(d):
    return chr(ord('A')+d-1) 

def map2(f,m):
    return [[f(e) for e in row] for row in m]

def toString(a):
    return '\n'.join(map(''.join,a))


m=[[chebDist(i,j,n)+1 for i in range(n)] for j in range(n)]
print(toString(map2(toChar,m)))
karakfa
  • 66,216
  • 7
  • 41
  • 56
0

We can solve everything in a single input line and a single output line:

N = int(input('Enter N value:'))
print('\n'.join([''.join([chr(64+max(max(N-i,N-j),max(i-N+2,j-N+2))) for i in range(2*N-1)]) for j in range(2*N-1)]))

Explanation: We will work in this 2*N-1x2*N-1 grid, for now with zeros:

[[0 for i in range(2*N-1)] for j in range(2*N-1)]

Then, we want the formating, so we convert things to string and join them:

print('\n'.join([''.join([str(0) for i in range(2*N-1)]) for j in range(2*N-1)]))

Ok, we have zeros, but we want your number matrix, so we apply this formula for the matrix with i and j indexes max(max(N-i,N-j),max(i-N+2,j-N+2)):

print('\n'.join([''.join([str(max(max(N-i,N-j),max(i-N+2,j-N+2))) for i in range(2*N-1)]) for j in range(2*N-1)]))

Now that we have the numbers matrix, let's apply this transformation: chr(64+k) => capital letter of the alphabet, starting from zero, because 'A' is ascii code 64, 'B' is ascii code 65, and so on...

print('\n'.join([''.join([chr(64+max(max(N-i,N-j),max(i-N+2,j-N+2))) for i in range(2*N-1)]) for j in range(2*N-1)]))

There we have it.

brunoff
  • 4,161
  • 9
  • 10
  • 1
    why i am being downvoted just for presenting a different solution? i really like code without fors, it seems pythonic to me. – brunoff Feb 11 '21 at 18:45
  • 2
    I did not downvote, but I can guess : downvote could be for "non-valid" answer, and there is different criteria, here the OP seems to be still learning, and your solution is not apapted to his level, and even for me who code a lot, I'd never write such a code who is very not-readable – azro Feb 11 '21 at 18:47
  • 2
    I downvoted because complicated one-liners like this are egregiously bad practice, AND OP is obviously a beginner. I noticed you explained your answer in an edit, but my point still stands. Despite what you think, a messy one-liner is demonstrably *not* Pythonic. – ddejohn Feb 11 '21 at 18:51
  • Thank you for the different type of solution! – Emiiri93 Feb 11 '21 at 20:19