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.
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()
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)))
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.
Related
I did this code so I reverse sub array group of integers but actually it only reverse the first sub array only and I don't know why this is happening!!!
Here is the code:
def reverseInGroups(self, arr, N, K):
rev=list()
count=0
reach=K
limit=0
while limit<N-1:
rev[limit:reach]=reversed(arr[limit:reach])
limit=limit+K
reach=reach+K
if reach==N-1 or reach<N-1:
continue
elif reach>N-1:
reach=N-1
return rev
This is the the input,excpected output and my output:
For Input:
5 3
1 2 3 4 5
Your Output:
1 2 3 4 5
Expected Output:
3 2 1 5 4
I tried your code online and its fine, but you have one logic error in your function to get your desired output.
while limit<N-1:
rev[limit:reach]=reversed(arr[limit:reach])
limit=limit+K #3
reach=reach+K #6
if reach==N-1 or reach<N-1:
continue
elif reach>N-1:
reach=N #5
this is an image to see what I mean image description
You don't have to create new list rev, you can reverse items in list arr. For example:
def reverseInGroups(arr, N, K):
limit = 0
while limit < N:
arr[limit : limit + K] = reversed(arr[limit : limit + K])
limit += K
return arr
l = [1, 2, 3, 4, 5]
print(reverseInGroups(l, 5, 3))
Prints:
[3, 2, 1, 5, 4]
I suggest you use this simpler solution:
arr = [1, 2, 3, 4, 5]
n = 5
k = 3
new_arr = list()
for index in range(0, n - 1, k):
new_arr[index:index+k] = arr[index:index+k][::-1]
print(new_arr)
And the output is:
[3, 2, 1, 5, 4]
After putting this code in your function, it is as below:
def reverseInGroups(self, arr, n, k):
new_arr = list()
for index in range(0, n - 1, k):
new_arr[index:index+k] = arr[index:index+k][::-1]
return new_arr
we can do the loop in the increment of K and then reverse the array of that specific size
def reverseInGroups(self, arr, N, K):
# code here
for i in range(0, N -1 , K):
arr[i:i +K] = arr[i:i +K][::-1]
I have n rows and m columns I need a matrix which consists of consecutive m numbers like 1,2,3,4 this in each of the n rows that needs to be in ever increasing order.
example: 3 X 4 matrix\
**[\
[1, 2, 3, 4], \
[5, 6, 7, 8],\
[9, 10, 11, 12]\
]**
The intuition is very simple. What we need is our starting element in eaxh row should be the next element of the previous row's last element. That is the only tricky part in this problem.
For that we start our next row generation with arr[i-1][-1] to the arr[i-1][-1] + m. But for the first row generation we start from 1 since the matrix is empty.
Code
mat = []
n,m = map(int,input().split())
for row in range(n):
# if the row is starting row we start it with 1
# Else we assign k to the prev rows
if row == 0:
k = 1
else:
k = mat[row-1][-1] + 1
x = []
#the new row starts from previous rows last elemnt + 1
for j in range(k,k+m):
x.append(j)
mat.append(x)
print(mat)
First generate a continuous sequence of numbers and then adjust the format, with reference to either:(n and m represent the number of rows and columns respectively)
use the built-in functions, array to generate sequences, reshape to adjust the layout
import numpy as np
n, m = map(int, input().split())
res = np.arange(1, n*m+1).reshape(n, m)
print(res)
using list generative
items = list(range(1, m*n+1))
res = [items[i:i+m] for i in range(0, len(items), m)]
print(res)
here's a one liner to achieve that -
row, col = 3, 4
mat = [[col*i + j for j in range(1, col+1)] for i in range(row)]
print(mat)
I'm working on a validator of credit cards. That sphere is new for me, so please, don't laugh:D
I'm trying to finish it without any libraries.
def creditCardValidation(creditcard):
creditcard = creditcard.replace( ' ', '' )
creditcard = [int(i) for i in creditcard]
evens = creditcard[::2]
odds = creditcard[1::2]
evens = [element * 2 for element in evens]
for j in evens:
if j >= 10:
j = [int(d) for d in str(j)]
for x in j:
evens.append(x)
for j in evens:
if j >= 10:
evens.remove(j)
return ((sum(evens) + sum(odds)) % 10 == 0)
creditCardValidation('1234 5678 9101 1213')
creditCardValidation('4561 2612 1234 5464')
creditCardValidation('4561 2612 1234 5467')
So the problem is in the array evens.
It returns
[2, 6, 14, 0, 2, 2, 1, 0, 1, 4, 1, 8]
[8, 4, 2, 2, 6, 12, 1, 2, 1, 0, 1, 2]
[8, 4, 2, 2, 6, 12, 1, 2, 1, 0, 1, 2]
It should return the same results except those which greater than 10. Everything works fine. Take a look at the first array, 18 deleted as well as 10, but 14 is not.
Removing while iterating over the array is not the best thing to do and will mostly result in skipping some elements in the array while iterating, so a safer way to do this
for j in evens:
if j >= 10:
evens.remove(j)
is to collect all the elements you want to remove in another list then subtract it from your original if you are using numpy arrrays or removing them one by one, as python lists has no subtraction operation defined to subtract one array from a another
to_remove = []
for j in evens:
if j >= 10:
to_remove.append(j)
for j in to_remove:
events.remove(j)
or you could whitelist instead of blacklisting
small_evens = []
for j in evens:
if j < 10:
small_evens.append(j)
# use small_evens and discard evens array
A couple of issues:
Python has zero indexed arrays, so evens[::2] is actually returning the first, third, etc. digit. Luhn's algo requires even digits (assuming 1 indexing) to be doubled.
You shouldn't modify a list you are iterating over.
You can simplify, removing a lot of the list creations:
def creditCardValidation(creditcard):
*creditcard, checkdigit = creditcard.replace(' ', '')
total = 0
for i, digit in enumerate(map(int, creditcard), 1):
if i % 2 == 0:
digit *= 2
total += digit // 10 # Will be zero for single digits
total += digit % 10
return 9*total % 10 == int(checkdigit)
In []:
creditCardValidation('1234 5678 9101 1213')
Out[]:
True
In []:
creditCardValidation('4561 2612 1234 5464')
Out[]:
False
I want to generate a lexicographic series of numbers such that for each number the sum of digits is a given constant. It is somewhat similar to 'subset sum problem'. For example if I wish to generate 4-digit numbers with sum = 3 then I have a series like:
[3 0 0 0]
[2 1 0 0]
[2 0 1 0]
[2 0 0 1]
[1 2 0 0] ... and so on.
I was able to do it successfully in Python with the following code:
import numpy as np
M = 4 # No. of digits
N = 3 # Target sum
a = np.zeros((1,M), int)
b = np.zeros((1,M), int)
a[0][0] = N
jj = 0
while a[jj][M-1] != N:
ii = M-2
while a[jj][ii] == 0:
ii = ii-1
kk = ii
if kk > 0:
b[0][0:kk-1] = a[jj][0:kk-1]
b[0][kk] = a[jj][kk]-1
b[0][kk+1] = N - sum(b[0][0:kk+1])
b[0][kk+2:] = 0
a = np.concatenate((a,b), axis=0)
jj += 1
for ii in range(0,len(a)):
print a[ii]
print len(a)
I don't think it is a very efficient way (as I am a Python newbie). It works fine for small values of M and N (<10) but really slow beyond that. I wish to use it for M ~ 100 and N ~ 6. How can I make my code more efficient or is there a better way to code it?
Very effective algorithm adapted from Jorg Arndt book "Matters Computational"
(Chapter 7.2 Co-lexicographic order for compositions into exactly k parts)
n = 4
k = 3
x = [0] * n
x[0] = k
while True:
print(x)
v = x[-1]
if (k==v ):
break
x[-1] = 0
j = -2
while (0==x[j]):
j -= 1
x[j] -= 1
x[j+1] = 1 + v
[3, 0, 0, 0]
[2, 1, 0, 0]
[2, 0, 1, 0]
[2, 0, 0, 1]
[1, 2, 0, 0]
[1, 1, 1, 0]
[1, 1, 0, 1]
[1, 0, 2, 0]
[1, 0, 1, 1]
[1, 0, 0, 2]
[0, 3, 0, 0]
[0, 2, 1, 0]
[0, 2, 0, 1]
[0, 1, 2, 0]
[0, 1, 1, 1]
[0, 1, 0, 2]
[0, 0, 3, 0]
[0, 0, 2, 1]
[0, 0, 1, 2]
[0, 0, 0, 3]
Number of compositions and time on seconds for plain Python (perhaps numpy arrays are faster) for n=100, and k = 2,3,4,5 (2.8 ghz Cel-1840)
2 5050 0.040000200271606445
3 171700 0.9900014400482178
4 4421275 20.02204465866089
5 91962520 372.03577995300293
I expect time 2 hours for 100/6 generation
Same with numpy arrays (x = np.zeros((n,), dtype=int)) gives worse results - but perhaps because I don't know how to use them properly
2 5050 0.07999992370605469
3 171700 2.390003204345703
4 4421275 54.74532389640808
Native code (this is Delphi, C/C++ compilers might optimize better) generates 100/6 in 21 seconds
3 171700 0.012
4 4421275 0.125
5 91962520 1.544
6 1609344100 20.748
Cannot go sleep until all measurements aren't done :)
MSVS VC++: 18 seconds! (O2 optimization)
5 91962520 1.466
6 1609344100 18.283
So 100 millions variants per second.
A lot of time is wasted for checking of empty cells (because fill ratio is small). Speed described by Arndt is reached on higher k/n ratios and is about 300-500 millions variants per second:
n=25, k=15 25140840660 60.981 400 millions per second
My recommendations:
Rewrite it as a generator utilizing yield, rather than a loop that concatenates a global variable on each iteration.
Keep a running sum instead of calculating the sum of some subset of the array representation of the number.
Operate on a single instance of your working number representation instead of splicing a copy of it to a temporary variable on each iteration.
Note no particular order is implied.
I have a better solution using itertools as follows,
from itertools import product
n = 4 #number of elements
s = 3 #sum of elements
r = []
for x in range(n):
r.append(x)
result = [p for p in product(r, repeat=n) if sum(p) == s]
print(len(result))
print(result)
I am saying this is better because it took 0.1 secs on my system, while your code with numpy took 0.2 secs.
But as far as n=100 and s=6, this code takes time to go through all the combinations, I think it will take days to compute the results.
I found a solution using itertools as well (Source: https://bugs.python.org/msg144273). Code follows:
import itertools
import operator
def combinations_with_replacement(iterable, r):
# combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
pool = tuple(iterable)
n = len(pool)
if not n and r:
return
indices = [0] * r
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != n - 1:
break
else:
return
indices[i:] = [indices[i] + 1] * (r - i)
yield tuple(pool[i] for i in indices)
int_part = lambda n, k: (tuple(map(c.count, range(k))) for c in combinations_with_replacement(range(k), n))
for item in int_part(3,4): print(item)
I tried to create this code to input an m by n matrix. I intended to input [[1,2,3],[4,5,6]] but the code yields [[4,5,6],[4,5,6]. Same things happen when I input other m by n matrix, the code yields an m by n matrix whose rows are identical.
Perhaps you can help me to find what is wrong with my code.
m = int(input('number of rows, m = '))
n = int(input('number of columns, n = '))
matrix = []; columns = []
# initialize the number of rows
for i in range(0,m):
matrix += [0]
# initialize the number of columns
for j in range (0,n):
columns += [0]
# initialize the matrix
for i in range (0,m):
matrix[i] = columns
for i in range (0,m):
for j in range (0,n):
print ('entry in row: ',i+1,' column: ',j+1)
matrix[i][j] = int(input())
print (matrix)
The problem is on the initialization step.
for i in range (0,m):
matrix[i] = columns
This code actually makes every row of your matrix refer to the same columns object. If any item in any column changes - every other column will change:
>>> for i in range (0,m):
... matrix[i] = columns
...
>>> matrix
[[0, 0, 0], [0, 0, 0]]
>>> matrix[1][1] = 2
>>> matrix
[[0, 2, 0], [0, 2, 0]]
You can initialize your matrix in a nested loop, like this:
matrix = []
for i in range(0,m):
matrix.append([])
for j in range(0,n):
matrix[i].append(0)
or, in a one-liner by using list comprehension:
matrix = [[0 for j in range(n)] for i in range(m)]
or:
matrix = [x[:] for x in [[0]*n]*m]
See also:
How to initialize a two-dimensional array in Python?
Hope that helps.
you can accept a 2D list in python this way ...
simply
arr2d = [[j for j in input().strip()] for i in range(n)]
# n is no of rows
for characters
n = int(input().strip())
m = int(input().strip())
a = [[0]*n for _ in range(m)]
for i in range(n):
a[i] = list(input().strip())
print(a)
or
n = int(input().strip())
n = int(input().strip())
a = []
for i in range(n):
a[i].append(list(input().strip()))
print(a)
for numbers
n = int(input().strip())
m = int(input().strip())
a = [[0]*n for _ in range(m)]
for i in range(n):
a[i] = [int(j) for j in input().strip().split(" ")]
print(a)
where n is no of elements in columns while m is no of elements in a row.
In pythonic way, this will create a list of list
If the input is formatted like this,
1 2 3
4 5 6
7 8 9
a one liner can be used
mat = [list(map(int,input().split())) for i in range(row)]
explanation with example:
input() takes a string as input. "1 2 3"
split() splits the string by whitespaces and returns a
list of strings. ["1", "2", "3"]
list(map(int, ...)) transforms/maps the list of strings into a list of ints. [1, 2, 3]
All these steps are done row times and these lists are stored in another list.[[1, 2, 3], [4, 5, 6], [7, 8, 9]], row = 3
If you want to take n lines of input where each line contains m space separated integers like:
1 2 3
4 5 6
7 8 9
Then you can use:
a=[] // declaration
for i in range(0,n): //where n is the no. of lines you want
a.append([int(j) for j in input().split()]) // for taking m space separated integers as input
Then print whatever you want like for the above input:
print(a[1][1])
O/P would be 5 for 0 based indexing
Apart from the accepted answer, you can also initialise your rows in the following manner -
matrix[i] = [0]*n
Therefore, the following piece of code will work -
m = int(input('number of rows, m = '))
n = int(input('number of columns, n = '))
matrix = []
# initialize the number of rows
for i in range(0,m):
matrix += [0]
# initialize the matrix
for i in range (0,m):
matrix[i] = [0]*n
for i in range (0,m):
for j in range (0,n):
print ('entry in row: ',i+1,' column: ',j+1)
matrix[i][j] = int(input())
print (matrix)
This code takes number of row and column from user then takes elements and displays as a matrix.
m = int(input('number of rows, m : '))
n = int(input('number of columns, n : '))
a=[]
for i in range(1,m+1):
b = []
print("{0} Row".format(i))
for j in range(1,n+1):
b.append(int(input("{0} Column: " .format(j))))
a.append(b)
print(a)
If your matrix is given in row manner like below, where size is s*s here s=5
5
31 100 65 12 18 10 13 47 157 6 100 113 174 11 33 88 124 41 20 140 99 32 111 41 20
then you can use this
s=int(input())
b=list(map(int,input().split()))
arr=[[b[j+s*i] for j in range(s)]for i in range(s)]
your matrix will be 'arr'
m,n=map(int,input().split()) # m - number of rows; n - number of columns;
matrix = [[int(j) for j in input().split()[:n]] for i in range(m)]
for i in matrix:print(i)
no_of_rows = 3 # For n by n, and even works for n by m but just give no of rows
matrix = [[int(j) for j in input().split()] for i in range(n)]
print(matrix)
You can make any dimension of list
list=[]
n= int(input())
for i in range(0,n) :
#num = input()
list.append(input().split())
print(list)
output:
Creating matrix with prepopulated numbers can be done with list comprehension. It may be hard to read but it gets job done:
rows = int(input('Number of rows: '))
cols = int(input('Number of columns: '))
matrix = [[i + cols * j for i in range(1, cols + 1)] for j in range(rows)]
with 2 rows and 3 columns matrix will be [[1, 2, 3], [4, 5, 6]], with 3 rows and 2 columns matrix will be [[1, 2], [3, 4], [5, 6]] etc.
a = []
b = []
m=input("enter no of rows: ")
n=input("enter no of coloumns: ")
for i in range(n):
a = []
for j in range(m):
a.append(input())
b.append(a)
Input : 1 2 3 4 5 6 7 8 9
Output : [ ['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9'] ]
row=list(map(int,input().split())) #input no. of row and column
b=[]
for i in range(0,row[0]):
print('value of i: ',i)
a=list(map(int,input().split()))
print(a)
b.append(a)
print(b)
print(row)
Output:
2 3
value of i:0
1 2 4 5
[1, 2, 4, 5]
value of i: 1
2 4 5 6
[2, 4, 5, 6]
[[1, 2, 4, 5], [2, 4, 5, 6]]
[2, 3]
Note: this code in case of control.it only control no. Of rows but we can enter any number of column we want i.e row[0]=2 so be careful. This is not the code where you can control no of columns.
a,b=[],[]
n=int(input("Provide me size of squre matrix row==column : "))
for i in range(n):
for j in range(n):
b.append(int(input()))
a.append(b)
print("Here your {} column {}".format(i+1,a))
b=[]
for m in range(n):
print(a[m])
works perfectly
rows, columns = list(map(int,input().split())) #input no. of row and column
b=[]
for i in range(rows):
a=list(map(int,input().split()))
b.append(a)
print(b)
input
2 3
1 2 3
4 5 6
output
[[1, 2, 3], [4, 5, 6]]
I used numpy library and it works fine for me. Its just a single line and easy to understand.
The input needs to be in a single size separated by space and the reshape converts the list into shape you want. Here (2,2) resizes the list of 4 elements into 2*2 matrix.
Be careful in giving equal number of elements in the input corresponding to the dimension of the matrix.
import numpy as np
a=np.array(list(map(int,input().strip().split(' ')))).reshape(2,2)
print(a)
Input
array([[1, 2],
[3, 4]])
Output