Divide matrix into submatrix python - python

The program must accept an integer matrix of size R*C and four integers X, Y, P, Q as the input. The program must divide the matrix into nine submatrices based on the following condition. The program must divide the matrix horizontally after the Xth row and Yth row. Then the program must divide the matrix vertically after the Pth column and Qth column. Finally, the program must print the sum of integers in each submatrix as the output.
Input:
6 5
6 9 2 9 2
7 1 9 3 2
9 9 1 2 6
6 5 7 1 9
6 6 6 2 3
1 6 7 9 7
3 5 2 4
Output:
41 26 10 23 16 12 7 16 7
Explanation:
Here X = 3, Y=5, P = 2 and Q = 4
The nine submatrices and their sums are given below.
1st submatrix sum= 6+9+7+1+9+9 =41
6 9
7 1
9 9
2nd submatrix sum= 2+9+9+3+1+2 =26
2 9
9 3
1 2
3rd submatrix sum= 2+2+6 = 10
2
2
6
4th submatrix sum= 6+5+6+6 = 23
6 5
6 6
5th submatrix sum = 7+1+6+2 = 16
7 1
6 2
6th submatrix sum = 9 + 3 = 12
9
3
7th submatrix sum = 1 + 6 = 7
1 6
8th submatrix sum = 7 + 9 = 16
7 9
9th submatrix sum = 7
7
My program:
r,c=map(int,input().split())
m=[list(map(int,input().split())) for i in range(r)]
x,y,p,q=list(map(int,input().split()))
for i in range(x):
for j in range(p):
print(m[i][j])
print()
How to iterate from the given row and column and find the submatrix and print the sum?

Here are five solutions...
After reading all input like you did, you could go through the three boundary pairs for columns and the three boundary pairs for columns:
print(*(sum(sum(row[j:J]) for row in m[i:I])
for i, I in [(0, x), (x, y), (y, r)]
for j, J in [(0, p), (p, q), (q, c)]))
Same idea, slicing earlier / less often:
print(*(sum(sum(row[j:J]) for row in rows)
for rows in [m[:x], m[x:y], m[y:]]
for j, J in [(0, p), (p, q), (q, c)]))
Or without slicing:
print(*(sum(m[i][j]
for i in range(*irange)
for j in range(*jrange))
for irange in [(0, x), (x, y), (y, r)]
for jrange in [(0, p), (p, q), (q, c)]))
Or go through the matrix and update the right one of the nine sums:
sums = [0] * 9
for i in range(r):
for j in range(c):
sums[((i>=x)+(i>=y)) * 3 + (j>=p)+(j>=q)] += m[i][j]
print(*sums)
Again a variation:
sums = [0] * 9
for i in range(r):
for j in range(c):
sums[(0 if i<x else 3 if i<y else 6) +
(0 if j<p else 1 if j<q else 2)] += m[i][j]
print(*sums)
Try it online!

Related

Create dynamic nested for loops

I have some arrays m rows by 2 `columns (like series of coordinates) and I want to automatize my code so that I will not use nested loop for every coord. Here is my code it runs well and gives right answer coordinates but I want to make a dynamic loop:
import numpy as np
A = np.array([[1,5,7,4,6,2,2,6,7,2],[2,8,2,9,3,9,8,5,6,2],[3,4,0,2,4,3,0,2,6,7],\
[1,5,7,3,4,5,2,7,9,7],[6,2,8,8,6,7,9,6,9,7],[0,2,0,3,3,5,2,3,5,5],[5,5,5,0,6,6,8,5,9,0]\
,[0,5,7,6,0,6,9,9,6,7],[5,5,8,5,0,8,5,3,5,5],[0,0,6,3,3,3,9,5,9,9]])
number = 8292
number = np.asarray([int(i) for i in str(number)]) #split number into array
#the coordinates of every single value contained in required number
coord1=np.asarray(np.where(A == number[0])).T
coord2=np.asarray(np.where(A == number[1])).T
coord3=np.asarray(np.where(A == number[2])).T
coord4=np.asarray(np.where(A == number[3])).T
coordinates = np.array([[0,0]]) #initialize the array that will return all the desired coordinates
solutions = 0 #initialize the array that will give the number of solutions
for j in coord1:
j = j.reshape(1, -1)
for i in coord2 :
i=i.reshape(1, -1)
if (i[0,0]==j[0,0]+1 and i[0,1]==j[0,1]) or (i[0,0]==j[0,0]-1 and i[0,1]==j[0,1]) or (i[0,0]==j[0,0] and i[0,1]==j[0,1]+1) or (i[0,0]==j[0,0] and i[0,1]==j[0,1]-1) :
for ii in coord3 :
ii=ii.reshape(1, -1)
if (np.array_equal(ii,j)==0 and ii[0,0]==i[0,0]+1 and ii[0,1]==i[0,1]) or (np.array_equal(ii,j)==0 and ii[0,0]==i[0,0]-1 and ii[0,1]==i[0,1]) or (np.array_equal(ii,j)==0 and ii[0,0]==i[0,0] and ii[0,1]==i[0,1]+1) or (np.array_equal(ii,j)==0 and ii[0,0]==i[0,0] and ii[0,1]==i[0,1]-1) :
for iii in coord4 :
iii=iii.reshape(1, -1)
if (np.array_equal(iii,i)==0 and iii[0,0]==ii[0,0]+1 and iii[0,1]==ii[0,1]) or (np.array_equal(iii,i)==0 and iii[0,0]==ii[0,0]-1 and iii[0,1]==ii[0,1]) or (np.array_equal(iii,i)==0 and iii[0,0]==ii[0,0] and iii[0,1]==ii[0,1]+1) or (np.array_equal(iii,i)==0 and iii[0,0]==ii[0,0] and iii[0,1]==ii[0,1]-1) :
point = np.concatenate((j,i,ii,iii))
coordinates = np.append(coordinates,point,axis=0)
solutions +=1
coordinates = np.delete(coordinates, (0), axis=0)
import itertools
A = [1, 2, 3]
B = [4, 5, 6]
C = [7, 8, 9]
for (a, b, c) in itertools.product (A, B, C):
print (a, b, c);
outputs:
1 4 7
1 4 8
1 4 9
1 5 7
1 5 8
1 5 9
1 6 7
1 6 8
1 6 9
2 4 7
2 4 8
2 4 9
2 5 7
2 5 8
2 5 9
2 6 7
2 6 8
2 6 9
3 4 7
3 4 8
3 4 9
3 5 7
3 5 8
3 5 9
3 6 7
3 6 8
3 6 9
See documentation for details.

How to print a sequence stacked in a "pyramid" with alternating sort?

I want to print the following sequence of integers in a pyramid (odd rows sorted ascending, even rows sorted descending). If S=4, it must print four rows and so on.
Expected output:
1
3 2
4 5 6
10 9 8 7
I tried out the following code but it produced the wrong output.
S=int(input())
for i in range(1,S+1):
y=i+(i-1)
if i%2!=0:
print(*range(i,y+1))
elif i%2==0:
print(*range(y,i-1,-1))
# Output:
# 1
# 3 2
# 3 4 5
# 7 6 5 4
You need some way of either keeping track of where you are in the sequence when printing each row, generating the entire sequence and then chunking it into rows, or... (the list of possible approaches goes on and on).
Below is a fairly simple approach that just keeps track of a range start value, calculates the range stop value based on the row number, and reverses even rows.
rows = int(input())
start = 1
for n in range(1, rows + 1):
stop = int((n * (n + 1)) / 2) + 1
row = range(start, stop) if n % 2 else reversed(range(start, stop))
start = stop
print(*row)
# If rows input is 4, then output:
# 1
# 3 2
# 4 5 6
# 10 9 8 7
Using itertools.count and just reversing the sublist before printing on even rows
from itertools import count
s = 4
l = count(1)
for i in range(1, s+1):
temp = []
for j in range(i):
temp.append(next(l))
if i % 2:
print(' '.join(map(str, temp)))
else:
print(' '.join(map(str, temp[::-1])))
1
3 2
4 5 6
10 9 8 7

How to calculate the sum faster

Memory limit: 256 MB
Time limit: 1 s
Hello.
We have the following code:
N, M = list(map(int, input().split()))
stones = list(map(int, input().split()))
for __ in range(M):
command, index, num = input().split()
index, num = int(index), int(num)
if command == "S":
print(sum(stones[index:num + 1]))
elif command == "M":
stones[index] = num
Where:
N is the length of list stones
M is number of commands
1 ≤ N, M ≤ 10**5
commands in form {type} {index} {index2 or value} of two types:
'S' to print sum of items in range [index; index2]
'M' to change value of item on index to new 0 ≤ value ≤ 10
This code exceeds the time limit. So, how to optimize it?
Sample Input:
9 10
1 1 2 3 5 0 4 9 4
S 2 4
S 8 8
S 0 8
S 4 5
M 5 9
S 0 8
S 4 5
M 0 7
S 1 8
S 0 5
Sample Output:
10
4
29
5
38
14
37
27

Creating a subarray with no of aubarrays passed as arguments in python

I have a large 100x15 array like this:
[a b c d e f g h i j k l m n o]
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
.
.
.(Up to 100 rows)
I want to select a portion of this data into a subset using a function which has an argument 'k' in which 'k' denotes the no of subsets to be made, like say k=5 means the data attributes are divided into 3 subsets like below:
[a b c d e] [f g h i j] [k l m n o]
[1 2 3 4 5] [6 7 8 9 10] [11 12 13 14 15]
[1 2 3 4 5] [6 7 8 9 10] [11 12 13 14 15]
[1 2 3 4 5] [6 7 8 9 10] [11 12 13 14 15]
[1 2 3 4 5] [6 7 8 9 10] [11 12 13 14 15]
.
.
.(Up to 100 rows)
and they are stored in a different array. I want to implement this using python. I have implemented this partially. Can any one implement this and provide me the code in the answer?
Partial logic for the inner loop
given k
set start_index = 0
end_index = length of array/k = increment
for j from start_index to end_index
start_index=end_index + 1
end_index = end_index + increment
//newarray[][] (I'm not sure abt here)
Thank You.
This returns an array of matrices with columnsize = 2 , which works for k=2:
import numpy as np
def portion(mtx, k):
array = []
array.append( mtx[:, :k])
for i in range(1, mtx.shape[1]-1):
array.append( mtx[:, k*i:k*(i+1)])
return array[:k+1]
mtx = np.matrix([[1,2,3,10,13,14], [4,5,6,11,15,16], [7,8,9,12,17,18]])
k = 2
print(portion(mtx, k))
Unfortunately I have to do it myself and this is the code in python for the logic. Anyway thanks to #astaning for the attempt.
def build_rotationtree_model(k):
mtx =np.array([[2.95,6,63,23],[2,53,7,79],[3.57,5,65,32],[3.16,5,47,34],[21,2.58,4,46],[3.1,2.16,6,22],[3.5,3.27,3,52],[12,2.56,4,42]])
#Length of attributes (width of matrix)
a = mtx.shape[1]
newArray =[[0 for x in range(k)] for y in range(len(mtx))]
#Height of matrix(total rows)
b = mtx.shape[0]
#Seperation limit
limit = a/k
#Starting of sub matrix
start = 0
#Ending of sub matrix
end = a/k
print(end)
print(a)
#Loop
while(end != a):
for i in range(0,b-1):
for j in range(start,int(end)):
newArray[i][j] = mtx[i][j]
print(newArray[i])
#Call LDA function and add the result to Sparse Matrix
#sparseMat = LDA(newArray) SHould be inside a loop
start = end + 1
end = end + limit
a=list(input())
for i in range(0,len(a)):
for j in range(i,len(a)):
for k in range(i,j+1):
print(a[k],end=" ")
print("\n",end="")

Nearest value of a given value

Given this pandas Series.
x = pd.Series([5, 10])
I use searchsorted and a loop to find the closest value of the looped number, X.
for X in xrange(1, 11):
print X, x.searchsorted(X)
What is returned.
1 [0]
2 [0]
3 [0]
4 [0]
5 [0]
6 [1]
7 [1]
8 [1]
9 [1]
10 [1]
What I'm trying to achieve is having 6 and 7 return [0] because those numbers are closer to 5 than 10.
Instead of .searchsorted() you could also check for the index of the pd.Series value that minimizes the absolute difference to the value in question:
import numpy as np
for X in range(1, 11):
print(X, (np.abs(x - X)).argmin())
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 1
9 1
10 1

Categories