How to compare the elements of a nested list? - python-3.x

I have some kind of matrix:
[[1,2,3],[1,2,3],[0,2,1],[1,2,3]] and I would like to be able to determine how many times I have the sequence 1,2,3 diagonally, vertically and horizontally but I have problems of index out of range for the last two loops. Thank you in advance for your answers!!
lista = [[1,2,3],[1,2,3],[0,2,1],[1,2,3]]
compteur_horizontal = 0
for i in range(len(lista)):
for c in range(len(lista[i])-2):
if lista[i][c] == 1 and lista[i][c+1] == 2 and lista[i][c+2] == 3:
compteur_horizontal += 1
print("ok")
compteur_vertical = 0
for c in range(len(lista)):
for j in range(len(lista[c])):
print(lista[j][c])
compteur_diagonale = 0
for j in range(len(lista)):
print(lista[i][i])
For the first counter, I would like it to be 3 since we have 3 times the sequence 1,2,3 horizontally. For the second counter, I would like it to be 0 because vertically there is no 1,2,3 sequence. And I'm waiting for a counter with 0 also since there's no 1,2,3 sequence in diagonal

Your code will not work even if you correct the current error. You need to change j and c in the second loop to resolve the error.
For horizontal and vertical here's the code. I'll add how to count diagonal ones later.
#lista = [[1, 2, 3],[1, 2, 3],[0, 2, 1],[1, 2, 3]]
lista = [[1,2,2],
[1,2,4],
[4,2,3],
[5,6,3]]
ptrn = [1, 2, 3]
# returns True is lst (1d array) has ptrn (1d array).
# e.g. lst[1,2,4,6,1,2,3,7], ptrn=[1,2,3] return True
# e.g. lst[1,2,4,6,1,4,3,7], ptrn=[1,2,3] return False
def is_pattern_in_a_list(lst, ptrn):
if ptrn[0] in lst:
idx = lst.index(ptrn[0])
for i in range(1, len(ptrn)):
if idx + i < len(lst):
if ptrn[i] != lst[idx+i]:
return False
else:
return False
return True
else:
return False
# counting horizontal occurances
count_h = 0
for row in lista:
if is_pattern_in_a_list(row, ptrn):
count_h += 1
# counting vertical occurances
# we first transpose the 2d array and use the same
# method of counting horizontal occurances.
def transpose_2d_array(a):
return [[a[j][i] for j in range(len(a))] for i in range(len(a[0]))]
lista_transpose = transpose_2d_array(lista)
count_v = 0
for row in lista_transpose:
if is_pattern_in_a_list(row, ptrn):
count_v += 1
# for diagonal occurances first we need to extract the diagonals
# with len >= len(ptrn).
# diagonals for the upper right triangle of the matrix:
count_d = 0
for i in range(len(lista[0])):
diag = []
j = 0
k = i
while j < len(lista)-i and k < len(lista[0]):
diag.append(lista[j][k])
j += 1
k += 1
if is_pattern_in_a_list(diag, ptrn):
count_d += 1
# diagonals for the lower left triangle of the matrix
i = len(lista) - 1
while i >= 1:
j = i
k = 0
diag = []
while j < len(lista) and k <= len(lista)+1-i:
diag.append(lista[j][k])
j += 1
k += 1
i -= 1
if is_pattern_in_a_list(diag, ptrn):
count_d += 1
print(diag)
print("Horizontal %d" % count_h)
print("Vertical %d" % count_v)
print("Diagonal %d" % count_d)

Related

How to sort elements in 2d array like pie chart or sunburst chart in python?

I have 2d array
I wanted to divide 5 values in this array such that it should be kind of structure like sunburst or pie chart.
I will be very thankful if you could provide python code or idea to do so, any related suggestions are also welcome. Thank you!
This may be the way that you can divide your square grid according to percentages into five types.
While I am not sure how to do it in a circular way.
mat = np.reshape(list(np.random.choice(a=[i for i in range(1,6)], size=30*30, p=[0.326 ,0.02 ,0.11,0.053,0.491])), (30,30))
mat2= [[0 for col in range(30)] for row in range(30)]
lst=[0,0,0,0,0]
for i in range(30):
for j in range(30):
lst[mat[i][j]-1] += 1
print(lst)
lst2=[0,0,0,0,0]
for i in range(len(lst)):
lst2[i] = [lst[i], i+1]
print(lst2)
print(sorted(lst2))
lst3=sorted(lst2)
def action(n,v):
count = n
for j in range(len(mat2)//2,-1,-1):
for i in range(0,len(mat2)//2):
if mat2[i][j]==0 and count!=0:
mat2[i][j] = v
count -= 1
for j in range(len(mat2)//2):
for i in range(len(mat2)//2,len(mat2)):
if mat2[i][j]==0 and count!=0:
mat2[i][j] = v
count -= 1
for j in range(len(mat2)//2,len(mat2)):
for i in range(len(mat2)//2,len(mat2)):
if mat2[i][j]==0 and count!=0:
mat2[i][j] = v
count -= 1
for i in range(len(mat2)//2,-1,-1):
for j in range(len(mat2)//2,len(mat2),-1):
if mat2[i][j]==0 and count!=0:
mat2[i][j] = v
count -= 1
for i in range(len(mat2)):
for j in range(len(mat2)):
if mat2[i][j]==0 and count != 0:
mat2[i][j]=v
count-=1
for val in lst3:
action(val[0],val[1])
for i in mat2:
print(i)

Max Points on a Line with python 3

algorithm question:
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
Example 1:
Input: [[1,1],[2,2],[3,3]]
Output: 3
Explanation:
^
|
| o
| o
| o
+------------->
0 1 2 3 4
Example 2:
Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
Output: 4
the working python 3 code is below:
wondering
snippet 1 d[slope] = d.get(slope, 1) + 1 is working
but why this snippet 2 is not working correctly for example 2 even though snippet 1 and 2 are the same
if slope in d:
d[slope] += 1
else:
d[slope] = 1
def gcd(self, a, b):
if b == 0:
return a
return self.gcd(b, a%b)
def get_slope(self, p1, p2):
dx = p1[0] - p2[0]
dy = p1[1] - p2[1]
c = self.gcd(dx, dy)
dx /= c
dy /= c
return str(dy) + "/" + str(dx)
def is_same_points(self, p1:List[int], p2:List[int]):
return p1[0] == p2[0] and p1[1] == p2[1]
def maxPoints(self, points: List[List[int]]) -> int:
if not points:
return 0
n = len(points)
count = 1
for i in range(0, n):
d = {}
duped = 0
localmax = 1
p1 = points[i]
for j in range(i+1, n):
p2 = points[j]
if self.is_same_points(p1, p2):
duped += 1
else:
slope = self.get_slope(p1, p2)
# 1) not work: output is 3 in example 2
# if slope in d:
# d[slope] += 1
# else:
# d[slope] = 1
# 2) works: correct output 4 for example 2
d[slope] = d.get(slope, 1) + 1
localmax = max(localmax, d[slope]);
count = max(count, localmax + duped)
return count
Interesting problem and nice solution.
The reason why the commented out code doesn't work is because of that:
else:
d[slope] = 1 ## correct would be d[slope] = 2
Every 2 points are on the same line, you are counting only one point for the first two p1 p2, thus you get one less in the final answer.

Where should I put the count in this tim sort algorithm, to accurately compare runtime to other algorithms

I've written a Timsort sorting algorithm for a computer science class, I would like to be able to compare the runtime to other similar algorithms, such as merge sort for instance. However, I am not sure where I should put the count (ie: count +=1)within the code to have an accurate run time. Any help would be much appreciated.
RUN = 32
def insertion_sort(arr, left, right):
for i in range(left + 1, right + 1):
temp = arr[i]
j = i - 1
while (arr[j] > temp and j >= left):
arr[j + 1] = arr[j]
arr[j] = temp
j -= 1
def merge(arr, left, right, count):
c = 0
index = count
length = len(left) + len(right)
while left and right:
if left[0] < right[0]:
arr[index] = left.pop(0)
c += 1
index += 1
else:
arr[index] = right.pop(0)
c += 1
index += 1
if len(left) == 0:
while c < length:
arr[index] = right.pop(0)
c += 1
index += 1
elif len(right) == 0:
while c < length:
arr[index] = left.pop(0)
c += 1
index += 1
def tim_sort(arr):
n = len(arr)
for i in range(0, n, RUN):
insertion_sort(arr, i, min((i + (RUN - 1)), (n - 1)))
size = RUN
while size < n:
for left in range(0, n, 2 * size):
if (left + size > n):
merge(arr, arr[left:n], [], left)
else:
left_sub_arr = arr[left:(left + size)]
right_sub_arr = arr[(left + size):min((left + 2 * size), n)]
merge(arr, left_sub_arr, right_sub_arr, left)
size *= 2
return arr

Start counting indexes from 1 instead of 0 of a list

I created a program to get the the max value of a list and the position of its occurrences (list starting at indexing with 1 not 0) but I can't manage to find any useful solutions.
The input is always a string of numbers divided by zero.
This is my code:
inp = list(map(int,input().split()))
m = max(inp)
count = inp.count(m)
print(m)
def maxelements(seq): # #SilentGhost
return [i for i, j in enumerate(seq) if j == m]
print(maxelements(inp))
I expect to output the maximum value and then all the positions of its occurrences. (also is it possible to do without brackets as in the example below?)
Input: 4 56 43 45 2 56 8
Output: 56
2 6
If you want to shift index values, you could just do
return [i + 1 for i, j in enumerate(seq) if j == m]
more generally any transformation of i or j!
def f(i, j):
# do whatever you want, and return something
return i + 1
return [f(i, j) for i, j in enumerate(seq) if j == m]
Without brackets, as a string:
return " ".join(str(i + 1) for i, j in enumerate(seq) if j==m)
Specifiy start=1 with enumerate():
>>> l = [4, 56, 43, 45, 2, 56, 8]
>>> max_num = max(l)
>>> [i for i, e in enumerate(l, start=1) if e == max_num]
[2, 6]
By default enumerate() uses start=0, because indices start at 0.

Can't figure out why my program is not creating a list

I need to compare each number in a list back to back, subtract, and add the outcome to a new list.
so
list1[1]-[0] = list2 [0]
list1[2]-[1] = list2 [1]
etc.
But I can't get it to do this.
Here is my block
change = []
index = 0
popyear_up = 1
popyear_low = 0
while index < len(data_numbers):
#for i in range, len(data_numbers:
difference = data_numbers[popyear_up] - data_numbers[popyear_low]
change.append(difference)
popyear_up += 1
popyear_low += 1
index += 1
The uncommented "while" line right now returns
difference = data_numbers[popyear_up] - data_numbers[popyear_low]
IndexError: list index out of range
The commented line only does [1]-[0] and [2]-[1], but does them correctly and appends them to change[]
I have no idea why it only does those 2. But for the first one I feel it has something to do with the length of my main list of data and the length of the list I'm asking it to create.
So two different issues, and I can't for the life of me figure out what I'm missing.
Full code if necessary
file = input('File to open: ')
infile = open(file, 'r')
source_file = infile.readlines()
infile.close()
index = 0
while index < len(source_file):
source_file[index] = source_file[index].rstrip('\n')
index += 1
data_numbers = [int(i) for i in source_file]
change = []
index = 0
popyear_up = 1
popyear_low = 0
while index < len(data_numbers):
#for i in range, len(data_numbers:
difference = data_numbers[popyear_up] - data_numbers[popyear_low]
change.append(difference)
popyear_up += 1
popyear_low += 1
index += 1
#start_year = 1950
#change_sum = float(sum(change))
#change_average = change_sum / len(change)
#max_change = start_year + change.index(max(n)) + 1
#min _change = start_year + change.index(min(n)) + 1
#print('Average Change in Population:',change_average)
#print ('Year with most population increas:',max_change)
#print ('Year with lease population increas:',min_change)
Since your lists are of the same length and one of the indices (popyear_up) is one ahead, it will break. Instead, only go up to index < len(data_numbers) - 1.
Also, just do this:
change = []
popyear_up = 1
popyear_low = 0
for popyear_low in range(len(data_numbers) - 1):
difference = data_numbers[popyear_low + 1] - data_numbers[popyear_low]
change.append(difference)
Also, just do this:
change = [data_numbers[i + 1] - data_numbers[i] for i in range(len(data_numbers) - 1)]
Or if you want (though this is slightly less readable):
change = [y - x for x, y in zip(data_numbers, data_numbers[1:])]

Resources