I want a matrix amount that can be in any size for example 2x2 or 3x3 etc but reverse, my problem with for loops along with if not working well
Would appreciate help
for example:
2,1,5
3,6,1
8,5,0
the result is 5 + 6 + 8 = 19
def is_diagonal_equal(matrix):
for i in range(0, len(matrix)):
for j in range(0, len(matrix)):
if i == a and j == g/2:
sum2 += matrix[i][j]
The function gets an initialized matrix with values and size
You can use enumerate to get the backward progressing indexes of each row and sum() to add up the result:
def rearDiagSum(matrix):
return sum(row[-i] for i,row in enumerate(matrix,1))
M = [ [2,1,5],
[3,6,1],
[8,5,0] ]
print(rearDiagSum(M)) # 19
Note that this assumes a square matrix
Related
I have the following Matlab code (adopted from Programming and Numerical Methods in MATLAB by Otto&Denier, page 75)
clear all
p = input('Enter the power you require: ');
points = p+2;
n = 1:points;
for N = n
sums(N) = 0;
for j = 1:N
sums(N) = sums(N)+j^p;
end
end
The output for 3 as the given value of p is the following list
>> sums
sums =
1 9 36 100 225
I have written the following Python code (maybe not the most 'Pythonic way') trying to follow as much as possible Matlab instructions.
p = int(input('Enter the power you require: '))
points = p+2
n = range(points)
for N in range(1, len(n)+1):
sums = [0]*N
for index, item in list(enumerate(sums)):
sums[index] = item+index**p
Nevertheless the output is not same list. I have tried to replace the inner loop with
for j in range(1,N+1):
sums[N] = sums[N]+j**p
but this results to an index error message. Thanks in advance for any suggestions.
This might be due to the index difference. In Python, it starts from 0 while it's 1 in Matlab. Also, sums = [0]*N initialize a list of a length N, this has to be moved outside of the loop.
points = p+2
sums = [0]*points
for N in range(0, points):
for index in range(0, N+1):
sums[N] = sums[N] + (index+1)**p
sums(N) = 0; does not create an array of all zeros, it sets element N of the existing array to 0, and creates additional elements in the array if it not at least of length N.
Because N grows by one each iteration, you could initialize as an empty array before the loop, and append(0) inside the loop:
sums = []
for N in range(1, len(n)+1):
sums.append(0)
I don’t particularly like the use of enumerate here either, I would:
for index in range(N)
sums[index] += (index + 1)**p
(Notice the +1 on the index that was missing in the code in the OP!)
Finally, n is just confusing here. I would:
for N in range(1, points + 1):
…
We are given a number N and we have to find pairs i and j where i^3=j^2
For example, let N=50 so for this we will have 3 pairs (1,1),(4,8),(9,27)
basically, we have to find pairs where the cube of one number is the same as the square of the other number in a given pair
the constraint is
1<=N<10^6
1<=i,j<N
Naive approach use 2 for loops iterate through each element and get those pairs where cube is equal to sum time complexity is O(n*2)
def get_pair(N):
for i in range(1,N):
for j in range(1,N):
if i*i*i==j*j:
print(i,j)
N=50
get_pair(N)
what will be an optimal way to solve this problem with a better time complexity?
Since you're working with integers, if there exists some number M = i^3 = j^2 for i and j between 1 and N, then that means there exists a k such that M = k^6. To find i and j, simply compare the representations of M:
(1) M = k^6 = i^3 = (k^2)^3 therefore i = k^2
(2) M = k^6 = j^2 = (k^3)^2 therefore j = k^3
Since j is always greater than or equal to i, you only need to check if 1 < k^3 < N. In other words, k should be less than the cube root of N.
k
M = k^6
i = k^2
j = k^3
2
64
4
8
3
729
9
27
4
4,096
16
64
5
15,625
25
125
6
46,656
36
216
...
...
...
...
97
8.329x10^11
9409
912,673
98
8.858x10^11
9604
941,192
99
9.415x10^11
9801
970,299
Note that 100 isn't a valid candidate for k because that would make j less than or equal to N instead of strictly less than N (if we're going with N = 10^6).
So to get the list of tuples that satisfy your problem, find the values of k such that 1 < k^3 < N and return its square and cube in a tuple.
import math
from typing import List, Tuple
N: int = 10**6
pairs: List[Tuple[int, int]] = [(k * k, k * k * k) for k in range(2, math.ceil(N**(1 / 3)))]
print(pairs)
This is a list comprehension, a shorthand for a for-loop.
I'm basically asking Python to generate a list of tuples over an index k that falls in the range defined as range(2, math.ceil(N**(1 / 3)). That range is exactly the first column of the table above.
Then, for every k in that range I make a tuple of which the first item is k^2 and the second item is k^3, just like the last two columns of the table.
Also threw in the typing library in there for good measure. Clear code is good code, even for something as small as this. Python can figure out that pairs is a list of tuples without anyone telling it, but this way I've explicitly enforced that variable to be a list of tuples to avoid any confusion when someone tries to give it a different value or isn't sure what the variable contains.
Another naive approach could be to use the "basic" values ?
def get_pair(N):
for i in range(N):
if(i**3 > MAX):
break # Limit to the max you want, and i**3 > i**2 if i > 1
print(i**2, i**3)
Time complexity seems to be O(n) (Not an expert, so correct me if i'm wrong)
This is made so that the first element cubed == second element squared:
first = a^2
second = a^3
first^3 = a^(2*3) = a^6
second^2 = a^(3*2) = a^6
You can use itertool's combinations_with_replacement function.
from itertools import combinations_with_replacement as combinations
def get_pair(N):
for i, j in combinations(range(1,N), 2):
if i*i*i==j*j:
print(i,j)
N=50
get_pair(N)
You do this with one loop (and minimal iterations) if you know that that pairs (x, y) are always y = x * i, this means you can use:
def get_pair(N):
i = 1
a = 1
while a * i < N:
b = a * i
print(a,b)
i += 1
a = i**2
N=50
get_pair(N)
This gets all 3 pairs:
1 1
4 8
9 27
In only 3 total iterations.
Does anyone know why my index matrix[k][m]=sum/9 is out of range? I'm pretty sure that my solution is correct. I tried debugging it, but I still cannot think
why it's not working.
def downsample_by_3(image):
matrix_image = copy.deepcopy(image)
matrix=[ [], [], [] ]
k=0
m=0
for i in range(0,len(matrix_image),3):
for j in range(0,len(matrix_image[i]),3):
sum=0
for r in range(i,i+3):
for c in range(j,j+3):
sum+=matrix_image[r][c]
m+=1
matrix[k][m]=sum/9
m=0
k+=1
return matrix
The image is presented as a matrix (list of lists).
Let's say I took this list,
print(downsample_by_3([[2,2,2],[2,2,2],[2,2,2]]))
it should return a list with 18.
Another example of it to understand it better:
You have a list of empty lists. So while matrix[0] is fine, matrix[0][0] is out of bounds.
You have to either preallocate the lengths of the sublists beforehand if you wish to access them by index, or you append the averages as shown in Gary02127's answer. If you choose the former, you must also increment m after matrix[k][m]=sum/9.
However, your code has another out-of-bounds bug waiting to be triggered. Suppose you have a 3x4 image, i.e., one of the dimensions isn't divisible by 3. You average the first 3x3 block just fine, and then you try to access the pixels at column indices 3-5.
If your dimensions aren't divisible by the downsample factor, you have 3 choices:
raise an error at the beginning of the function call,
add extra rows/columns to make your matrix divisible by your factor (you can use the value of the last element of the row/column to extend it further), or
use only as many elements are you have left.
Here's an implementation with approach #3 and preallocating your matrix.
def downsample(image, factor):
height = len(image)
# this assumes that all sublists have the same length!
width = len(image[0])
matrix = [[None] * ((width + factor - 1) // factor)
for _ in range((height + factor - 1) // factor)]
k = 0
m = 0
for i in range(0, height, factor):
for j in range(0, width, factor):
# don't overshadow the `sum` builtin
total = 0
count = 0
for r in range(i, min(i+factor, height)):
for c in range(j, min(j+factor, width)):
total += image[r][c]
count += 1
matrix[k][m] = total / count
m += 1
m = 0
k += 1
return matrix
You start with matrix hard-coded to a sequence of empty lists matrix=[ [], [], [] ], and then in the
matrix[k][m]=sum/9
line, you try to force a value into one of those slots, but there are no slots. The k will be okay for the first few (from 0 through 2), but the m is going to error right away. Seems like you need to dynamically create matrix on the fly. Maybe
matrix[k].append(sum/9)
Also, a return matrix at the end your function wouldn't hurt. :)
The above should help you move forward. At least it gives running code.
the recursive function below helps to find all the paths for a 3X3 matrix, from top left to bottom right, moving either down or right. But i want to change it into an iterative function so that I can edit the function to just find a specific completed path (just 1, from top left to bottom right, by moving right or down) which sums up( sum of the values at each point equate to a set number) to a desired number eg. 12. This is especially important for a bigger matrix eg. a 9 X 1000 matrix. How do I do it?
Note for Danoran:
The values are always positive. If you look at my 3X3 matrix a, you see values of 1s, 2s and 3s. So for example, moving from 1 to 1 to 1 to 2 to 3 (goal) is a completed path and the sum is 8.
This finds all the paths only.
a = []
for i in range(3):
r = []
for j in range(3):
r.append(i+1)
a.append(r)
a = matrix
1 1 1
2 2 2
3 3 3
all_paths = []
def printall(currentRow, currentColumn, nums):
if (currentRow == len(a) - 1):
for i in range(currentColumn, len(a[0])):
nums.append(a[currentRow][i])
all_paths.append(nums)
return all_paths
if (currentColumn == len(a[0]) - 1):
for i in range(currentRow, len(a)):
nums.append(a[i][currentColumn])
all_paths.append(nums)
return all_paths
nums.append(a[currentRow][currentColumn])
printall(currentRow+1, currentColumn, nums[:])
printall(currentRow, currentColumn+1, nums[:])
printall(0,0,[])
print all_paths
If there are R rows and C columns, you have to make R-1 down-jumps and
C-1 right-jumps. That’s invariant. The only variation is in the order of
the jumps. If we say dj=R-1 and rj=C-1, then the total number of paths
is (dj+rj)!/(dj!rj!).
So, we can simply iterate through all the unique permutations. Note that
itertools.permutations() will generate all permutations, not just
the unique ones, so we have to filter out the repeats. Of course, this
also means the run time will be proportional to (dj+rj)!, the number of
non-unique permutations. I won’t go into how to efficiently generate
unique permutations; see, for example, Question 22431637.
In the code below, I’ve increased the number of rows to 4, to help
distinguish rows from columns.
from itertools import permutations
a = []
for i in range(4):
r = []
for j in range(3):
r.append(i+1)
a.append(r)
#print a # Uncomment to trace execution
all_paths = []
def gen_all_paths(matrix):
rows = len(matrix)
cols = len(matrix[0])
dj = rows - 1 # down-jumps
rj = cols - 1 # right-jumps
pathmix = 'd' * dj + 'r' * rj
prev = ()
for path in permutations(pathmix):
if path <= prev: # filter out repeats
continue
prev = path
r, c = 0, 0
cells = [matrix[0][0]]
for i in path:
if i == 'd':
r += 1
else:
c += 1
cells.append(matrix[r][c])
#print ''.join(path), cells # Uncomment to trace execution
all_paths.append(cells)
gen_all_paths(a)
print all_paths
I'd like to iterate over every other element of a m-by-n "chessboard", i.e.,
l = []
for i in range(m):
for j in range(n):
if (i+j) % 2 == 0:
l.append(something(i, j))
I'm using an explicit loop here, but for speed would rather use a list comprehension.
Any hints?
For bonus points, the solution also works for i, j, k with (i+j+k) % 2 == 0.
Well, list comprehension is just like your nested for loop, except that this is done within the list brackets:
my_list = [something(i, j) for i in range(m) for j in range(n) if (i + j) % 2 == 0]
More generally, for n nested loops, you can use itertools.product, like this:
from itertools import product
my_list = [something(*p) for p in product(range(n), repeat=n) if sum(p) % 2 == 0]
As I understand it, you would like an explicit expression for the x and y coordinates of the black squares on the 'chess board', so that you don't have to evaluate the boolean for every square. Here is an implementation of my solution (for a 2-dimensional board):
import numpy as np
# 'Chess board' dimension
m = 3 # Number of columns
n = 4 # Number of rows
# Counter variable. The length of this array is equal to the total number of black squares.
k = np.arange(0,m*n,2)
x_coords = (k + (k/n) % 2) % n # x-coordinates of black squares
y_coords = (k + (k/n) % 2) / n # y-coordinates of black squares
print("x-coordinates: "+str(x_coords))
print("y-coordinates: "+str(y_coords))
For the 3x4 dimensional board in the example above, this generates the following output:
x-coordinates: [0 2 1 3 0 2]
y-coordinates: [0 0 1 1 2 2]
which you can verify by drawing a little diagram. Note that the 'helper variable' (k/n) % 2 keeps track of whether the row number is even or odd; the odd rows have an 'offset' with respect to the even ones.