Loop stuck while calculating the nearest neighbour - python

I am trying to print out the list of nearest neighbours. I should be getting a list of length 12; however, the list I am getting is of shorter length. When I print out the values for the variable 'a', it is getting stuck at the last element of the list 'path'. I've been trying to debug it, but couldn't find why the value of 'a' is not following the same pattern and why I can't get the other elements.
G is a graph with 11 nodes in total, and what I should be getting is G.NNA(3) = [3, 4, 0, 10, 2, 8, 1, 7, 5, 11, 6, 9]. I am getting the list up until the eighth index [3, 4, 0, 10, 2, 8, 1, 7, 5].
I put print statements inside the two 'if' statements, and the value 'a' clearly gets stuck. It would be amazing if I could fix it. Thanks in advance!
def NNA(self, start):
path = [start] # Initialize the path that starts with the given point
usedNodes = [start] # List for used nodes
currentNode = start
a = 1
while len(path) < self.n and a < self.n:
distances = self.dists[currentNode] # self.dists[3] = [4, 3, 3, 0, 1, 3, 3, 2, 3, 3, 4, 2] and the indeces correspond to the nodes
nextNode = distances.index(sorted(distances)[a]) # Gets the next node
if nextNode not in usedNodes :
a = 1
path.append(nextNode)
usedNodes.append(nextNode)
currentNode = nextNode
print(currentNode, a)
elif nextNode in usedNodes:
a = a + 1 # Check the next smallest value
print(currentNode, a)
self.perm = path
print(path)
# Here is the output
4 1
4 2
0 1
10 1
10 2
2 1
8 1
8 2
1 1
7 1
5 1 # gets stuck at 5
5 2
5 3
5 4
5 5
5 6
5 7
5 8
5 9
5 10
5 11
5 12
[3, 4, 0, 10, 2, 8, 1, 7, 5] # expecting [3, 4, 0, 10, 2, 8, 1, 7, 5, 11, 6, 9]

Related

When to reset temp variable in this Python procedure?

I'm trying to find the column wise combinations for given m x n 2d matrix. For example if the matrix is 3 x 3, it might be,
1 2 3
4 5 6
7 8 9
And I want the combinations, 3 at time, like -
1, 4, 7
1, 4, 8
1, 4, 9
1, 5, 7
.
.
1, 6, 7
I've tried the following recursive procedure in Python 3:
def getKeys(keychars):
temp = []
create(keychars, 0, 0, temp)
def create(kc, i, j, temp):
if i == 3:
print(temp)
del temp[-1]
return
temp.append(kc[i][j])
for j in range(3):
create(kc, i+1, j, temp)
def main():
keychars = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
getKeys(keychars)
main()
(If running the snippet gives you an error, please try in an IDE.)
But the problem is that, I'm not sure how or when to clear the temp variable. The outputs are like - 1,4,7 1,4,7,8 1,4,7,8,9 1,4,7,8,9,5
That is the temp variable retains the previous results. Any help would be appreciated.

How can i sum every nth number from list recursively?

I want to add every nth number from list recursively, but NOT the first number, so lets say I have a list [1, 2, 3, 4, 5, 6] and I want to add every 2nd number, so that would mean I need to add 2 + 4 + 6 but if I want to add every 3rd number, then it should add 3 + 6.
So right now I have this much, I want to add every 2nd number so that means I want to add 2, 4 and 6, but I can't seem to figure out why it doesn't work, what should I do differently?
def getsum(numbers):
if len(piece)==0:
return 0
else:
return getsum(numbers[2:]) + numbers[0]
print getSum([1, 2, 3, 4, 5, 6])
You can pick out the nth number, then recursively slice off everything after that when you call the function again
def get_sum(numbers, n):
if len(numbers) < n:
return 0
return numbers[n-1] + get_sum(numbers[n:], n)
For example with n = 2 and n = 3 respectively
>>> get_sum([1, 2, 3, 4, 5, 6], 2) # 2 + 4 + 6
12
>>> get_sum([1, 2, 3, 4, 5, 6], 3) # 3 + 6
9

How do I print a list in a triangular shape in python?

I have a code that generates a list of values to form a Romberg Triangle. The list is always a triangular length (3, 6, 10, 15). How do I print a list like this in triangular form?
What I currently have:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Print statement that I want:
1
2 5
3 6 8
4 7 9 10
Try this:
def getLength(n):
i = 1
s = 1
while ( s < n ):
i += 1
s = s + i
return i
def printTriangle(a):
l = len(a)
lt = getLength(l)
for i in range(lt):
d = lt - 2
s = 0
for j in range(i+1):
print(a[i+j+s], end=' ')
s += d
d -= 1
print('')
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
printTriangle(a)
The getLength function just calculates the height of the triangle and the printTriangle function handles the actual printing logic.
A different approach:
def print_tri(l):
n_rows = 1
n_elements = 1
while n_elements < len(l):
n_rows += 1
n_elements += n_rows
rows = [[] for _ in range(n_rows)]
offset = 0
while l:
for d in range(offset, n_rows):
rows[d].append(l.pop(0))
offset += 1
for row in rows:
print(' '.join(map(str, row)))
print_tri([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
The following works fairly efficiently:
def print_triangle(x):
it = iter(x)
num = 0
while True:
val = next(it, None)
if val:
print(val, *(next(it) for _ in range(num)))
num += 1
else:
break
>>> print_triangle([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
1
2 3
4 5 6
7 8 9 10
>>> print_triangle([1, 2, 3, 4, 5, 6])
1
2 3
4 5 6
Will fail if the input doesn't have the correct length:
>>> print_triangle([1, 2, 3, 4, 5])
1
2 3
Traceback (most recent call last):
File "<stdin>", line 7, in <genexpr>
StopIteration
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in print_triangle
RuntimeError: generator raised StopIteration
I have used a lot of mathematics! n is the side of triangle (I have used delta equation to calculate that). l is the list of numbers you can give to the function. I hope the rest would be understandable!! Feel free to ask questions in comment.
def print_triang(l):
lg = len(l)
number_of_rows = int(((1+8*lg)**.5 - 1) / 2)
for row_index in range(number_of_rows):
print(' '.join(
str(l[x]) for x in [row_index + col_index*number_of_rows - int(col_index*(col_index+1)/2) for col_index in range(row_index+1)]
))
One can go full-math, solving length=(n*(n+1))/2 for n (number of rows and columns, it has one positive solution), and then use the sum of arithmetic progression for calculating indices for the columns (what the older variant below does using sum):
def tri(lst):
rows=int(((1+8*len(lst))**0.5-1)/2)
for row in range(0,rows):
print([lst[int(row+(2*rows-column-1)*column/2)] for column in range(0,row+1)])
print() # this is just for separating subsequent calls
tri([1])
tri([1,2,3])
tri([1,2,3,4,5,6])
tri([1,2,3,4,5,6,7,8,9,10])
tri([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])
Output:
[1]
[1]
[2, 3]
[1]
[2, 4]
[3, 5, 6]
[1]
[2, 5]
[3, 6, 8]
[4, 7, 9, 10]
[1]
[2, 6]
[3, 7, 10]
[4, 8, 11, 13]
[5, 9, 12, 14, 15]
An older variant collecting column-lengths first, and then indexing into the list directly:
a=list(range(1,11))
lena=len(a)
deltas=[]
total=0
i=0
while total<lena:
deltas.append(i)
i+=1
total+=i
lend=len(deltas)
for row in range(lend):
print([a[row+sum(deltas[lend-column:])] for column in range(0,row+1)])
You can also use next with iter:
def is_side(d, s):
return not d if not s else is_side(d[s:], s-1)
def to_triangle(d):
new_d, r = iter(d), [i for i in range(len(d)) if is_side(d, i)][0]
s = [[next(new_d) for _ in range(i)] for i in reversed(range(1, r+1))]
return '\n'.join(' '.join(str(b[x]) if (x:=len(b) - len(s[0])+i) >= 0 else ' ' for b in s) for i in range(len(s[0])))
d = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(to_triangle(d))
Output:
1
2 5
3 6 8
4 7 9 10

Splitting a heap at given key

Given a list: [10, 4, 9, 3, 2, 5, 8, 1, 0]
that has the heap structure of below:
8
9
5
10
2
4
0
3
1
What is a good algorithm in python to get [4,3,2,1,0] which is basically the left child of 10.
parent is (index+1)//2
left child is 2i+1, right child is 2i+2
L = [10, 4, 9, 3, 2, 5, 8, 1, 0]
index = 1
newheap = []
newheap.append(L[index])
leftc = 2 * index + 1
rightc = 2 * index + 2
while(leftc < len(L)):
newheap.append(L[leftc])
if(rightc < len(L)):
newheap.append(L[rightc])
leftc = 2 * leftc + 1
rightc = 2 * rightc + 2
print(newheap)
which outputs
[4,3,2,1]
but I need [4,3,2,1, 0], so not what I wanted. I started the index at 1 which points to 4.
Would recursion be better? Not sure how to go about this.
You can try something like that :
L = [10, 4, 9, 3, 2, 5, 8, 1, 0]
index = 0
offset = 1
newheap = []
while index < len(L):
index += offset
for i in range(offset):
if index+i == len(L):
break
newheap += [L[index+i]]
offset = 2 * offset
print(newheap)

solving 8 puzzle problem with BFS DFS (Using Python. Needs some suggestion)

My final state is
0 1 2 3 4 5 6 7 8
my graph would look like this
graph = {0 :[1, 3],
1 :[0, 4, 2],
2 :[1, 5],
3 :[0, 4, 6],
4 :[1, 3, 5, 7],
5 :[2, 4, 8],
6 :[3, 7],
7 :[4, 6, 8],
8 :[5 ,7]
}
1 - I was wondering if I should try some other methods such as list, if else statement than graph(above).
2 - Is anything wrong with the graph?
The problem given -
Example [1,5,3,2,0,4,7,8,6] <- more like this 1 5 3 2 0 4
7 8 6
I am supposed to find final state with given state
Thank You
So, there are 4 corner cases:
Top row
Bottom row
Most left column
Most right column
(And combinations)
We can handle them easy like this:
data = [1, 5, 3,
2, 0, 4,
7, 8, 6]
width = 3
height = 3
graph = {number: list() for number in data}
for idx, number in enumerate(data):
current_height = int(idx / width)
current_width = idx % width
if current_width != width - 1: # if next element in same row
graph[number].append(data[idx + 1])
if current_width != 0: # if prev element in same row
graph[number].append(data[idx - 1])
if current_height != 0: # if there is top element
graph[number].append(data[idx - 3])
if current_height != height - 1: # if there is bottom element
graph[number].append(data[idx + 3])
import pprint
pprint.pprint(graph)
This code will construct graph, but is this all for that puzzle?.

Categories