i have a problem with finding the solution to make searching algorithm on a list that have various type of item, especially with nested list.
def fib(n):
if n < 1:
return 1
elif n == 1 :
return 1
else:
return fib(n-1) + fib(n-2)
def fibonaccisearch(arr,x,q):
p = 0
p += q
n = 0
while p > 0:
while fib(n) < len(arr) and p != 0:
n = n + 1
offset = -1
while (fib(n) > 1) and p > 0:
i = min(offset + fib(n-2), len(arr) - 1)
if type(arr[i]) == list:
countingx(arr[i])
z = stringdata2.count(x)
print(f"{x} found1 at index:", i,"kolom ke -",fibonaccisearch(arr[i],x,z))
arr[i] = 'this is x'
p -= 1
elif (x > arr[i]):
n = n-1
offset = i
elif (x < arr[i]):
n = n-2
elif (x == arr[i]):
print(arr[i])
print(f"{x} found2 at index :", i)
p -= 1
arr[i] = 'this is x'
while p == 1:
z = 0
z += i
while z > -1:
if arr[z] != x:
z -= 1
else:
print(f"{x} found3 at index :", z)
arr[z] = 'this is X'
z = -1
p -= 1
else:
print()
if (fib(n-1) and arr[offset + 1] == x):
p -= 1
return offset + 1
return -1
def countingx(data):
global stringdata2
global list1
stringdata1 = []
stringdata2 = []
list1 = []
stringdata1.extend(data)
while True:
if len(stringdata1) == 0:
break
elif type(stringdata1[0]) == str:
stringdata2.append(stringdata1[0])
stringdata1.pop(0)
else:
list1.extend(stringdata1[0])
stringdata1.pop(0)
stringdata1.extend(list1)
list1.clear()
arr = ['b','a', ['c', 'a'], 'd', ['a', 'e', 'c'], 'a']
x = 'a'
countingx(arr)
print(stringdata2)
q = stringdata2.count(x)
print(arr)
fibonaccisearch(arr,x,q)
this is my code i dont know whats wrong with it i completely lost my mind trying to find the solution, i try to modified it the closes i find is, the code find the way to find the 'a' in the index 2 column 1, index 4 column 0, and index 5 but skips the 'a' in the index 1, i tried to fix it but it still dont works.
I need to find the biggest sequence of zeros next to each other (up down left right).
for example in this example the function should return 6
mat = [[1,**0**,**0**,3,0],
[**0**,**0**,2,3,0],
[2,**0**,**0**,2,0],
[0,1,2,3,3],]
the zeros that i marked as bold should be the answer (6)
the solution should be implemented without any loop (using recursion)
this is what i tried so far
def question_3_b(some_list,index_cord):
y = index_cord[0]
x = index_cord[1]
list_of_nums = []
def main(some_list,index_cord):
y = index_cord[0]
x = index_cord[1]
def check_right(x,y):
if x + 1 < 0:
return 0
if some_list[y][x+1] == 0:
main(some_list,(y,x+1))
else:
return 0
def check_left(x,y):
if x -1 < 0:
return 0
if some_list[y][x - 1] == 0:
main(some_list,(y, x - 1))
def check_down(x,y):
if y + 1 < 0:
return 0
try:
if some_list[y + 1][x] == 0:
main(some_list,(y + 1, x))
except:
print("out of range")
def check_up(x,y):
counter_up = 0
if y - 1 < 0:
return 0
if some_list[y - 1][x] == 0:
counter_up += 1
main(some_list,(y - 1, x))
list_of_nums.append((x,y))
right = check_right(x,y)
down = check_down(x,y)
left = check_left(x,y)
up = check_up(x, y)
main(some_list,index_cord)
print(list_of_nums)
question_3_b(mat,(0,1))
Solution #1: classic BFS
As I mention in a comment, you can tackle this problem using BFS (Breadth First Search), it will be something like this:
# This function will give the valid adjacent positions
# of a given position according the matrix size (NxM)
def valid_adj(i, j, N, M):
adjs = [[i + 1, j], [i - 1, j], [i, j + 1], [i, j - 1]]
for a_i, a_j in adjs:
if 0 <= a_i < N and 0 <= a_j < M:
yield a_i, a_j
def biggest_zero_chunk(mat):
answer = 0
N, M = len(mat), len(mat[0])
# Mark all non zero position as visited (we are not instrested in them)
mask = [[mat[i][j] != 0 for j in range(M)] for i in range(N)]
queue = []
for i in range(N):
for j in range(M):
if mask[i][j]: # You have visited this position
continue
# Here comes the BFS
# It visits all the adjacent zeros recursively,
# count them and mark them as visited
current_ans = 1
queue = [[i,j]]
while queue:
pos_i, pos_j = queue.pop(0)
mask[pos_i][pos_j] = True
for a_i, a_j in valid_adj(pos_i, pos_j, N, M):
if mat[a_i][a_j] == 0 and not mask[a_i][a_j]:
queue.append([a_i, a_j])
current_ans += 1
answer = max(answer, current_ans)
return answer
mat = [[1,0,0,3,0],
[0,0,2,3,0],
[2,0,0,2,0],
[0,1,2,3,3],]
mat2 = [[1,0,0,3,0],
[0,0,2,3,0],
[2,0,0,0,0], # A slight modification in this row to connect two chunks
[0,1,2,3,3],]
print(biggest_zero_chunk(mat))
print(biggest_zero_chunk(mat2))
Output:
6
10
Solution #2: using only recursion (no for statements)
def count_zeros(mat, i, j, N, M):
# Base case
# Don't search zero chunks if invalid position or non zero values
if i < 0 or i >= N or j < 0 or j >= M or mat[i][j] != 0:
return 0
ans = 1 # To count the current zero we start at 1
mat[i][j] = 1 # To erase the current zero and don't count it again
ans += count_zeros(mat, i - 1, j, N, M) # Up
ans += count_zeros(mat, i + 1, j, N, M) # Down
ans += count_zeros(mat, i, j - 1, N, M) # Left
ans += count_zeros(mat, i, j + 1, N, M) # Right
return ans
def biggest_zero_chunk(mat, i = 0, j = 0, current_ans = 0):
N, M = len(mat), len(mat[0])
# Base case (last position of mat)
if i == N - 1 and j == M - 1:
return current_ans
next_j = (j + 1) % M # Move to next column, 0 if j is the last one
next_i = i + 1 if next_j == 0 else i # Move to next row if j is 0
ans = count_zeros(mat, i, j, N, M) # Count zeros from this position
current_ans = max(ans, current_ans) # Update the current answer
return biggest_zero_chunk(mat, next_i, next_j, current_ans) # Check the rest of mat
mat = [[1,0,0,3,0],
[0,0,2,3,0],
[2,0,0,2,0],
[0,1,2,3,3],]
mat2 = [[1,0,0,3,0],
[0,0,2,3,0],
[2,0,0,0,0], # A slight modification in this row to connect two chunks
[0,1,2,3,3],]
print(biggest_zero_chunk(mat.copy()))
print(biggest_zero_chunk(mat2.copy()))
Output:
6
10
Notes:
The idea behind this solution is still BFS (represented mainly in the count_zeros function). Also, if you are interested in using the matrix values after this you should call the biggest_zero_chunk with a copy of the matrix (because it is modified in the algorithm)
The task is to write function that foldes number into prime factors. By given number 'n' this function should return a list of tuples p_i,c^i, for example if input is 100, the output is (2,2),(5,2).
So, here is how i try to write it:
def factor(n):
c = 1
pre_ans = list()
temp_n=n
for i in range(2,temp_n+1):
if (is_prime(i) == True) and (temp_n % i == 0):
for j in range (2,temp_n+1):
if (temp_n % (i ** j) == 0):
pre_ans.append((i,j))
temp_n /= (i **j)
pre_ans.append((i,c))
temp_n /= i
print(pre_ans)
It works wrong but I can't find a mistake :(
Your general idea is ok. However there are some minor issues with the following part of your code:
for j in range (2,temp_n+1):
if (temp_n % (i ** j) == 0):
pre_ans.append((i,j))
temp_n /= (i **j)
pre_ans.append((i,c))
temp_n /= i
In fact the main problem is that you need to iterate in the other direction in this statement for j in range (2,temp_n+1). If you rewrite it like
def factor(n):
c = 1
pre_ans = list()
temp_n=n
for i in range(2,temp_n+1):
if (is_prime(i) == True) and (temp_n % i == 0):
for j in range (temp_n+1, 0,-1):
if (temp_n % (i ** j) == 0):
pre_ans.append((i,j))
temp_n /= (i **j)
print(pre_ans)
it will work. The whole code can also get written a bit shorter:
from collections import Counter
def factor(n):
lst = []
for i in range(2, n+1):
while n % i == 0:
lst.append(i)
n = n / i
return Counter(lst).items()
print(factor(100))
Fixed the code. This is working version
def factor(n):
c = 1
pre_ans = list()
temp_n=n
for i in range(2, n // 2 + 1):
if (is_prime(i) == True):
k = 1
while temp_n % (i ** k) == 0:
if temp_n % (i ** (k + 1)) == 0:
k += 1
else:
k += 1
break
if k > 1:
pre_ans.append((i, k - 1))
return pre_ans
So the gist of this is a function that takes two sorted lists. It takes a list of negative numbers (people who owe money) and a list of positive number (people who are owed money). It then pays off the people who are owed money from the negative list.
Example:
negatives = [-55.774, -45.884, -40.754, -35.694, -33.734, -29.024, -25.114, -16.144, -14.014, -5.874, -5.554]
positives = [43.936, 42.276, 33.756, 31.116, 30.456, 27.616, 21.526, 18.276, 13.176, 12.376, 11.966, 8.566, 8.486, 4.036]
The first step in my process is negatives[0] will pay off the positives[0], 43.936, then it pays off partially positives[1] until itself negatives[0] is 0, it then moves onto negatives[1] and pays off what is owed to positives[1]. I'm just trying to iterate this process. Here's what I have:
def pay_balances(x, y):
i = 0
j = 0
while i < len(x) and j < len(y):
while abs(x[i]) > abs(y[j]) and abs(round(x[i],4)) != 0:
print y[j]
x[i] = x[i] + y[j]
y[j] = 0
j += 1
print i, j
while abs(x[i]) < abs(y[j]) and abs(round(x[i],4)) != 0:
print -x[i]
y[j] = y[j] + x[i]
x[i] = 0
i += 1
print i, j
So, if you run...
pay_balances(negatives, positives)
This will eventually break due to IndexError: list index out of range
The issue is when we are the end of the lists, and my j value = 14 which is when I want everything to stop. It appears to stay in the loop even though I have this line which I thought would kill it:
while i < len(x) and j < len(y):
What am I doing wrong? As always thanks a lot!!
Since you increment the indices i and j in the inner loops, you need to put the corresponding condition also in the first inner while loop, and add an exit point half-way:
while i < len(x) and j < len(y):
while j < len(y) and abs(x[i]) > abs(y[j]) and abs(round(x[i],4)) != 0:
print y[j]
x[i] = x[i] + y[j]
y[j] = 0
j += 1
print i, j
if j >= len(y):
break
while i < len(x) and abs(x[i]) < abs(y[j]) and abs(round(x[i],4)) != 0:
print -x[i]
y[j] = y[j] + x[i]
x[i] = 0
i += 1
print i, j
I think that this code generates what you want by using one loop:
def pay_balances(x, y):
i = 0
j = 0
while x[-1] != 0 and y[-1] !=0:
if abs(x[i]) > abs(y[j]):
x[i] = x[i] + y[j]
y[j] = 0
j += 1
elif abs(x[i]) < abs(y[j]):
y[j] = y[j] + x[i]
x[i] = 0
i += 1
print x, y
return sum(x) + sum(y)