Find diagonals in a Python matrix using lists





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I'm trying to code the game connect-4, and there is a part of my code in which i try to find in a 7x6 matrix, diagonals of 4 ones in a row or 4 2s in a row.
This part of my code does not work i tried everything I was able to. And sometimes it detects that there is a 4 1s or 4 2s diagonal where is not. I created the matrix puting a 7 zero list in each position of a 6 zeros lists. I'm trying to do it using only lists functions, i cant use the numpy library or similar.
Okay, in this part of the code I'm trying to find if in each possible diagonal of the matrice there are 4 zeros in a row. PD: I'm only trying to find the diagonals that go from left to right ATM. Thanks for your help, I tried to explain my problem as good as I can because english is not my main tongue.
This is my code:



import random
llista = [0]*6 #when i say llista y mean matrix
for i in range(6):
llista[i]=[0]*7

#Here i fill the 7*6 matrix of 0s 1s and 2s randomly so i can see if it works.
for i in range(30):
x=random.randrange(-1,-7,-1)
y=random.randrange(0,7,1)
llista[x][y]=1
for i in range(30):
x=random.randrange(-1,-7,-1)
y=random.randrange(0,7,1)
llista[x][y]=2
#This 2 loops here are too see if it is possible to have a diagonal in the matrece because if you want a diagonal u need at least a one or 2 in the center, the problem is not here.
for i in range(-1,-7,-1):
possible = False
if llista[i][3]==1:
possible = True
break

for i in range(7):
possible2 = False
if llista[-4][i]==1 or llista[-4][i]==1:
possible2=True
break

if possible==True and possible2==True:
#The problem starts here. This first loop i use it too find the diagonals that go from left to right. I want to find diagonals of 4 1s or 4 2s.
for i in range(len(llista)-3):
for j in range(len(llista[i])-3):
#This if is too see if we have four 1 or 2 togheter in the list, if we have them it prints the sentence below.
if (llista[i][j]==1 and llista[i+1][j+1]==1 and llista[i+2][j+2]==1 and llista[i+3][j+3]==1) or (llista[i][j]==2 and llista[i+1][j+1]==2 and llista[i+2][j+2]==2 and llista[i+3][j+3]==2 ):
print("There is at least one left to right diagonal")

#This loop is the same than the last one but to find diagonals from right to left (a 4 diagonal made of 1s or 2s)
for i in range(len(llista)):
for j in range(len(llista[i])):
if i-3<0 and j-3<0:
if (llista[i][j]==1 and llista[i-1][j-1]==1 and llista[i-2][j-2]==1 and llista[i-3][j-3]==1) or (llista[i][j]==2 and llista[i-1][j-1]==2 and llista[i-2][j-2]==2 and llista[i-3][j-3]==2 ):
print("There is at least one right to left diagonal")

#Here i print the matrix
for i in range(6):
print(llista[i])
#So this program should say if there is at least one left to right diagonal


or right to left diagonal.
#I dont want to use functions that are not being used already, and i dont wanna do it another way because i must understand this way. thanks










share|improve this question




















  • 1





    Are you getting an error message? What is it?

    – berkelem
    Nov 21 '18 at 21:55











  • I'm not getting any error message, it says that there is a diagonal even if there is not a 4 ones or 2s diagonal.

    – RiesenChicken
    Nov 21 '18 at 22:10


















0















I'm trying to code the game connect-4, and there is a part of my code in which i try to find in a 7x6 matrix, diagonals of 4 ones in a row or 4 2s in a row.
This part of my code does not work i tried everything I was able to. And sometimes it detects that there is a 4 1s or 4 2s diagonal where is not. I created the matrix puting a 7 zero list in each position of a 6 zeros lists. I'm trying to do it using only lists functions, i cant use the numpy library or similar.
Okay, in this part of the code I'm trying to find if in each possible diagonal of the matrice there are 4 zeros in a row. PD: I'm only trying to find the diagonals that go from left to right ATM. Thanks for your help, I tried to explain my problem as good as I can because english is not my main tongue.
This is my code:



import random
llista = [0]*6 #when i say llista y mean matrix
for i in range(6):
llista[i]=[0]*7

#Here i fill the 7*6 matrix of 0s 1s and 2s randomly so i can see if it works.
for i in range(30):
x=random.randrange(-1,-7,-1)
y=random.randrange(0,7,1)
llista[x][y]=1
for i in range(30):
x=random.randrange(-1,-7,-1)
y=random.randrange(0,7,1)
llista[x][y]=2
#This 2 loops here are too see if it is possible to have a diagonal in the matrece because if you want a diagonal u need at least a one or 2 in the center, the problem is not here.
for i in range(-1,-7,-1):
possible = False
if llista[i][3]==1:
possible = True
break

for i in range(7):
possible2 = False
if llista[-4][i]==1 or llista[-4][i]==1:
possible2=True
break

if possible==True and possible2==True:
#The problem starts here. This first loop i use it too find the diagonals that go from left to right. I want to find diagonals of 4 1s or 4 2s.
for i in range(len(llista)-3):
for j in range(len(llista[i])-3):
#This if is too see if we have four 1 or 2 togheter in the list, if we have them it prints the sentence below.
if (llista[i][j]==1 and llista[i+1][j+1]==1 and llista[i+2][j+2]==1 and llista[i+3][j+3]==1) or (llista[i][j]==2 and llista[i+1][j+1]==2 and llista[i+2][j+2]==2 and llista[i+3][j+3]==2 ):
print("There is at least one left to right diagonal")

#This loop is the same than the last one but to find diagonals from right to left (a 4 diagonal made of 1s or 2s)
for i in range(len(llista)):
for j in range(len(llista[i])):
if i-3<0 and j-3<0:
if (llista[i][j]==1 and llista[i-1][j-1]==1 and llista[i-2][j-2]==1 and llista[i-3][j-3]==1) or (llista[i][j]==2 and llista[i-1][j-1]==2 and llista[i-2][j-2]==2 and llista[i-3][j-3]==2 ):
print("There is at least one right to left diagonal")

#Here i print the matrix
for i in range(6):
print(llista[i])
#So this program should say if there is at least one left to right diagonal


or right to left diagonal.
#I dont want to use functions that are not being used already, and i dont wanna do it another way because i must understand this way. thanks










share|improve this question




















  • 1





    Are you getting an error message? What is it?

    – berkelem
    Nov 21 '18 at 21:55











  • I'm not getting any error message, it says that there is a diagonal even if there is not a 4 ones or 2s diagonal.

    – RiesenChicken
    Nov 21 '18 at 22:10














0












0








0








I'm trying to code the game connect-4, and there is a part of my code in which i try to find in a 7x6 matrix, diagonals of 4 ones in a row or 4 2s in a row.
This part of my code does not work i tried everything I was able to. And sometimes it detects that there is a 4 1s or 4 2s diagonal where is not. I created the matrix puting a 7 zero list in each position of a 6 zeros lists. I'm trying to do it using only lists functions, i cant use the numpy library or similar.
Okay, in this part of the code I'm trying to find if in each possible diagonal of the matrice there are 4 zeros in a row. PD: I'm only trying to find the diagonals that go from left to right ATM. Thanks for your help, I tried to explain my problem as good as I can because english is not my main tongue.
This is my code:



import random
llista = [0]*6 #when i say llista y mean matrix
for i in range(6):
llista[i]=[0]*7

#Here i fill the 7*6 matrix of 0s 1s and 2s randomly so i can see if it works.
for i in range(30):
x=random.randrange(-1,-7,-1)
y=random.randrange(0,7,1)
llista[x][y]=1
for i in range(30):
x=random.randrange(-1,-7,-1)
y=random.randrange(0,7,1)
llista[x][y]=2
#This 2 loops here are too see if it is possible to have a diagonal in the matrece because if you want a diagonal u need at least a one or 2 in the center, the problem is not here.
for i in range(-1,-7,-1):
possible = False
if llista[i][3]==1:
possible = True
break

for i in range(7):
possible2 = False
if llista[-4][i]==1 or llista[-4][i]==1:
possible2=True
break

if possible==True and possible2==True:
#The problem starts here. This first loop i use it too find the diagonals that go from left to right. I want to find diagonals of 4 1s or 4 2s.
for i in range(len(llista)-3):
for j in range(len(llista[i])-3):
#This if is too see if we have four 1 or 2 togheter in the list, if we have them it prints the sentence below.
if (llista[i][j]==1 and llista[i+1][j+1]==1 and llista[i+2][j+2]==1 and llista[i+3][j+3]==1) or (llista[i][j]==2 and llista[i+1][j+1]==2 and llista[i+2][j+2]==2 and llista[i+3][j+3]==2 ):
print("There is at least one left to right diagonal")

#This loop is the same than the last one but to find diagonals from right to left (a 4 diagonal made of 1s or 2s)
for i in range(len(llista)):
for j in range(len(llista[i])):
if i-3<0 and j-3<0:
if (llista[i][j]==1 and llista[i-1][j-1]==1 and llista[i-2][j-2]==1 and llista[i-3][j-3]==1) or (llista[i][j]==2 and llista[i-1][j-1]==2 and llista[i-2][j-2]==2 and llista[i-3][j-3]==2 ):
print("There is at least one right to left diagonal")

#Here i print the matrix
for i in range(6):
print(llista[i])
#So this program should say if there is at least one left to right diagonal


or right to left diagonal.
#I dont want to use functions that are not being used already, and i dont wanna do it another way because i must understand this way. thanks










share|improve this question
















I'm trying to code the game connect-4, and there is a part of my code in which i try to find in a 7x6 matrix, diagonals of 4 ones in a row or 4 2s in a row.
This part of my code does not work i tried everything I was able to. And sometimes it detects that there is a 4 1s or 4 2s diagonal where is not. I created the matrix puting a 7 zero list in each position of a 6 zeros lists. I'm trying to do it using only lists functions, i cant use the numpy library or similar.
Okay, in this part of the code I'm trying to find if in each possible diagonal of the matrice there are 4 zeros in a row. PD: I'm only trying to find the diagonals that go from left to right ATM. Thanks for your help, I tried to explain my problem as good as I can because english is not my main tongue.
This is my code:



import random
llista = [0]*6 #when i say llista y mean matrix
for i in range(6):
llista[i]=[0]*7

#Here i fill the 7*6 matrix of 0s 1s and 2s randomly so i can see if it works.
for i in range(30):
x=random.randrange(-1,-7,-1)
y=random.randrange(0,7,1)
llista[x][y]=1
for i in range(30):
x=random.randrange(-1,-7,-1)
y=random.randrange(0,7,1)
llista[x][y]=2
#This 2 loops here are too see if it is possible to have a diagonal in the matrece because if you want a diagonal u need at least a one or 2 in the center, the problem is not here.
for i in range(-1,-7,-1):
possible = False
if llista[i][3]==1:
possible = True
break

for i in range(7):
possible2 = False
if llista[-4][i]==1 or llista[-4][i]==1:
possible2=True
break

if possible==True and possible2==True:
#The problem starts here. This first loop i use it too find the diagonals that go from left to right. I want to find diagonals of 4 1s or 4 2s.
for i in range(len(llista)-3):
for j in range(len(llista[i])-3):
#This if is too see if we have four 1 or 2 togheter in the list, if we have them it prints the sentence below.
if (llista[i][j]==1 and llista[i+1][j+1]==1 and llista[i+2][j+2]==1 and llista[i+3][j+3]==1) or (llista[i][j]==2 and llista[i+1][j+1]==2 and llista[i+2][j+2]==2 and llista[i+3][j+3]==2 ):
print("There is at least one left to right diagonal")

#This loop is the same than the last one but to find diagonals from right to left (a 4 diagonal made of 1s or 2s)
for i in range(len(llista)):
for j in range(len(llista[i])):
if i-3<0 and j-3<0:
if (llista[i][j]==1 and llista[i-1][j-1]==1 and llista[i-2][j-2]==1 and llista[i-3][j-3]==1) or (llista[i][j]==2 and llista[i-1][j-1]==2 and llista[i-2][j-2]==2 and llista[i-3][j-3]==2 ):
print("There is at least one right to left diagonal")

#Here i print the matrix
for i in range(6):
print(llista[i])
#So this program should say if there is at least one left to right diagonal


or right to left diagonal.
#I dont want to use functions that are not being used already, and i dont wanna do it another way because i must understand this way. thanks







python






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 '18 at 5:39







RiesenChicken

















asked Nov 21 '18 at 21:48









RiesenChickenRiesenChicken

52




52








  • 1





    Are you getting an error message? What is it?

    – berkelem
    Nov 21 '18 at 21:55











  • I'm not getting any error message, it says that there is a diagonal even if there is not a 4 ones or 2s diagonal.

    – RiesenChicken
    Nov 21 '18 at 22:10














  • 1





    Are you getting an error message? What is it?

    – berkelem
    Nov 21 '18 at 21:55











  • I'm not getting any error message, it says that there is a diagonal even if there is not a 4 ones or 2s diagonal.

    – RiesenChicken
    Nov 21 '18 at 22:10








1




1





Are you getting an error message? What is it?

– berkelem
Nov 21 '18 at 21:55





Are you getting an error message? What is it?

– berkelem
Nov 21 '18 at 21:55













I'm not getting any error message, it says that there is a diagonal even if there is not a 4 ones or 2s diagonal.

– RiesenChicken
Nov 21 '18 at 22:10





I'm not getting any error message, it says that there is a diagonal even if there is not a 4 ones or 2s diagonal.

– RiesenChicken
Nov 21 '18 at 22:10












3 Answers
3






active

oldest

votes


















0














If you consider the logic of your 'right-to-left' loop, you are actually just doing the same as your 'left-to-right' loop in reverse order. To really get the 'right-to-left' pass right you have to have your i and j indices moving in different directions.



So your conditional statement in this section should look like:



if i-3>=0 and j+3<7:
if (llista[i][j]==1 and llista[i-1][j+1]==1 and llista[i-2][j+2]==1 and llista[i-3][j+3]==1) or (llista[i][j]==2 and llista[i-1][j+1]==2 and llista[i-2][j+2]==2 and llista[i-3][j+3]==2 ):
print("There is at least one right to left diagonal")


There are a ton of optimizations you could use by importing libraries like numpy or itertools as AResem showed. That answer is not entirely correct though for the following reason.



When you say return True, k you are not exercising any control over the value of k because it was used in the list comprehension just above and will just have the value of the last item it iterated over. So when your function finds a diagonal it reports the wrong number about two thirds of the time.



Here is an edited function that gives the correct results:



def check_diagonals(matrix):
for offset in range(-2, 4):
diag = matrix.diagonal(offset=offset)

# Here you can create a tuple of numbers with the number of times they are repeated.
# This allows you to keep your k and g values associated.
repeat_groups = [(k, sum(1 for _ in g)) for k, g in groupby(diag)]

# By using the built-in max function with the 'key' keyword, you can find
# the maximum number of repeats and return the number associated with that.
num, max_repeats = max(repeat_groups, key=lambda item: item[1])
if max_repeats >= 4:
return True, num
return False, None


If you run this function with print statements added you can get output like the following:



Matrix: 
[[1 0 2 2 1 0 1]
[0 2 0 2 1 1 1]
[2 2 0 0 0 0 1]
[0 0 2 2 0 2 2]
[2 1 1 1 1 1 0]
[2 2 0 2 1 0 2]]

offset -2
diag [2 0 1 2]
repeat_groups [(2, 1), (0, 1), (1, 1), (2, 1)]
num, max_repeats 2 1

offset -1
diag [0 2 2 1 1]
repeat_groups [(0, 1), (2, 2), (1, 2)]
num, max_repeats 2 2

offset 0
diag [1 2 0 2 1 0]
repeat_groups [(1, 1), (2, 1), (0, 1), (2, 1), (1, 1), (0, 1)]
num, max_repeats 1 1

offset 1
diag [0 0 0 0 1 2]
repeat_groups [(0, 4), (1, 1), (2, 1)]
num, max_repeats 0 4
(True, 0)
There is at least one left to right diagonal: 0's' # Correct!


If you want to ignore diagonals of zeros, you can easily add an extra condition, e.g.



if max_repeats >= 4 and num != 0:
return True, num


You could try and recreate this without using numpy if you wanted.






share|improve this answer


























  • Thanks for ur help berkelem I really appreciate the time u spend helping me :)

    – RiesenChicken
    Nov 22 '18 at 14:37



















0














Perhaps you are not getting the right answer because of the way you parsed your conditional statements.
You should have



if cond1 or cond2:
# do something


with the conditions contained in parentheses (). At the moment only your second condition is contained in parentheses.
Try the following:



if (matrix[i][j]==1 and matrix[i+1][j+1]==1 and matrix[i+2][j+2]==1 and matrix[i+3][j+3]==1)  or (matrix[i][j]==2 and matrix[i+1][j+1]==2 and matrix[i+2][j+2]==2 and matrix[i+3][j+3]==2 ):
print("There is at least one left to right diagonal")





share|improve this answer
























  • I changed that and sometimes it says that there is a diagonal even if is not there.

    – RiesenChicken
    Nov 21 '18 at 22:08






  • 1





    Could you post more of your code? It should help pinpoint where the problem is. Otherwise we're just guessing where the problem might be.

    – berkelem
    Nov 21 '18 at 22:20











  • done, i really apreciate ur help

    – RiesenChicken
    Nov 22 '18 at 5:39











  • I posted another answer below. I initially copied the wrong code so you have a corrected version of AResem's answer as well as a correction for your own code.

    – berkelem
    Nov 22 '18 at 12:56



















0














You may consider using numpy for this problem. Here goes some code to get you started.



import numpy as np
from itertools import groupby

def check_diagonals(matrix):
for offset in range(-2, 4):
diag = matrix.diagonal(offset=offset)
if max([sum(1 for _ in g) for k, g in groupby(diag)]) >= 4:
return True, k
return False, None

# random test matrix
matrix = np.random.randint(0, 3, 6 * 7)
matrix = matrix.reshape(6,7)

# left to right check
resp_tuple = check_diagonals(matrix)
if resp_tuple[0]:
print("There is at least one left to right diagonal: {}'s'".format(resp_tuple[1]))
else:
# right to left
resp_tuple = check_diagonals(np.fliplr(matrix))
if resp_tuple[0]:
print("There is at least one right to left diagonal: {}'s'".format(resp_tuple[1]))
else:
# No diagonals
print('No diagonals')





share|improve this answer
























  • Thnak you, but, like I said using numpy is not an option because I'm new at coding and i must understand how to find it without the numpy function, only using lists. Thanks

    – RiesenChicken
    Nov 22 '18 at 5:27












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53420933%2ffind-diagonals-in-a-python-matrix-using-lists%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














If you consider the logic of your 'right-to-left' loop, you are actually just doing the same as your 'left-to-right' loop in reverse order. To really get the 'right-to-left' pass right you have to have your i and j indices moving in different directions.



So your conditional statement in this section should look like:



if i-3>=0 and j+3<7:
if (llista[i][j]==1 and llista[i-1][j+1]==1 and llista[i-2][j+2]==1 and llista[i-3][j+3]==1) or (llista[i][j]==2 and llista[i-1][j+1]==2 and llista[i-2][j+2]==2 and llista[i-3][j+3]==2 ):
print("There is at least one right to left diagonal")


There are a ton of optimizations you could use by importing libraries like numpy or itertools as AResem showed. That answer is not entirely correct though for the following reason.



When you say return True, k you are not exercising any control over the value of k because it was used in the list comprehension just above and will just have the value of the last item it iterated over. So when your function finds a diagonal it reports the wrong number about two thirds of the time.



Here is an edited function that gives the correct results:



def check_diagonals(matrix):
for offset in range(-2, 4):
diag = matrix.diagonal(offset=offset)

# Here you can create a tuple of numbers with the number of times they are repeated.
# This allows you to keep your k and g values associated.
repeat_groups = [(k, sum(1 for _ in g)) for k, g in groupby(diag)]

# By using the built-in max function with the 'key' keyword, you can find
# the maximum number of repeats and return the number associated with that.
num, max_repeats = max(repeat_groups, key=lambda item: item[1])
if max_repeats >= 4:
return True, num
return False, None


If you run this function with print statements added you can get output like the following:



Matrix: 
[[1 0 2 2 1 0 1]
[0 2 0 2 1 1 1]
[2 2 0 0 0 0 1]
[0 0 2 2 0 2 2]
[2 1 1 1 1 1 0]
[2 2 0 2 1 0 2]]

offset -2
diag [2 0 1 2]
repeat_groups [(2, 1), (0, 1), (1, 1), (2, 1)]
num, max_repeats 2 1

offset -1
diag [0 2 2 1 1]
repeat_groups [(0, 1), (2, 2), (1, 2)]
num, max_repeats 2 2

offset 0
diag [1 2 0 2 1 0]
repeat_groups [(1, 1), (2, 1), (0, 1), (2, 1), (1, 1), (0, 1)]
num, max_repeats 1 1

offset 1
diag [0 0 0 0 1 2]
repeat_groups [(0, 4), (1, 1), (2, 1)]
num, max_repeats 0 4
(True, 0)
There is at least one left to right diagonal: 0's' # Correct!


If you want to ignore diagonals of zeros, you can easily add an extra condition, e.g.



if max_repeats >= 4 and num != 0:
return True, num


You could try and recreate this without using numpy if you wanted.






share|improve this answer


























  • Thanks for ur help berkelem I really appreciate the time u spend helping me :)

    – RiesenChicken
    Nov 22 '18 at 14:37
















0














If you consider the logic of your 'right-to-left' loop, you are actually just doing the same as your 'left-to-right' loop in reverse order. To really get the 'right-to-left' pass right you have to have your i and j indices moving in different directions.



So your conditional statement in this section should look like:



if i-3>=0 and j+3<7:
if (llista[i][j]==1 and llista[i-1][j+1]==1 and llista[i-2][j+2]==1 and llista[i-3][j+3]==1) or (llista[i][j]==2 and llista[i-1][j+1]==2 and llista[i-2][j+2]==2 and llista[i-3][j+3]==2 ):
print("There is at least one right to left diagonal")


There are a ton of optimizations you could use by importing libraries like numpy or itertools as AResem showed. That answer is not entirely correct though for the following reason.



When you say return True, k you are not exercising any control over the value of k because it was used in the list comprehension just above and will just have the value of the last item it iterated over. So when your function finds a diagonal it reports the wrong number about two thirds of the time.



Here is an edited function that gives the correct results:



def check_diagonals(matrix):
for offset in range(-2, 4):
diag = matrix.diagonal(offset=offset)

# Here you can create a tuple of numbers with the number of times they are repeated.
# This allows you to keep your k and g values associated.
repeat_groups = [(k, sum(1 for _ in g)) for k, g in groupby(diag)]

# By using the built-in max function with the 'key' keyword, you can find
# the maximum number of repeats and return the number associated with that.
num, max_repeats = max(repeat_groups, key=lambda item: item[1])
if max_repeats >= 4:
return True, num
return False, None


If you run this function with print statements added you can get output like the following:



Matrix: 
[[1 0 2 2 1 0 1]
[0 2 0 2 1 1 1]
[2 2 0 0 0 0 1]
[0 0 2 2 0 2 2]
[2 1 1 1 1 1 0]
[2 2 0 2 1 0 2]]

offset -2
diag [2 0 1 2]
repeat_groups [(2, 1), (0, 1), (1, 1), (2, 1)]
num, max_repeats 2 1

offset -1
diag [0 2 2 1 1]
repeat_groups [(0, 1), (2, 2), (1, 2)]
num, max_repeats 2 2

offset 0
diag [1 2 0 2 1 0]
repeat_groups [(1, 1), (2, 1), (0, 1), (2, 1), (1, 1), (0, 1)]
num, max_repeats 1 1

offset 1
diag [0 0 0 0 1 2]
repeat_groups [(0, 4), (1, 1), (2, 1)]
num, max_repeats 0 4
(True, 0)
There is at least one left to right diagonal: 0's' # Correct!


If you want to ignore diagonals of zeros, you can easily add an extra condition, e.g.



if max_repeats >= 4 and num != 0:
return True, num


You could try and recreate this without using numpy if you wanted.






share|improve this answer


























  • Thanks for ur help berkelem I really appreciate the time u spend helping me :)

    – RiesenChicken
    Nov 22 '18 at 14:37














0












0








0







If you consider the logic of your 'right-to-left' loop, you are actually just doing the same as your 'left-to-right' loop in reverse order. To really get the 'right-to-left' pass right you have to have your i and j indices moving in different directions.



So your conditional statement in this section should look like:



if i-3>=0 and j+3<7:
if (llista[i][j]==1 and llista[i-1][j+1]==1 and llista[i-2][j+2]==1 and llista[i-3][j+3]==1) or (llista[i][j]==2 and llista[i-1][j+1]==2 and llista[i-2][j+2]==2 and llista[i-3][j+3]==2 ):
print("There is at least one right to left diagonal")


There are a ton of optimizations you could use by importing libraries like numpy or itertools as AResem showed. That answer is not entirely correct though for the following reason.



When you say return True, k you are not exercising any control over the value of k because it was used in the list comprehension just above and will just have the value of the last item it iterated over. So when your function finds a diagonal it reports the wrong number about two thirds of the time.



Here is an edited function that gives the correct results:



def check_diagonals(matrix):
for offset in range(-2, 4):
diag = matrix.diagonal(offset=offset)

# Here you can create a tuple of numbers with the number of times they are repeated.
# This allows you to keep your k and g values associated.
repeat_groups = [(k, sum(1 for _ in g)) for k, g in groupby(diag)]

# By using the built-in max function with the 'key' keyword, you can find
# the maximum number of repeats and return the number associated with that.
num, max_repeats = max(repeat_groups, key=lambda item: item[1])
if max_repeats >= 4:
return True, num
return False, None


If you run this function with print statements added you can get output like the following:



Matrix: 
[[1 0 2 2 1 0 1]
[0 2 0 2 1 1 1]
[2 2 0 0 0 0 1]
[0 0 2 2 0 2 2]
[2 1 1 1 1 1 0]
[2 2 0 2 1 0 2]]

offset -2
diag [2 0 1 2]
repeat_groups [(2, 1), (0, 1), (1, 1), (2, 1)]
num, max_repeats 2 1

offset -1
diag [0 2 2 1 1]
repeat_groups [(0, 1), (2, 2), (1, 2)]
num, max_repeats 2 2

offset 0
diag [1 2 0 2 1 0]
repeat_groups [(1, 1), (2, 1), (0, 1), (2, 1), (1, 1), (0, 1)]
num, max_repeats 1 1

offset 1
diag [0 0 0 0 1 2]
repeat_groups [(0, 4), (1, 1), (2, 1)]
num, max_repeats 0 4
(True, 0)
There is at least one left to right diagonal: 0's' # Correct!


If you want to ignore diagonals of zeros, you can easily add an extra condition, e.g.



if max_repeats >= 4 and num != 0:
return True, num


You could try and recreate this without using numpy if you wanted.






share|improve this answer















If you consider the logic of your 'right-to-left' loop, you are actually just doing the same as your 'left-to-right' loop in reverse order. To really get the 'right-to-left' pass right you have to have your i and j indices moving in different directions.



So your conditional statement in this section should look like:



if i-3>=0 and j+3<7:
if (llista[i][j]==1 and llista[i-1][j+1]==1 and llista[i-2][j+2]==1 and llista[i-3][j+3]==1) or (llista[i][j]==2 and llista[i-1][j+1]==2 and llista[i-2][j+2]==2 and llista[i-3][j+3]==2 ):
print("There is at least one right to left diagonal")


There are a ton of optimizations you could use by importing libraries like numpy or itertools as AResem showed. That answer is not entirely correct though for the following reason.



When you say return True, k you are not exercising any control over the value of k because it was used in the list comprehension just above and will just have the value of the last item it iterated over. So when your function finds a diagonal it reports the wrong number about two thirds of the time.



Here is an edited function that gives the correct results:



def check_diagonals(matrix):
for offset in range(-2, 4):
diag = matrix.diagonal(offset=offset)

# Here you can create a tuple of numbers with the number of times they are repeated.
# This allows you to keep your k and g values associated.
repeat_groups = [(k, sum(1 for _ in g)) for k, g in groupby(diag)]

# By using the built-in max function with the 'key' keyword, you can find
# the maximum number of repeats and return the number associated with that.
num, max_repeats = max(repeat_groups, key=lambda item: item[1])
if max_repeats >= 4:
return True, num
return False, None


If you run this function with print statements added you can get output like the following:



Matrix: 
[[1 0 2 2 1 0 1]
[0 2 0 2 1 1 1]
[2 2 0 0 0 0 1]
[0 0 2 2 0 2 2]
[2 1 1 1 1 1 0]
[2 2 0 2 1 0 2]]

offset -2
diag [2 0 1 2]
repeat_groups [(2, 1), (0, 1), (1, 1), (2, 1)]
num, max_repeats 2 1

offset -1
diag [0 2 2 1 1]
repeat_groups [(0, 1), (2, 2), (1, 2)]
num, max_repeats 2 2

offset 0
diag [1 2 0 2 1 0]
repeat_groups [(1, 1), (2, 1), (0, 1), (2, 1), (1, 1), (0, 1)]
num, max_repeats 1 1

offset 1
diag [0 0 0 0 1 2]
repeat_groups [(0, 4), (1, 1), (2, 1)]
num, max_repeats 0 4
(True, 0)
There is at least one left to right diagonal: 0's' # Correct!


If you want to ignore diagonals of zeros, you can easily add an extra condition, e.g.



if max_repeats >= 4 and num != 0:
return True, num


You could try and recreate this without using numpy if you wanted.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 22 '18 at 12:55

























answered Nov 22 '18 at 10:09









berkelemberkelem

9632721




9632721













  • Thanks for ur help berkelem I really appreciate the time u spend helping me :)

    – RiesenChicken
    Nov 22 '18 at 14:37



















  • Thanks for ur help berkelem I really appreciate the time u spend helping me :)

    – RiesenChicken
    Nov 22 '18 at 14:37

















Thanks for ur help berkelem I really appreciate the time u spend helping me :)

– RiesenChicken
Nov 22 '18 at 14:37





Thanks for ur help berkelem I really appreciate the time u spend helping me :)

– RiesenChicken
Nov 22 '18 at 14:37













0














Perhaps you are not getting the right answer because of the way you parsed your conditional statements.
You should have



if cond1 or cond2:
# do something


with the conditions contained in parentheses (). At the moment only your second condition is contained in parentheses.
Try the following:



if (matrix[i][j]==1 and matrix[i+1][j+1]==1 and matrix[i+2][j+2]==1 and matrix[i+3][j+3]==1)  or (matrix[i][j]==2 and matrix[i+1][j+1]==2 and matrix[i+2][j+2]==2 and matrix[i+3][j+3]==2 ):
print("There is at least one left to right diagonal")





share|improve this answer
























  • I changed that and sometimes it says that there is a diagonal even if is not there.

    – RiesenChicken
    Nov 21 '18 at 22:08






  • 1





    Could you post more of your code? It should help pinpoint where the problem is. Otherwise we're just guessing where the problem might be.

    – berkelem
    Nov 21 '18 at 22:20











  • done, i really apreciate ur help

    – RiesenChicken
    Nov 22 '18 at 5:39











  • I posted another answer below. I initially copied the wrong code so you have a corrected version of AResem's answer as well as a correction for your own code.

    – berkelem
    Nov 22 '18 at 12:56
















0














Perhaps you are not getting the right answer because of the way you parsed your conditional statements.
You should have



if cond1 or cond2:
# do something


with the conditions contained in parentheses (). At the moment only your second condition is contained in parentheses.
Try the following:



if (matrix[i][j]==1 and matrix[i+1][j+1]==1 and matrix[i+2][j+2]==1 and matrix[i+3][j+3]==1)  or (matrix[i][j]==2 and matrix[i+1][j+1]==2 and matrix[i+2][j+2]==2 and matrix[i+3][j+3]==2 ):
print("There is at least one left to right diagonal")





share|improve this answer
























  • I changed that and sometimes it says that there is a diagonal even if is not there.

    – RiesenChicken
    Nov 21 '18 at 22:08






  • 1





    Could you post more of your code? It should help pinpoint where the problem is. Otherwise we're just guessing where the problem might be.

    – berkelem
    Nov 21 '18 at 22:20











  • done, i really apreciate ur help

    – RiesenChicken
    Nov 22 '18 at 5:39











  • I posted another answer below. I initially copied the wrong code so you have a corrected version of AResem's answer as well as a correction for your own code.

    – berkelem
    Nov 22 '18 at 12:56














0












0








0







Perhaps you are not getting the right answer because of the way you parsed your conditional statements.
You should have



if cond1 or cond2:
# do something


with the conditions contained in parentheses (). At the moment only your second condition is contained in parentheses.
Try the following:



if (matrix[i][j]==1 and matrix[i+1][j+1]==1 and matrix[i+2][j+2]==1 and matrix[i+3][j+3]==1)  or (matrix[i][j]==2 and matrix[i+1][j+1]==2 and matrix[i+2][j+2]==2 and matrix[i+3][j+3]==2 ):
print("There is at least one left to right diagonal")





share|improve this answer













Perhaps you are not getting the right answer because of the way you parsed your conditional statements.
You should have



if cond1 or cond2:
# do something


with the conditions contained in parentheses (). At the moment only your second condition is contained in parentheses.
Try the following:



if (matrix[i][j]==1 and matrix[i+1][j+1]==1 and matrix[i+2][j+2]==1 and matrix[i+3][j+3]==1)  or (matrix[i][j]==2 and matrix[i+1][j+1]==2 and matrix[i+2][j+2]==2 and matrix[i+3][j+3]==2 ):
print("There is at least one left to right diagonal")






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 21 '18 at 21:59









berkelemberkelem

9632721




9632721













  • I changed that and sometimes it says that there is a diagonal even if is not there.

    – RiesenChicken
    Nov 21 '18 at 22:08






  • 1





    Could you post more of your code? It should help pinpoint where the problem is. Otherwise we're just guessing where the problem might be.

    – berkelem
    Nov 21 '18 at 22:20











  • done, i really apreciate ur help

    – RiesenChicken
    Nov 22 '18 at 5:39











  • I posted another answer below. I initially copied the wrong code so you have a corrected version of AResem's answer as well as a correction for your own code.

    – berkelem
    Nov 22 '18 at 12:56



















  • I changed that and sometimes it says that there is a diagonal even if is not there.

    – RiesenChicken
    Nov 21 '18 at 22:08






  • 1





    Could you post more of your code? It should help pinpoint where the problem is. Otherwise we're just guessing where the problem might be.

    – berkelem
    Nov 21 '18 at 22:20











  • done, i really apreciate ur help

    – RiesenChicken
    Nov 22 '18 at 5:39











  • I posted another answer below. I initially copied the wrong code so you have a corrected version of AResem's answer as well as a correction for your own code.

    – berkelem
    Nov 22 '18 at 12:56

















I changed that and sometimes it says that there is a diagonal even if is not there.

– RiesenChicken
Nov 21 '18 at 22:08





I changed that and sometimes it says that there is a diagonal even if is not there.

– RiesenChicken
Nov 21 '18 at 22:08




1




1





Could you post more of your code? It should help pinpoint where the problem is. Otherwise we're just guessing where the problem might be.

– berkelem
Nov 21 '18 at 22:20





Could you post more of your code? It should help pinpoint where the problem is. Otherwise we're just guessing where the problem might be.

– berkelem
Nov 21 '18 at 22:20













done, i really apreciate ur help

– RiesenChicken
Nov 22 '18 at 5:39





done, i really apreciate ur help

– RiesenChicken
Nov 22 '18 at 5:39













I posted another answer below. I initially copied the wrong code so you have a corrected version of AResem's answer as well as a correction for your own code.

– berkelem
Nov 22 '18 at 12:56





I posted another answer below. I initially copied the wrong code so you have a corrected version of AResem's answer as well as a correction for your own code.

– berkelem
Nov 22 '18 at 12:56











0














You may consider using numpy for this problem. Here goes some code to get you started.



import numpy as np
from itertools import groupby

def check_diagonals(matrix):
for offset in range(-2, 4):
diag = matrix.diagonal(offset=offset)
if max([sum(1 for _ in g) for k, g in groupby(diag)]) >= 4:
return True, k
return False, None

# random test matrix
matrix = np.random.randint(0, 3, 6 * 7)
matrix = matrix.reshape(6,7)

# left to right check
resp_tuple = check_diagonals(matrix)
if resp_tuple[0]:
print("There is at least one left to right diagonal: {}'s'".format(resp_tuple[1]))
else:
# right to left
resp_tuple = check_diagonals(np.fliplr(matrix))
if resp_tuple[0]:
print("There is at least one right to left diagonal: {}'s'".format(resp_tuple[1]))
else:
# No diagonals
print('No diagonals')





share|improve this answer
























  • Thnak you, but, like I said using numpy is not an option because I'm new at coding and i must understand how to find it without the numpy function, only using lists. Thanks

    – RiesenChicken
    Nov 22 '18 at 5:27
















0














You may consider using numpy for this problem. Here goes some code to get you started.



import numpy as np
from itertools import groupby

def check_diagonals(matrix):
for offset in range(-2, 4):
diag = matrix.diagonal(offset=offset)
if max([sum(1 for _ in g) for k, g in groupby(diag)]) >= 4:
return True, k
return False, None

# random test matrix
matrix = np.random.randint(0, 3, 6 * 7)
matrix = matrix.reshape(6,7)

# left to right check
resp_tuple = check_diagonals(matrix)
if resp_tuple[0]:
print("There is at least one left to right diagonal: {}'s'".format(resp_tuple[1]))
else:
# right to left
resp_tuple = check_diagonals(np.fliplr(matrix))
if resp_tuple[0]:
print("There is at least one right to left diagonal: {}'s'".format(resp_tuple[1]))
else:
# No diagonals
print('No diagonals')





share|improve this answer
























  • Thnak you, but, like I said using numpy is not an option because I'm new at coding and i must understand how to find it without the numpy function, only using lists. Thanks

    – RiesenChicken
    Nov 22 '18 at 5:27














0












0








0







You may consider using numpy for this problem. Here goes some code to get you started.



import numpy as np
from itertools import groupby

def check_diagonals(matrix):
for offset in range(-2, 4):
diag = matrix.diagonal(offset=offset)
if max([sum(1 for _ in g) for k, g in groupby(diag)]) >= 4:
return True, k
return False, None

# random test matrix
matrix = np.random.randint(0, 3, 6 * 7)
matrix = matrix.reshape(6,7)

# left to right check
resp_tuple = check_diagonals(matrix)
if resp_tuple[0]:
print("There is at least one left to right diagonal: {}'s'".format(resp_tuple[1]))
else:
# right to left
resp_tuple = check_diagonals(np.fliplr(matrix))
if resp_tuple[0]:
print("There is at least one right to left diagonal: {}'s'".format(resp_tuple[1]))
else:
# No diagonals
print('No diagonals')





share|improve this answer













You may consider using numpy for this problem. Here goes some code to get you started.



import numpy as np
from itertools import groupby

def check_diagonals(matrix):
for offset in range(-2, 4):
diag = matrix.diagonal(offset=offset)
if max([sum(1 for _ in g) for k, g in groupby(diag)]) >= 4:
return True, k
return False, None

# random test matrix
matrix = np.random.randint(0, 3, 6 * 7)
matrix = matrix.reshape(6,7)

# left to right check
resp_tuple = check_diagonals(matrix)
if resp_tuple[0]:
print("There is at least one left to right diagonal: {}'s'".format(resp_tuple[1]))
else:
# right to left
resp_tuple = check_diagonals(np.fliplr(matrix))
if resp_tuple[0]:
print("There is at least one right to left diagonal: {}'s'".format(resp_tuple[1]))
else:
# No diagonals
print('No diagonals')






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 22 '18 at 0:19









AResemAResem

1114




1114













  • Thnak you, but, like I said using numpy is not an option because I'm new at coding and i must understand how to find it without the numpy function, only using lists. Thanks

    – RiesenChicken
    Nov 22 '18 at 5:27



















  • Thnak you, but, like I said using numpy is not an option because I'm new at coding and i must understand how to find it without the numpy function, only using lists. Thanks

    – RiesenChicken
    Nov 22 '18 at 5:27

















Thnak you, but, like I said using numpy is not an option because I'm new at coding and i must understand how to find it without the numpy function, only using lists. Thanks

– RiesenChicken
Nov 22 '18 at 5:27





Thnak you, but, like I said using numpy is not an option because I'm new at coding and i must understand how to find it without the numpy function, only using lists. Thanks

– RiesenChicken
Nov 22 '18 at 5:27


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53420933%2ffind-diagonals-in-a-python-matrix-using-lists%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to pass form data using jquery Ajax to insert data in database?

National Museum of Racing and Hall of Fame

Guess what letter conforming each word