Home > database >  wrong output when testing a different input (finding a path)
wrong output when testing a different input (finding a path)

Time:10-04

For school i need to make an assignment. We have to find a path between 2 vertices. I have given my code below, i almost got it working, but i am stuck at one part. this is the input:

1->5
1, 2; 2, 3; 3, 4; 4, 5; 5, 

this is the correct output:

1->2->3->4->5

My program also gives the correct output when passing this input. However when passing the following input:

    1->4000000000
    1, 2, 3; 2, 2; 3, 4, 5; 4, 1, 2; 5, 5, 4000000000; 4000000000, 2

This should be the output:

     1->3->5->4000000000

but my program gives me this

     1-> 2-> 3-> 4-> 5-> 4000000000

How can i optimize this? Thanks for the help in advanve!

import sys
from typing import List

stack: []

def output():
    '''
    Will print the path stored in the `stack` global variable.
    You are free to modify it to be a parameter.
    '''
    #for id in stack[:-1]:
        #print(f'{id}->', end='')
    #try:
        #print(f'{stack[-1]}')
    #except IndexError:
        #pass
    return "->".join(stack) if stack else ""


def find_path(graph, start, target, path):
    #print(start, target)
    path = path   [start]
    #print(path)
    if start == target:
        return path
    for node in graph:
        #print(node)
        if node not in path: ##idk what to do here..
            new_path = find_path(graph, node, target, path)
            if new_path:
                return new_path
    return path

def add_value(dict_obj, key, value):
    if key not in dict_obj:
        dict_obj[key] = list()
    dict_obj[key].append(value)


if __name__ == '__main__':
    '''
    Fetch starting and target nodes.
    '''
    start, target = [x for x in input().split('->')]
    #print(start, target)
    '''
    Fetch `;` separated twitter data. <id-1: u_int>, <following: u_int>, ..<following: u_int>; ... 
    i.e: 1, 2; 2, 3; 3, 4; 4, 5; 5,
    '''
    data = input()
    data_l: List = data.split(';')
    graph = dict()
    for d in data_l:
        id, followers = d.split(', ', 1)
        # print(followers)
        following_l: List = followers.split(', ')
        for f in following_l:
            if f == '':
                # node is not following other nodes.
                continue
        add_value(graph, id, followers)
    print(graph)
    stack = find_path(graph, start, target, [])

sys.stdout.write(output())

CodePudding user response:

First mistake: you add followers which is string like "1, 2" - you should add following_l which is a list ["1", "2"]

Another mistake: you use for node in graph: but you should use graph[start] in for node in graph[start]:

Another mistake: you shouldn't add start to path because it may not be correct direction - but you should add it when you find new_path - return [start] new_path.

And when it can't find path then you should return empty list, not path

You should add start to separated list visited and later check if node not in visited - to check every node only once.

def find_path(graph, start, target):
    print('find_path:', start, '->', target)

    visited.append(start)
    
    if start == target:
        return [start]
    
    for node in graph[start]:
        #print('node:', node)
        if node not in visited:
            path = find_path(graph, node, target)
            if path:
                print('path:', [start]   path)
                return [start]   path
                
    return []

My full version:

def find_path(graph, start, target, visited):
    print('find_path:', start, '->', target)

    visited.append(start)
    
    if start == target:
        return [start]
    
    for node in graph[start]:
        #print('node:', node)
        if node not in visited:
            path = find_path(graph, node, target, visited)
            if path:
                print('path:', [start]   path)
                return [start]   path
                
    return []

def main(path, data):
    start, target = path.split('->')
    print('start, target:', start, target)

    data = data.split(';')

    graph = dict()
    
    for d in data:
        parts = d.split(',')
        
        if len(parts) > 1:
            id = parts[0]
            id = id.strip()
            
            followers = parts[1:]
            followers = [x.strip() for x in followers if x.strip()]
            
            print(id, 'followers:', followers)

            if followers:
                graph[id] = followers

    print('graph:', graph)
    
    visited = list()
    stack = find_path(graph, start, target, visited)

    output = "->".join(stack)
    
    print('output:', output)
    
    print('------')
    
if __name__ == '__main__':
    #path = input()
    #data = input()
    #main(path, data)
    
    path = '1->4000000000'
    data = '1, 2, 3; 2, 2; 3, 4, 5; 4, 1, 2; 5, 5, 4000000000; 4000000000, 2'
    main(path, data)

    path = '1->5'
    data = '1, 2; 2, 3; 3, 4; 4, 5; 5,'
    main(path, data)

Result:

start, target: 1 4000000000
1 followers: ['2', '3']
2 followers: ['2']
3 followers: ['4', '5']
4 followers: ['1', '2']
5 followers: ['5', '4000000000']
4000000000 followers: ['2']
graph: {'1': ['2', '3'], '2': ['2'], '3': ['4', '5'], '4': ['1', '2'], '5': ['5', '4000000000'], '4000000000': ['2']}
find_path: 1 -> 4000000000
find_path: 2 -> 4000000000
find_path: 3 -> 4000000000
find_path: 4 -> 4000000000
find_path: 5 -> 4000000000
find_path: 4000000000 -> 4000000000
path: ['5', '4000000000']
path: ['3', '5', '4000000000']
path: ['1', '3', '5', '4000000000']
output: 1->3->5->4000000000
------
start, target: 1 5
1 followers: ['2']
2 followers: ['3']
3 followers: ['4']
4 followers: ['5']
5 followers: []
graph: {'1': ['2'], '2': ['3'], '3': ['4'], '4': ['5']}
find_path: 1 -> 5
find_path: 2 -> 5
find_path: 3 -> 5
find_path: 4 -> 5
find_path: 5 -> 5
path: ['4', '5']
path: ['3', '4', '5']
path: ['2', '3', '4', '5']
path: ['1', '2', '3', '4', '5']
output: 1->2->3->4->5
------
  • Related